]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libcc1: share GDB plugin code
authorTom Tromey <tom@tromey.com>
Tue, 4 May 2021 21:26:58 +0000 (15:26 -0600)
committerTom Tromey <tom@tromey.com>
Wed, 5 May 2021 06:06:17 +0000 (00:06 -0600)
The two GDB plugins in libcc1 share a fair amount of code.  This was
done by copy-and-paste, though in reality the underlying code is
nearly identical.

libcc1

* libcp1.cc (struct libcp1): Derive from base_gdb_plugin.  Remove
shared code.
(class libcp1_connection): Remove.
(rpc): Remove.
(libcp1_set_verbose, libcp1_compile): Update.
(cp_call_binding_oracle, cp_call_symbol_address)
(cp_call_enter_scope, cp_call_leave_scope): Update.
* libcc1.cc (struct libcc1): Derive from base_gdb_plugin.  Remove
shared code.
(class libcc1_connection): Remove.
(c_call_binding_oracle, c_call_symbol_address): Update.
(rpc): Remove.
(libcc1_set_verbose, libcc1_compile): Update.
* gdbctx.hh: New file.

libcc1/gdbctx.hh [new file with mode: 0644]
libcc1/libcc1.cc
libcc1/libcp1.cc

diff --git a/libcc1/gdbctx.hh b/libcc1/gdbctx.hh
new file mode 100644 (file)
index 0000000..1c8d87d
--- /dev/null
@@ -0,0 +1,105 @@
+/* Generic GDB-side plugin
+   Copyright (C) 2020 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef CC1_PLUGIN_GDBCTX_HH
+#define CC1_PLUGIN_GDBCTX_HH
+
+namespace cc1_plugin
+{
+  // The compiler context that we hand back to our caller.
+  template<typename T>
+  struct base_gdb_plugin : public T
+  {
+    explicit base_gdb_plugin (const gcc_base_vtable *v)
+      : verbose (false),
+       compilerp (new compiler (verbose))
+    {
+      this->base.ops = v;
+    }
+
+    // A convenience function to print something.
+    void print (const char *str)
+    {
+      this->print_function (this->print_datum, str);
+    }
+
+    // Set the verbose flag.
+    void set_verbose (bool v)
+    {
+      verbose = v;
+      if (compilerp != nullptr)
+       compilerp->set_verbose (v);
+    }
+
+    // Make a new connection.
+    void set_connection (int fd, int aux_fd)
+    {
+      connection.reset (new local_connection (fd, aux_fd, this));
+    }
+
+    // A local subclass of connection that holds a back-pointer to the
+    // context object that we provide to our caller.
+    class local_connection : public cc1_plugin::connection
+    {
+    public:
+
+      local_connection (int fd, int aux_fd, base_gdb_plugin<T> *b)
+       : connection (fd, aux_fd),
+         back_ptr (b)
+      {
+      }
+
+      void print (const char *buf) override
+      {
+       back_ptr->print (buf);
+      }
+
+      base_gdb_plugin<T> *back_ptr;
+    };
+
+    std::unique_ptr<local_connection> connection;
+
+    void (*print_function) (void *datum, const char *message) = nullptr;
+    void *print_datum = nullptr;
+
+    std::vector<std::string> args;
+    std::string source_file;
+
+    /* Non-zero as an equivalent to gcc driver option "-v".  */
+    bool verbose;
+
+    std::unique_ptr<cc1_plugin::compiler> compilerp;
+  };
+
+  // Instances of this rpc<> template function are installed into the
+  // "vtable"s.  These functions are parameterized by type and method
+  // name and forward the call via the connection.
+  template<typename CTX, typename R, const char *&NAME, typename... Arg>
+  R rpc (CTX *s, Arg... rest)
+  {
+    base_gdb_plugin<CTX> *self = (base_gdb_plugin<CTX> *) s;
+    R result;
+    
+    if (!cc1_plugin::call (self->connection.get (), NAME, &result, rest...))
+      return 0;
+    return result;
+  }
+}
+
+#endif // CC1_PLUGIN_GDBCTX_HH
index ea52c26d78322f9202d970a90f1dfaa0094c245e..b9f1eb343aaf822d73821026e3f1d055c9b4150d 100644 (file)
@@ -37,73 +37,21 @@ along with GCC; see the file COPYING3.  If not see
 #include "compiler-name.hh"
 #include "gcc-c-interface.h"
 #include "compiler.hh"
-
-struct libcc1;
-
-class libcc1_connection;
+#include "gdbctx.hh"
 
 // The C compiler context that we hand back to our caller.
-struct libcc1 : public gcc_c_context
+struct libcc1 : public cc1_plugin::base_gdb_plugin<gcc_c_context>
 {
   libcc1 (const gcc_base_vtable *, const gcc_c_fe_vtable *);
 
-  // A convenience function to print something.
-  void print (const char *str)
-  {
-    this->print_function (this->print_datum, str);
-  }
-
-  std::unique_ptr<libcc1_connection> connection;
-
-  gcc_c_oracle_function *binding_oracle;
-  gcc_c_symbol_address_function *address_oracle;
-  void *oracle_datum;
-
-  void (*print_function) (void *datum, const char *message);
-  void *print_datum;
-
-  std::vector<std::string> args;
-  std::string source_file;
-
-  /* Non-zero as an equivalent to gcc driver option "-v".  */
-  bool verbose;
-
-  std::unique_ptr<cc1_plugin::compiler> compilerp;
+  gcc_c_oracle_function *binding_oracle = nullptr;
+  gcc_c_symbol_address_function *address_oracle = nullptr;
+  void *oracle_datum = nullptr;
 };
 
-// A local subclass of connection that holds a back-pointer to the
-// gcc_c_context object that we provide to our caller.
-class libcc1_connection : public cc1_plugin::connection
+libcc1::libcc1 (const gcc_base_vtable *v, const gcc_c_fe_vtable *cv)
+  : cc1_plugin::base_gdb_plugin<gcc_c_context> (v)
 {
-public:
-
-  libcc1_connection (int fd, int aux_fd, libcc1 *b)
-    : connection (fd, aux_fd),
-      back_ptr (b)
-  {
-  }
-
-  void print (const char *buf) override
-  {
-    back_ptr->print (buf);
-  }
-
-  libcc1 *back_ptr;
-};
-
-libcc1::libcc1 (const gcc_base_vtable *v,
-               const gcc_c_fe_vtable *cv)
-  : binding_oracle (NULL),
-    address_oracle (NULL),
-    oracle_datum (NULL),
-    print_function (NULL),
-    print_datum (NULL),
-    args (),
-    source_file (),
-    verbose (false),
-    compilerp (new cc1_plugin::compiler (verbose))
-{
-  base.ops = v;
   c_ops = cv;
 }
 
@@ -122,7 +70,7 @@ namespace {
                         enum gcc_c_oracle_request request,
                         const char *identifier)
   {
-    libcc1 *self = ((libcc1_connection *) conn)->back_ptr;
+    libcc1 *self = (libcc1 *) (((libcc1::local_connection *) conn)->back_ptr);
 
     self->binding_oracle (self->oracle_datum, self, request, identifier);
     return 1;
@@ -133,7 +81,7 @@ namespace {
   gcc_address
   c_call_symbol_address (cc1_plugin::connection *conn, const char *identifier)
   {
-    libcc1 *self = ((libcc1_connection *) conn)->back_ptr;
+    libcc1 *self = (libcc1 *) (((libcc1::local_connection *) conn)->back_ptr);
 
     return self->address_oracle (self->oracle_datum, self, identifier);
   }
@@ -154,40 +102,25 @@ set_callbacks (struct gcc_c_context *s,
   self->oracle_datum = datum;
 }
 
-// Instances of this rpc<> template function are installed into the
-// "c_vtable".  These functions are parameterized by type and method
-// name and forward the call via the connection.
-
-template<typename R, const char *&NAME, typename... Arg>
-R rpc (struct gcc_c_context *s, Arg... rest)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection.get (), NAME, &result, rest...))
-    return 0;
-  return result;
-}
-
 static const struct gcc_c_fe_vtable c_vtable =
 {
   GCC_C_FE_VERSION_0,
   set_callbacks,
 
 #define GCC_METHOD0(R, N) \
-  rpc<R, cc1_plugin::c::N>,
+  cc1_plugin::rpc<gcc_c_context, R, cc1_plugin::c::N>,
 #define GCC_METHOD1(R, N, A) \
-  rpc<R, cc1_plugin::c::N, A>,
+  cc1_plugin::rpc<gcc_c_context, R, cc1_plugin::c::N, A>,
 #define GCC_METHOD2(R, N, A, B) \
-  rpc<R, cc1_plugin::c::N, A, B>,
+  cc1_plugin::rpc<gcc_c_context, R, cc1_plugin::c::N, A, B>,
 #define GCC_METHOD3(R, N, A, B, C) \
-  rpc<R, cc1_plugin::c::N, A, B, C>,
+  cc1_plugin::rpc<gcc_c_context, R, cc1_plugin::c::N, A, B, C>,
 #define GCC_METHOD4(R, N, A, B, C, D) \
-  rpc<R, cc1_plugin::c::N, A, B, C, D>,
+  cc1_plugin::rpc<gcc_c_context, R, cc1_plugin::c::N, A, B, C, D>,
 #define GCC_METHOD5(R, N, A, B, C, D, E) \
-  rpc<R, cc1_plugin::c::N, A, B, C, D, E>,
+  cc1_plugin::rpc<gcc_c_context, R, cc1_plugin::c::N, A, B, C, D, E>,
 #define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
-  rpc<R, cc1_plugin::c::N, A, B, C, D, E, F, G>,
+  cc1_plugin::rpc<gcc_c_context, R, cc1_plugin::c::N, A, B, C, D, E, F, G>,
 
 #include "gcc-c-fe.def"
 
@@ -207,9 +140,7 @@ libcc1_set_verbose (struct gcc_base_context *s, int /* bool */ verbose)
 {
   libcc1 *self = (libcc1 *) s;
 
-  self->verbose = verbose != 0;
-  if (self->compilerp != nullptr)
-    self->compilerp->set_verbose (self->verbose);
+  self->set_verbose (verbose != 0);
 }
 
 static char *
@@ -386,7 +317,7 @@ libcc1_compile (struct gcc_base_context *s,
   if (self->verbose)
     self->args.push_back ("-v");
 
-  self->connection.reset (new libcc1_connection (fds[0], stderr_fds[0], self));
+  self->set_connection (fds[0], stderr_fds[0]);
 
   cc1_plugin::callback_ftype *fun
     = cc1_plugin::callback<int,
index c57ac8c66a6b736ec1ac62f7f076179a18130c55..6fb9fb4c9a6c80db324c8224da6889f5ccc448ae 100644 (file)
@@ -36,75 +36,23 @@ along with GCC; see the file COPYING3.  If not see
 #include "libiberty.h"
 #include "compiler-name.hh"
 #include "compiler.hh"
-
-struct libcp1;
-
-class libcp1_connection;
+#include "gdbctx.hh"
 
 // The C compiler context that we hand back to our caller.
-struct libcp1 : public gcc_cp_context
+struct libcp1 : public cc1_plugin::base_gdb_plugin<gcc_cp_context>
 {
   libcp1 (const gcc_base_vtable *, const gcc_cp_fe_vtable *);
 
-  // A convenience function to print something.
-  void print (const char *str)
-  {
-    this->print_function (this->print_datum, str);
-  }
-
-  std::unique_ptr<libcp1_connection> connection;
-
-  gcc_cp_oracle_function *binding_oracle;
-  gcc_cp_symbol_address_function *address_oracle;
-  gcc_cp_enter_leave_user_expr_scope_function *enter_scope;
-  gcc_cp_enter_leave_user_expr_scope_function *leave_scope;
-  void *oracle_datum;
-
-  void (*print_function) (void *datum, const char *message);
-  void *print_datum;
-
-  std::vector<std::string> args;
-  std::string source_file;
-
-  /* Non-zero as an equivalent to gcc driver option "-v".  */
-  bool verbose;
-
-  std::unique_ptr<cc1_plugin::compiler> compilerp;
+  gcc_cp_oracle_function *binding_oracle = nullptr;
+  gcc_cp_symbol_address_function *address_oracle = nullptr;
+  gcc_cp_enter_leave_user_expr_scope_function *enter_scope = nullptr;
+  gcc_cp_enter_leave_user_expr_scope_function *leave_scope = nullptr;
+  void *oracle_datum = nullptr;
 };
 
-// A local subclass of connection that holds a back-pointer to the
-// gcc_c_context object that we provide to our caller.
-class libcp1_connection : public cc1_plugin::connection
+libcp1::libcp1 (const gcc_base_vtable *v, const gcc_cp_fe_vtable *cv)
+  : cc1_plugin::base_gdb_plugin<gcc_cp_context> (v)
 {
-public:
-
-  libcp1_connection (int fd, int aux_fd, libcp1 *b)
-    : connection (fd, aux_fd),
-      back_ptr (b)
-  {
-  }
-
-  void print (const char *buf) override
-  {
-    back_ptr->print (buf);
-  }
-
-  libcp1 *back_ptr;
-};
-
-libcp1::libcp1 (const gcc_base_vtable *v,
-                 const gcc_cp_fe_vtable *cv)
-  : binding_oracle (NULL),
-    address_oracle (NULL),
-    oracle_datum (NULL),
-    print_function (NULL),
-    print_datum (NULL),
-    args (),
-    source_file (),
-    verbose (false),
-    compilerp (new cc1_plugin::compiler (verbose))
-{
-  base.ops = v;
   cp_ops = cv;
 }
 
@@ -123,7 +71,7 @@ namespace {
                       enum gcc_cp_oracle_request request,
                       const char *identifier)
   {
-    libcp1 *self = ((libcp1_connection *) conn)->back_ptr;
+    libcp1 *self = (libcp1 *) (((libcp1::local_connection *) conn)->back_ptr);
 
     self->binding_oracle (self->oracle_datum, self, request, identifier);
     return 1;
@@ -134,7 +82,7 @@ namespace {
   gcc_address
   cp_call_symbol_address (cc1_plugin::connection *conn, const char *identifier)
   {
-    libcp1 *self = ((libcp1_connection *) conn)->back_ptr;
+    libcp1 *self = (libcp1 *) (((libcp1::local_connection *) conn)->back_ptr);
 
     return self->address_oracle (self->oracle_datum, self, identifier);
   }
@@ -142,7 +90,7 @@ namespace {
   int
   cp_call_enter_scope (cc1_plugin::connection *conn)
   {
-    libcp1 *self = ((libcp1_connection *) conn)->back_ptr;
+    libcp1 *self = (libcp1 *) (((libcp1::local_connection *) conn)->back_ptr);
 
     self->enter_scope (self->oracle_datum, self);
     return 1;
@@ -151,7 +99,7 @@ namespace {
   int
   cp_call_leave_scope (cc1_plugin::connection *conn)
   {
-    libcp1 *self = ((libcp1_connection *) conn)->back_ptr;
+    libcp1 *self = (libcp1 *) (((libcp1::local_connection *) conn)->back_ptr);
 
     self->leave_scope (self->oracle_datum, self);
     return 1;
@@ -177,40 +125,25 @@ set_callbacks (struct gcc_cp_context *s,
   self->oracle_datum = datum;
 }
 
-// Instances of this rpc<> template function are installed into the
-// "cp_vtable".  These functions are parameterized by type and method
-// name and forward the call via the connection.
-
-template<typename R, const char *&NAME, typename... Arg>
-R rpc (struct gcc_cp_context *s, Arg... rest)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection.get (), NAME, &result, rest...))
-    return 0;
-  return result;
-}
-
 static const struct gcc_cp_fe_vtable cp_vtable =
 {
   GCC_CP_FE_VERSION_0,
   set_callbacks,
 
 #define GCC_METHOD0(R, N) \
-  rpc<R, cc1_plugin::cp::N>,
+  cc1_plugin::rpc<gcc_cp_context, R, cc1_plugin::cp::N>,
 #define GCC_METHOD1(R, N, A) \
-  rpc<R, cc1_plugin::cp::N, A>,
+  cc1_plugin::rpc<gcc_cp_context, R, cc1_plugin::cp::N, A>,
 #define GCC_METHOD2(R, N, A, B) \
-  rpc<R, cc1_plugin::cp::N, A, B>,
+  cc1_plugin::rpc<gcc_cp_context, R, cc1_plugin::cp::N, A, B>,
 #define GCC_METHOD3(R, N, A, B, C) \
-  rpc<R, cc1_plugin::cp::N, A, B, C>,
+  cc1_plugin::rpc<gcc_cp_context, R, cc1_plugin::cp::N, A, B, C>,
 #define GCC_METHOD4(R, N, A, B, C, D) \
-  rpc<R, cc1_plugin::cp::N, A, B, C, D>,
+  cc1_plugin::rpc<gcc_cp_context, R, cc1_plugin::cp::N, A, B, C, D>,
 #define GCC_METHOD5(R, N, A, B, C, D, E) \
-  rpc<R, cc1_plugin::cp::N, A, B, C, D, E>,
+  cc1_plugin::rpc<gcc_cp_context, R, cc1_plugin::cp::N, A, B, C, D, E>,
 #define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
-  rpc<R, cc1_plugin::cp::N, A, B, C, D, E, F, G>,
+  cc1_plugin::rpc<gcc_cp_context, R, cc1_plugin::cp::N, A, B, C, D, E, F, G>,
 
 #include "gcc-cp-fe.def"
 
@@ -230,9 +163,7 @@ libcp1_set_verbose (struct gcc_base_context *s, int /* bool */ verbose)
 {
   libcp1 *self = (libcp1 *) s;
 
-  self->verbose = verbose != 0;
-  if (self->compilerp != nullptr)
-    self->compilerp->set_verbose (self->verbose);
+  self->set_verbose (verbose != 0);
 }
 
 static char *
@@ -409,7 +340,7 @@ libcp1_compile (struct gcc_base_context *s,
   if (self->verbose)
     self->args.push_back ("-v");
 
-  self->connection.reset (new libcp1_connection (fds[0], stderr_fds[0], self));
+  self->set_connection (fds[0], stderr_fds[0]);
 
   cc1_plugin::callback_ftype *fun
     = cc1_plugin::callback<int,