libcc1: share GDB plugin code
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.
This commit is contained in:
parent
0624823260
commit
1a51cb2990
105
libcc1/gdbctx.hh
Normal file
105
libcc1/gdbctx.hh
Normal file
@ -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
|
105
libcc1/libcc1.cc
105
libcc1/libcc1.cc
@ -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,
|
||||
|
113
libcc1/libcp1.cc
113
libcc1/libcp1.cc
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user