From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gateway32.websitewelcome.com (gateway32.websitewelcome.com [192.185.145.184]) by sourceware.org (Postfix) with ESMTPS id 9115639BD00C for ; Wed, 28 Apr 2021 01:01:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 9115639BD00C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=tromey.com Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=tom@tromey.com Received: from cm14.websitewelcome.com (cm14.websitewelcome.com [100.42.49.7]) by gateway32.websitewelcome.com (Postfix) with ESMTP id 449592310E for ; Tue, 27 Apr 2021 20:01:44 -0500 (CDT) Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with SMTP id bYaGloCAPw11MbYaGlBjLj; Tue, 27 Apr 2021 20:01:44 -0500 X-Authority-Reason: nr=8 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=wEZVqNhhCzDQJGdSMknGXqBDd0nxXDyRpEXHjvEOEB0=; b=gM6Po3xSTvxCK7JyuZIIE43ruc 160ce5nibWmI27si/9S5QQxKTgCRoNAzfvmDZJy39b6gJFKbip7lBKq0jtyRVqA4Toi53U+NSNhrj 1VETdnzaxap5kybjc436YXwJ8; Received: from 97-122-70-176.hlrn.qwest.net ([97.122.70.176]:32966 helo=localhost.localdomain) by box5379.bluehost.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94) (envelope-from ) id 1lbYaF-003tiR-VP; Tue, 27 Apr 2021 19:01:44 -0600 From: Tom Tromey To: gcc-patches@gcc.gnu.org Cc: Tom Tromey Subject: [PATCH v2 17/21] libcc1: share the GCC interface code Date: Tue, 27 Apr 2021 19:01:15 -0600 Message-Id: <20210428010119.806184-18-tom@tromey.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210428010119.806184-1-tom@tromey.com> References: <20210428010119.806184-1-tom@tromey.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - box5379.bluehost.com X-AntiAbuse: Original Domain - gcc.gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - tromey.com X-BWhitelist: no X-Source-IP: 97.122.70.176 X-Source-L: No X-Exim-ID: 1lbYaF-003tiR-VP X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: 97-122-70-176.hlrn.qwest.net (localhost.localdomain) [97.122.70.176]:32966 X-Source-Auth: tom+tromey.com X-Email-Count: 18 X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTM3OS5ibHVlaG9zdC5jb20= X-Local-Domain: yes X-Spam-Status: No, score=-3031.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, RCVD_IN_SBL_CSS, SPF_HELO_PASS, SPF_NEUTRAL, TXREP, URIBL_CSS, URIBL_CSS_A autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Apr 2021 01:01:49 -0000 Both the C and C++ side of the GDB plugin in libcc1 share a lot of code relating to the base GCC interface. It was all copy-and-pasted, but is essentially identical between the two. This is by design, as the base GCC API is intended to be shared. This patch merges the implementations into base_gdb_plugin, which was introduced earlier for this purpose. libcc1/ChangeLog 2021-04-27 Tom Tromey * libcp1.cc (libcp1): Change parameters. Update. (libcp1_set_verbose, libcp1_set_arguments) (libcp1_set_triplet_regexp, libcp1_set_driver_filename) (libcp1_set_source_file, libcp1_set_print_callback, fork_exec) (libcp1_compile, libcp1_destroy, vtable): Remove. (libcp1::add_callbacks): New method, extracted from libcp1_compile. (gcc_c_fe_context): Update. * libcc1.cc (libcc1): Change parameters. Update. (libcc1_set_verbose, libcc1_set_arguments) (libcc1_set_triplet_regexp, libcc1_set_driver_filename) (libcc1_set_source_file, libcc1_set_print_callback, fork_exec) (libcc1_compile, libcc1_destroy, vtable): Remove. (libcc1::add_callbacks): New method, extracted from libcc1_compile. (gcc_c_fe_context): Update. * gdbctx.hh (base_gdb_plugin): Change parameters. (~base_gdb_plugin): New. : New virtual method. : New members. (get_self, do_set_verbose, do_set_arguments) (do_set_triplet_regexp, do_set_driver_filename) (do_set_arguments_v0, do_set_source_file, do_set_print_callback) (fork_exec, do_compile, do_compile_v0, do_destroy): New methods. --- libcc1/ChangeLog | 27 +++++ libcc1/gdbctx.hh | 253 ++++++++++++++++++++++++++++++++++++++++++++++- libcc1/libcc1.cc | 242 +++------------------------------------------ libcc1/libcp1.cc | 246 +++------------------------------------------ 4 files changed, 304 insertions(+), 464 deletions(-) diff --git a/libcc1/gdbctx.hh b/libcc1/gdbctx.hh index 1c8d87dff021..4a48381f2b4a 100644 --- a/libcc1/gdbctx.hh +++ b/libcc1/gdbctx.hh @@ -23,16 +23,38 @@ along with GCC; see the file COPYING3. If not see namespace cc1_plugin { // The compiler context that we hand back to our caller. + // Due to this, the entire implementation is in this header. template struct base_gdb_plugin : public T { - explicit base_gdb_plugin (const gcc_base_vtable *v) + base_gdb_plugin (const char *plugin_name_, const char *base_name, + int version) : verbose (false), + plugin_name (plugin_name_), + fe_version (version), + compiler_name (base_name), compilerp (new compiler (verbose)) { - this->base.ops = v; + vtable = + { + GCC_FE_VERSION_1, + do_set_arguments_v0, + do_set_source_file, + do_set_print_callback, + do_compile_v0, + do_destroy, + do_set_verbose, + do_compile, + do_set_arguments, + do_set_triplet_regexp, + do_set_driver_filename, + }; + + this->base.ops = &vtable; } + virtual ~base_gdb_plugin () = default; + // A convenience function to print something. void print (const char *str) { @@ -53,6 +75,10 @@ namespace cc1_plugin connection.reset (new local_connection (fd, aux_fd, this)); } + // This is called just before compilation begins. It should set + // any needed callbacks on the connection. + virtual void add_callbacks () = 0; + // 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 @@ -84,7 +110,230 @@ namespace cc1_plugin /* Non-zero as an equivalent to gcc driver option "-v". */ bool verbose; + const char *plugin_name; + int fe_version; + + const char *compiler_name; std::unique_ptr compilerp; + + private: + + struct gcc_base_vtable vtable; + + static inline base_gdb_plugin * + get_self (gcc_base_context *s) + { + T *sub = (T *) s; + return static_cast *> (sub); + } + + static void + do_set_verbose (struct gcc_base_context *s, int /* bool */ verbose) + { + base_gdb_plugin *self = get_self (s); + + self->set_verbose (verbose != 0); + } + + static char * + do_set_arguments (struct gcc_base_context *s, + int argc, char **argv) + { + base_gdb_plugin *self = get_self (s); + + std::string compiler; + char *errmsg = self->compilerp->find (self->compiler_name, compiler); + if (errmsg != NULL) + return errmsg; + + self->args.push_back (compiler); + + for (int i = 0; i < argc; ++i) + self->args.push_back (argv[i]); + + return NULL; + } + + static char * + do_set_triplet_regexp (struct gcc_base_context *s, + const char *triplet_regexp) + { + base_gdb_plugin *self = get_self (s); + + self->compilerp.reset + (new cc1_plugin::compiler_triplet_regexp (self->verbose, + triplet_regexp)); + return NULL; + } + + static char * + do_set_driver_filename (struct gcc_base_context *s, + const char *driver_filename) + { + base_gdb_plugin *self = get_self (s); + + self->compilerp.reset + (new cc1_plugin::compiler_driver_filename (self->verbose, + driver_filename)); + return NULL; + } + + static char * + do_set_arguments_v0 (struct gcc_base_context *s, + const char *triplet_regexp, + int argc, char **argv) + { + char *errmsg = do_set_triplet_regexp (s, triplet_regexp); + if (errmsg != NULL) + return errmsg; + + return do_set_arguments (s, argc, argv); + } + + static void + do_set_source_file (struct gcc_base_context *s, + const char *file) + { + base_gdb_plugin *self = get_self (s); + + self->source_file = file; + } + + static void + do_set_print_callback (struct gcc_base_context *s, + void (*print_function) (void *datum, + const char *message), + void *datum) + { + base_gdb_plugin *self = get_self (s); + + self->print_function = print_function; + self->print_datum = datum; + } + + int fork_exec (char **argv, int spair_fds[2], int stderr_fds[2]) + { + pid_t child_pid = fork (); + + if (child_pid == -1) + { + close (spair_fds[0]); + close (spair_fds[1]); + close (stderr_fds[0]); + close (stderr_fds[1]); + return 0; + } + + if (child_pid == 0) + { + // Child. + dup2 (stderr_fds[1], 1); + dup2 (stderr_fds[1], 2); + close (stderr_fds[0]); + close (stderr_fds[1]); + close (spair_fds[0]); + + execvp (argv[0], argv); + _exit (127); + } + else + { + // Parent. + close (spair_fds[1]); + close (stderr_fds[1]); + + cc1_plugin::status result = cc1_plugin::FAIL; + if (connection->send ('H') + && ::cc1_plugin::marshall (connection.get (), fe_version)) + result = connection->wait_for_query (); + + close (spair_fds[0]); + close (stderr_fds[0]); + + while (true) + { + int status; + + if (waitpid (child_pid, &status, 0) == -1) + { + if (errno != EINTR) + return 0; + } + + if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) + return 0; + break; + } + + if (!result) + return 0; + return 1; + } + } + + static int + do_compile (struct gcc_base_context *s, + const char *filename) + { + base_gdb_plugin *self = get_self (s); + + int fds[2]; + if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) != 0) + { + self->print ("could not create socketpair\n"); + return 0; + } + + int stderr_fds[2]; + if (pipe (stderr_fds) != 0) + { + self->print ("could not create pipe\n"); + close (fds[0]); + close (fds[1]); + return 0; + } + + self->args.push_back (std::string ("-fplugin=") + self->plugin_name); + self->args.push_back (std::string ("-fplugin-arg-") + self->plugin_name + + "-fd=" + std::to_string (fds[1])); + + self->args.push_back (self->source_file); + self->args.push_back ("-c"); + self->args.push_back ("-o"); + self->args.push_back (filename); + if (self->verbose) + self->args.push_back ("-v"); + + self->set_connection (fds[0], stderr_fds[0]); + + self->add_callbacks (); + + char **argv = new (std::nothrow) char *[self->args.size () + 1]; + if (argv == NULL) + return 0; + + for (unsigned int i = 0; i < self->args.size (); ++i) + argv[i] = const_cast (self->args[i].c_str ()); + argv[self->args.size ()] = NULL; + + return self->fork_exec (argv, fds, stderr_fds); + } + + static int + do_compile_v0 (struct gcc_base_context *s, const char *filename, + int verbose) + { + do_set_verbose (s, verbose); + return do_compile (s, filename); + } + + static void + do_destroy (struct gcc_base_context *s) + { + base_gdb_plugin *self = get_self (s); + + delete self; + } }; // Instances of this rpc<> template function are installed into the diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc index b9f1eb343aaf..cbc54ee0a044 100644 --- a/libcc1/libcc1.cc +++ b/libcc1/libcc1.cc @@ -42,15 +42,19 @@ along with GCC; see the file COPYING3. If not see // The C compiler context that we hand back to our caller. struct libcc1 : public cc1_plugin::base_gdb_plugin { - libcc1 (const gcc_base_vtable *, const gcc_c_fe_vtable *); + explicit libcc1 (const gcc_c_fe_vtable *); + + void add_callbacks () override; gcc_c_oracle_function *binding_oracle = nullptr; gcc_c_symbol_address_function *address_oracle = nullptr; void *oracle_datum = nullptr; }; -libcc1::libcc1 (const gcc_base_vtable *v, const gcc_c_fe_vtable *cv) - : cc1_plugin::base_gdb_plugin (v) +libcc1::libcc1 (const gcc_c_fe_vtable *cv) + : cc1_plugin::base_gdb_plugin ("libcc1plugin", + C_COMPILER_NAME, + GCC_C_FE_VERSION_1) { c_ops = cv; } @@ -135,244 +139,22 @@ static const struct gcc_c_fe_vtable c_vtable = -static void -libcc1_set_verbose (struct gcc_base_context *s, int /* bool */ verbose) -{ - libcc1 *self = (libcc1 *) s; - - self->set_verbose (verbose != 0); -} - -static char * -libcc1_set_arguments (struct gcc_base_context *s, - int argc, char **argv) -{ - libcc1 *self = (libcc1 *) s; - - std::string compiler; - char *errmsg = self->compilerp->find (C_COMPILER_NAME, compiler); - if (errmsg != NULL) - return errmsg; - - self->args.push_back (compiler); - - for (int i = 0; i < argc; ++i) - self->args.push_back (argv[i]); - - return NULL; -} - -static char * -libcc1_set_triplet_regexp (struct gcc_base_context *s, - const char *triplet_regexp) -{ - libcc1 *self = (libcc1 *) s; - - self->compilerp.reset - (new cc1_plugin::compiler_triplet_regexp (self->verbose, - triplet_regexp)); - return NULL; -} - -static char * -libcc1_set_driver_filename (struct gcc_base_context *s, - const char *driver_filename) -{ - libcc1 *self = (libcc1 *) s; - - self->compilerp.reset - (new cc1_plugin::compiler_driver_filename (self->verbose, - driver_filename)); - return NULL; -} - -static char * -libcc1_set_arguments_v0 (struct gcc_base_context *s, - const char *triplet_regexp, - int argc, char **argv) +void +libcc1::add_callbacks () { - char *errmsg = libcc1_set_triplet_regexp (s, triplet_regexp); - if (errmsg != NULL) - return errmsg; - - return libcc1_set_arguments (s, argc, argv); -} - -static void -libcc1_set_source_file (struct gcc_base_context *s, - const char *file) -{ - libcc1 *self = (libcc1 *) s; - - self->source_file = file; -} - -static void -libcc1_set_print_callback (struct gcc_base_context *s, - void (*print_function) (void *datum, - const char *message), - void *datum) -{ - libcc1 *self = (libcc1 *) s; - - self->print_function = print_function; - self->print_datum = datum; -} - -static int -fork_exec (libcc1 *self, char **argv, int spair_fds[2], int stderr_fds[2]) -{ - pid_t child_pid = fork (); - - if (child_pid == -1) - { - close (spair_fds[0]); - close (spair_fds[1]); - close (stderr_fds[0]); - close (stderr_fds[1]); - return 0; - } - - if (child_pid == 0) - { - // Child. - dup2 (stderr_fds[1], 1); - dup2 (stderr_fds[1], 2); - close (stderr_fds[0]); - close (stderr_fds[1]); - close (spair_fds[0]); - - execvp (argv[0], argv); - _exit (127); - } - else - { - // Parent. - close (spair_fds[1]); - close (stderr_fds[1]); - - cc1_plugin::status result = cc1_plugin::FAIL; - if (self->connection->send ('H') - && ::cc1_plugin::marshall (self->connection.get (), - GCC_C_FE_VERSION_1)) - result = self->connection->wait_for_query (); - - close (spair_fds[0]); - close (stderr_fds[0]); - - while (true) - { - int status; - - if (waitpid (child_pid, &status, 0) == -1) - { - if (errno != EINTR) - return 0; - } - - if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) - return 0; - break; - } - - if (!result) - return 0; - return 1; - } -} - -static int -libcc1_compile (struct gcc_base_context *s, - const char *filename) -{ - libcc1 *self = (libcc1 *) s; - - int fds[2]; - if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) != 0) - { - self->print ("could not create socketpair\n"); - return 0; - } - - int stderr_fds[2]; - if (pipe (stderr_fds) != 0) - { - self->print ("could not create pipe\n"); - close (fds[0]); - close (fds[1]); - return 0; - } - - self->args.push_back ("-fplugin=libcc1plugin"); - char buf[100]; - if (snprintf (buf, sizeof (buf), "-fplugin-arg-libcc1plugin-fd=%d", fds[1]) - >= (long) sizeof (buf)) - abort (); - self->args.push_back (buf); - - self->args.push_back (self->source_file); - self->args.push_back ("-c"); - self->args.push_back ("-o"); - self->args.push_back (filename); - if (self->verbose) - self->args.push_back ("-v"); - - self->set_connection (fds[0], stderr_fds[0]); - cc1_plugin::callback_ftype *fun = cc1_plugin::callback; - self->connection->add_callback ("binding_oracle", fun); + connection->add_callback ("binding_oracle", fun); fun = cc1_plugin::callback; - self->connection->add_callback ("address_oracle", fun); - - char **argv = new (std::nothrow) char *[self->args.size () + 1]; - if (argv == NULL) - return 0; - - for (unsigned int i = 0; i < self->args.size (); ++i) - argv[i] = const_cast (self->args[i].c_str ()); - argv[self->args.size ()] = NULL; - - return fork_exec (self, argv, fds, stderr_fds); -} - -static int -libcc1_compile_v0 (struct gcc_base_context *s, const char *filename, - int verbose) -{ - libcc1_set_verbose (s, verbose); - return libcc1_compile (s, filename); + connection->add_callback ("address_oracle", fun); } -static void -libcc1_destroy (struct gcc_base_context *s) -{ - libcc1 *self = (libcc1 *) s; - - delete self; -} - -static const struct gcc_base_vtable vtable = -{ - GCC_FE_VERSION_1, - libcc1_set_arguments_v0, - libcc1_set_source_file, - libcc1_set_print_callback, - libcc1_compile_v0, - libcc1_destroy, - libcc1_set_verbose, - libcc1_compile, - libcc1_set_arguments, - libcc1_set_triplet_regexp, - libcc1_set_driver_filename, -}; - extern "C" gcc_c_fe_context_function gcc_c_fe_context; #ifdef __GNUC__ @@ -388,5 +170,5 @@ gcc_c_fe_context (enum gcc_base_api_version base_version, || (c_version != GCC_C_FE_VERSION_0 && c_version != GCC_C_FE_VERSION_1)) return NULL; - return new libcc1 (&vtable, &c_vtable); + return new libcc1 (&c_vtable); } diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc index 65e9770205c0..d22d9dc6af8c 100644 --- a/libcc1/libcp1.cc +++ b/libcc1/libcp1.cc @@ -41,7 +41,9 @@ along with GCC; see the file COPYING3. If not see // The C compiler context that we hand back to our caller. struct libcp1 : public cc1_plugin::base_gdb_plugin { - libcp1 (const gcc_base_vtable *, const gcc_cp_fe_vtable *); + explicit libcp1 (const gcc_cp_fe_vtable *); + + void add_callbacks () override; gcc_cp_oracle_function *binding_oracle = nullptr; gcc_cp_symbol_address_function *address_oracle = nullptr; @@ -50,8 +52,10 @@ struct libcp1 : public cc1_plugin::base_gdb_plugin void *oracle_datum = nullptr; }; -libcp1::libcp1 (const gcc_base_vtable *v, const gcc_cp_fe_vtable *cv) - : cc1_plugin::base_gdb_plugin (v) +libcp1::libcp1 (const gcc_cp_fe_vtable *cv) + : cc1_plugin::base_gdb_plugin ("libcp1plugin", + CP_COMPILER_NAME, + GCC_CP_FE_VERSION_0) { cp_ops = cv; } @@ -158,252 +162,30 @@ static const struct gcc_cp_fe_vtable cp_vtable = -static void -libcp1_set_verbose (struct gcc_base_context *s, int /* bool */ verbose) -{ - libcp1 *self = (libcp1 *) s; - - self->set_verbose (verbose != 0); -} - -static char * -libcp1_set_arguments (struct gcc_base_context *s, - int argc, char **argv) -{ - libcp1 *self = (libcp1 *) s; - - std::string compiler; - char *errmsg = self->compilerp->find (CP_COMPILER_NAME, compiler); - if (errmsg != NULL) - return errmsg; - - self->args.push_back (compiler); - - for (int i = 0; i < argc; ++i) - self->args.push_back (argv[i]); - - return NULL; -} - -static char * -libcp1_set_triplet_regexp (struct gcc_base_context *s, - const char *triplet_regexp) -{ - libcp1 *self = (libcp1 *) s; - - self->compilerp.reset - (new cc1_plugin::compiler_triplet_regexp (self->verbose, - triplet_regexp)); - return NULL; -} - -static char * -libcp1_set_driver_filename (struct gcc_base_context *s, - const char *driver_filename) -{ - libcp1 *self = (libcp1 *) s; - - self->compilerp.reset - (new cc1_plugin::compiler_driver_filename (self->verbose, - driver_filename)); - return NULL; -} - -static char * -libcp1_set_arguments_v0 (struct gcc_base_context *s, - const char *triplet_regexp, - int argc, char **argv) -{ - char *errmsg = libcp1_set_triplet_regexp (s, triplet_regexp); - if (errmsg != NULL) - return errmsg; - - return libcp1_set_arguments (s, argc, argv); -} - -static void -libcp1_set_source_file (struct gcc_base_context *s, - const char *file) -{ - libcp1 *self = (libcp1 *) s; - - self->source_file = file; -} - -static void -libcp1_set_print_callback (struct gcc_base_context *s, - void (*print_function) (void *datum, - const char *message), - void *datum) -{ - libcp1 *self = (libcp1 *) s; - - self->print_function = print_function; - self->print_datum = datum; -} - -static int -fork_exec (libcp1 *self, char **argv, int spair_fds[2], int stderr_fds[2]) -{ - pid_t child_pid = fork (); - - if (child_pid == -1) - { - close (spair_fds[0]); - close (spair_fds[1]); - close (stderr_fds[0]); - close (stderr_fds[1]); - return 0; - } - - if (child_pid == 0) - { - // Child. - dup2 (stderr_fds[1], 1); - dup2 (stderr_fds[1], 2); - close (stderr_fds[0]); - close (stderr_fds[1]); - close (spair_fds[0]); - - execvp (argv[0], argv); - _exit (127); - } - else - { - // Parent. - close (spair_fds[1]); - close (stderr_fds[1]); - - cc1_plugin::status result = cc1_plugin::FAIL; - if (self->connection->send ('H') - && ::cc1_plugin::marshall (self->connection.get (), - GCC_CP_FE_VERSION_0)) - result = self->connection->wait_for_query (); - - close (spair_fds[0]); - close (stderr_fds[0]); - - while (true) - { - int status; - - if (waitpid (child_pid, &status, 0) == -1) - { - if (errno != EINTR) - return 0; - } - - if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) - return 0; - break; - } - - if (!result) - return 0; - return 1; - } -} - -static int -libcp1_compile (struct gcc_base_context *s, - const char *filename) +void +libcp1::add_callbacks () { - libcp1 *self = (libcp1 *) s; - - int fds[2]; - if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) != 0) - { - self->print ("could not create socketpair\n"); - return 0; - } - - int stderr_fds[2]; - if (pipe (stderr_fds) != 0) - { - self->print ("could not create pipe\n"); - close (fds[0]); - close (fds[1]); - return 0; - } - - self->args.push_back ("-fplugin=libcp1plugin"); - char buf[100]; - if (snprintf (buf, sizeof (buf), "-fplugin-arg-libcp1plugin-fd=%d", fds[1]) - >= (long) sizeof (buf)) - abort (); - self->args.push_back (buf); - - self->args.push_back (self->source_file); - self->args.push_back ("-c"); - self->args.push_back ("-o"); - self->args.push_back (filename); - if (self->verbose) - self->args.push_back ("-v"); - - self->set_connection (fds[0], stderr_fds[0]); - cc1_plugin::callback_ftype *fun = cc1_plugin::callback; - self->connection->add_callback ("binding_oracle", fun); + connection->add_callback ("binding_oracle", fun); fun = cc1_plugin::callback; - self->connection->add_callback ("address_oracle", fun); + connection->add_callback ("address_oracle", fun); fun = cc1_plugin::callback; - self->connection->add_callback ("enter_scope", fun); + connection->add_callback ("enter_scope", fun); fun = cc1_plugin::callback; - self->connection->add_callback ("leave_scope", fun); - - char **argv = new (std::nothrow) char *[self->args.size () + 1]; - if (argv == NULL) - return 0; - - for (unsigned int i = 0; i < self->args.size (); ++i) - argv[i] = const_cast (self->args[i].c_str ()); - argv[self->args.size ()] = NULL; - - return fork_exec (self, argv, fds, stderr_fds); -} - -static int -libcp1_compile_v0 (struct gcc_base_context *s, const char *filename, - int verbose) -{ - libcp1_set_verbose (s, verbose); - return libcp1_compile (s, filename); + connection->add_callback ("leave_scope", fun); } -static void -libcp1_destroy (struct gcc_base_context *s) -{ - libcp1 *self = (libcp1 *) s; - - delete self; -} - -static const struct gcc_base_vtable vtable = -{ - GCC_FE_VERSION_1, - libcp1_set_arguments_v0, - libcp1_set_source_file, - libcp1_set_print_callback, - libcp1_compile_v0, - libcp1_destroy, - libcp1_set_verbose, - libcp1_compile, - libcp1_set_arguments, - libcp1_set_triplet_regexp, - libcp1_set_driver_filename, -}; - extern "C" gcc_cp_fe_context_function gcc_cp_fe_context; #ifdef __GNUC__ @@ -419,5 +201,5 @@ gcc_cp_fe_context (enum gcc_base_api_version base_version, || cp_version != GCC_CP_FE_VERSION_0) return NULL; - return new libcp1 (&vtable, &cp_vtable); + return new libcp1 (&cp_vtable); } -- 2.26.2