public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v2 00/21] C++11-based improvements for libcc1
@ 2021-04-28  1:00 Tom Tromey
  2021-04-28  1:00 ` [PATCH v2 01/21] libcc1: use templates to unmarshall enums Tom Tromey
                   ` (20 more replies)
  0 siblings, 21 replies; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:00 UTC (permalink / raw)
  To: gcc-patches

Here is v2 of my series to simplify libcc1 through the use of C++11
constructs.

v1 is here:

    https://gcc.gnu.org/pipermail/gcc-patches/2021-January/562668.html

I never pinged it because I'd sent it in the wrong stage.

As with v1, this brings libcc1 much closer to how I originally wanted
it to work.  Back then, C++11 couldn't be used, so some things had to
be written in a verbose way.  C++11 brings variadic templates, which
make it possible to simplify this code.

This version of the series brings more improvements.

The plugin for the C++ compiler was apparently written by copying much
of the C compiler code.  However, the original design was to unify
these, and this series eliminates much of the duplication.

This version also removes some manual memory management; typically in
favor of either unique_ptr or vector, but also via custom 'deleter'
classes for the rpc code.

Finally, a couple of minor bugs are fixed along the way.

I built and tested this against git GDB on x86-64 Fedora 32.

Note that the C++ plugin currently does not for git GCC -- it crashes.
This series doesn't make it worse (it may slightly change the reported
failures), but nor does it improve it.

Tom



^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 01/21] libcc1: use templates to unmarshall enums
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
@ 2021-04-28  1:00 ` Tom Tromey
  2021-04-28 18:27   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 02/21] libcc1: use "override" Tom Tromey
                   ` (19 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

Now that C++11 can be used in GCC, libcc1 can be changed to use
templates and type traits to handle unmarshalling all kinds of enums.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* marshall.hh (cc1_plugin::unmarshall): Use type traits.
	* marshall-cp.hh (cc1_plugin::unmarshall): Remove overloads.
	* marshall-c.hh: Remove.
	* libcc1plugin.cc: Update includes.
	* libcc1.cc: Update includes.
---
 libcc1/ChangeLog       |  8 ++++++
 libcc1/libcc1.cc       |  3 ++-
 libcc1/libcc1plugin.cc |  3 ++-
 libcc1/marshall-c.hh   | 59 ------------------------------------------
 libcc1/marshall-cp.hh  | 40 ----------------------------
 libcc1/marshall.hh     | 26 +++++++++++++++----
 6 files changed, 33 insertions(+), 106 deletions(-)
 delete mode 100644 libcc1/marshall-c.hh

diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index e4c200c8abd5..68d366a72871 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include <sys/stat.h>
 #include <stdlib.h>
 #include <sstream>
-#include "marshall-c.hh"
+#include "marshall.hh"
 #include "rpc.hh"
 #include "connection.hh"
 #include "names.hh"
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "findcomp.hh"
 #include "compiler-name.hh"
 #include "intl.h"
+#include "gcc-c-interface.h"
 
 struct libcc1;
 
diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc
index e80ecd8f4b35..59e4851064a2 100644
--- a/libcc1/libcc1plugin.cc
+++ b/libcc1/libcc1plugin.cc
@@ -63,8 +63,9 @@
 
 #include "callbacks.hh"
 #include "connection.hh"
-#include "marshall-c.hh"
+#include "marshall.hh"
 #include "rpc.hh"
+#include "gcc-c-interface.h"
 
 #ifdef __GNUC__
 #pragma GCC visibility push(default)
diff --git a/libcc1/marshall-c.hh b/libcc1/marshall-c.hh
deleted file mode 100644
index 212603ebb819..000000000000
--- a/libcc1/marshall-c.hh
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Marshalling and unmarshalling of C-specific types.
-   Copyright (C) 2014-2021 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_MARSHALL_C_HH
-#define CC1_PLUGIN_MARSHALL_C_HH
-
-#include "marshall.hh"
-#include "gcc-c-interface.h"
-
-namespace cc1_plugin
-{
-  status
-  unmarshall (connection *conn, enum gcc_c_symbol_kind *result)
-  {
-    protocol_int p;
-    if (!unmarshall_intlike (conn, &p))
-      return FAIL;
-    *result = (enum gcc_c_symbol_kind) p;
-    return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_c_oracle_request *result)
-  {
-    protocol_int p;
-    if (!unmarshall_intlike (conn, &p))
-      return FAIL;
-    *result = (enum gcc_c_oracle_request) p;
-    return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_qualifiers *result)
-  {
-    protocol_int p;
-    if (!unmarshall_intlike (conn, &p))
-      return FAIL;
-    *result = (enum gcc_qualifiers) p;
-    return OK;
-  }
-}
-
-#endif // CC1_PLUGIN_MARSHALL_C_HH
diff --git a/libcc1/marshall-cp.hh b/libcc1/marshall-cp.hh
index ff80bfe41870..3d6ae4126aee 100644
--- a/libcc1/marshall-cp.hh
+++ b/libcc1/marshall-cp.hh
@@ -25,46 +25,6 @@ along with GCC; see the file COPYING3.  If not see
 
 namespace cc1_plugin
 {
-  status
-  unmarshall (connection *conn, enum gcc_cp_symbol_kind *result)
-  {
-    protocol_int p;
-    if (!unmarshall_intlike (conn, &p))
-      return FAIL;
-    *result = (enum gcc_cp_symbol_kind) p;
-    return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_cp_oracle_request *result)
-  {
-    protocol_int p;
-    if (!unmarshall_intlike (conn, &p))
-      return FAIL;
-    *result = (enum gcc_cp_oracle_request) p;
-    return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_cp_qualifiers *result)
-  {
-    protocol_int p;
-    if (!unmarshall_intlike (conn, &p))
-      return FAIL;
-    *result = (enum gcc_cp_qualifiers) p;
-    return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_cp_ref_qualifiers *result)
-  {
-    protocol_int p;
-    if (!unmarshall_intlike (conn, &p))
-      return FAIL;
-    *result = (enum gcc_cp_ref_qualifiers) p;
-    return OK;
-  }
-
   // Send a gcc_vbase_array marker followed by the array.
   status
   marshall (connection *conn, const gcc_vbase_array *a)
diff --git a/libcc1/marshall.hh b/libcc1/marshall.hh
index 6999c4ff8fd1..8d890eb9b6c7 100644
--- a/libcc1/marshall.hh
+++ b/libcc1/marshall.hh
@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef CC1_PLUGIN_MARSHALL_HH
 #define CC1_PLUGIN_MARSHALL_HH
 
+#include <type_traits>
+
 #include "status.hh"
 #include "gcc-interface.h"
 
@@ -59,17 +61,31 @@ namespace cc1_plugin
   }
 
   // A template function that can handle unmarshalling various integer
-  // objects from the connection.  Note that this can't be
-  // instantiated for enum types.  Note also that there's no way at
-  // the protocol level to distinguish different int types.
+  // objects from the connection.  Note that there's no way at the
+  // protocol level to distinguish different int types.
+  template<typename T>
+  status unmarshall (connection *conn, T *scalar,
+		     typename std::enable_if<std::is_integral<T>::value, T>::type * = 0)
+  {
+    protocol_int result;
+
+    if (!unmarshall_intlike (conn, &result))
+      return FAIL;
+    *scalar = (T) result;
+    return OK;
+  }
+
+  // A template function that can handle unmarshalling various enum
+  // objects from the connection.
   template<typename T>
-  status unmarshall (connection *conn, T *scalar)
+  status unmarshall (connection *conn, T *e_val,
+		     typename std::enable_if<std::is_enum<T>::value, T>::type * = 0)
   {
     protocol_int result;
 
     if (!unmarshall_intlike (conn, &result))
       return FAIL;
-    *scalar = result;
+    *e_val = (T) result;
     return OK;
   }
 
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 02/21] libcc1: use "override"
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
  2021-04-28  1:00 ` [PATCH v2 01/21] libcc1: use templates to unmarshall enums Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-28 15:53   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 03/21] libcc1: inline some simple methods Tom Tromey
                   ` (18 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

This changes libcc1 to use "override" where appropriate.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* libcp1.cc (class compiler_triplet_regexp)
	(class compiler_driver_filename, class libcp1_connection): Use
	"override".
	* libcc1.cc (class compiler_triplet_regexp)
	(class compiler_driver_filename, class libcc1_connection): Use
	"override".
---
 libcc1/ChangeLog | 9 +++++++++
 libcc1/libcc1.cc | 6 +++---
 libcc1/libcp1.cc | 6 +++---
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index 68d366a72871..2c08dabb1a49 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -93,7 +93,7 @@ struct libcc1 : public gcc_c_context
   private:
     std::string triplet_regexp_;
   public:
-    virtual char *find (std::string &compiler) const;
+    char *find (std::string &compiler) const override;
     compiler_triplet_regexp (libcc1 *self, std::string triplet_regexp)
       : compiler (self), triplet_regexp_ (triplet_regexp)
     {
@@ -109,7 +109,7 @@ struct libcc1 : public gcc_c_context
   private:
     std::string driver_filename_;
   public:
-    virtual char *find (std::string &compiler) const;
+    char *find (std::string &compiler) const override;
     compiler_driver_filename (libcc1 *self, std::string driver_filename)
       : compiler (self), driver_filename_ (driver_filename)
     {
@@ -132,7 +132,7 @@ public:
   {
   }
 
-  virtual void print (const char *buf)
+  void print (const char *buf) override
   {
     back_ptr->print (buf);
   }
diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc
index 34d89579c31c..fb91125ef0cf 100644
--- a/libcc1/libcp1.cc
+++ b/libcc1/libcp1.cc
@@ -94,7 +94,7 @@ struct libcp1 : public gcc_cp_context
   private:
     std::string triplet_regexp_;
   public:
-    virtual char *find (std::string &compiler) const;
+    char *find (std::string &compiler) const override;
     compiler_triplet_regexp (libcp1 *self, std::string triplet_regexp)
       : compiler (self), triplet_regexp_ (triplet_regexp)
     {
@@ -110,7 +110,7 @@ struct libcp1 : public gcc_cp_context
   private:
     std::string driver_filename_;
   public:
-    virtual char *find (std::string &compiler) const;
+    char *find (std::string &compiler) const override;
     compiler_driver_filename (libcp1 *self, std::string driver_filename)
       : compiler (self), driver_filename_ (driver_filename)
     {
@@ -133,7 +133,7 @@ public:
   {
   }
 
-  virtual void print (const char *buf)
+  void print (const char *buf) override
   {
     back_ptr->print (buf);
   }
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 03/21] libcc1: inline some simple methods
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
  2021-04-28  1:00 ` [PATCH v2 01/21] libcc1: use templates to unmarshall enums Tom Tromey
  2021-04-28  1:01 ` [PATCH v2 02/21] libcc1: use "override" Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-28 15:54   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 04/21] libcc1: delete copy constructor and assignment operators Tom Tromey
                   ` (17 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

This changes libcc1 to inline a trivial method and to use the default
constructor.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* connection.hh (~connection): Use default.
	(print): Inline.
	* connection.cc (cc1_plugin::connection::~connection)
	(cc1_plugin::connection::print): Remove definitions.
---
 libcc1/ChangeLog     | 7 +++++++
 libcc1/connection.cc | 9 ---------
 libcc1/connection.hh | 6 ++++--
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/libcc1/connection.cc b/libcc1/connection.cc
index 64a6d4922c15..66d573911080 100644
--- a/libcc1/connection.cc
+++ b/libcc1/connection.cc
@@ -27,15 +27,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "connection.hh"
 #include "rpc.hh"
 
-cc1_plugin::connection::~connection ()
-{
-}
-
-void
-cc1_plugin::connection::print (const char *)
-{
-}
-
 cc1_plugin::status
 cc1_plugin::connection::send (char c)
 {
diff --git a/libcc1/connection.hh b/libcc1/connection.hh
index 50e8a8b5a032..a0e99bdbd98f 100644
--- a/libcc1/connection.hh
+++ b/libcc1/connection.hh
@@ -46,7 +46,7 @@ namespace cc1_plugin
     {
     }
 
-    virtual ~connection ();
+    virtual ~connection () = default;
 
     // Send a single character.  This is used to introduce various
     // higher-level protocol elements.
@@ -89,7 +89,9 @@ namespace cc1_plugin
       m_callbacks.add_callback (name, func);
     }
 
-    virtual void print (const char *);
+    virtual void print (const char *)
+    {
+    }
 
   private:
 
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 04/21] libcc1: delete copy constructor and assignment operators
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (2 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 03/21] libcc1: inline some simple methods Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-28 15:55   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 05/21] libcc1: use variadic templates for "call" Tom Tromey
                   ` (16 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

Change libcc1 to use "= delete" for the copy constructor and
assignment operator, rather than the old approach of private methods
that are nowhere defined.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* rpc.hh (argument_wrapper): Use delete for copy constructor.
	* connection.hh (class connection): Use delete for copy
	constructor.
	* callbacks.hh (class callbacks): Use delete for copy constructor.
---
 libcc1/ChangeLog     |  7 +++++++
 libcc1/callbacks.hh  |  7 +++----
 libcc1/connection.hh |  7 +++----
 libcc1/rpc.hh        | 42 ++++++++++++++++++------------------------
 4 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/libcc1/callbacks.hh b/libcc1/callbacks.hh
index b1f3e98d917b..dc470c62c48d 100644
--- a/libcc1/callbacks.hh
+++ b/libcc1/callbacks.hh
@@ -42,6 +42,9 @@ namespace cc1_plugin
     callbacks ();
     ~callbacks ();
 
+    callbacks (const callbacks &) = delete;
+    callbacks &operator= (const callbacks &) = delete;
+
     // Add a callback named NAME.  FUNC is the function to call when
     // this method is invoked.
     void add_callback (const char *name, callback_ftype *func);
@@ -52,10 +55,6 @@ namespace cc1_plugin
 
   private:
 
-    // Declared but not defined to avoid use.
-    callbacks (const callbacks &);
-    callbacks &operator= (const callbacks &);
-
     // The mapping.
     htab_t m_registry;
   };
diff --git a/libcc1/connection.hh b/libcc1/connection.hh
index a0e99bdbd98f..15ad1716a29e 100644
--- a/libcc1/connection.hh
+++ b/libcc1/connection.hh
@@ -48,6 +48,9 @@ namespace cc1_plugin
 
     virtual ~connection () = default;
 
+    connection (const connection &) = delete;
+    connection &operator= (const connection &) = delete;
+
     // Send a single character.  This is used to introduce various
     // higher-level protocol elements.
     status send (char c);
@@ -95,10 +98,6 @@ namespace cc1_plugin
 
   private:
 
-    // Declared but not defined, to prevent use.
-    connection (const connection &);
-    connection &operator= (const connection &);
-
     // Helper function for the wait_* methods.
     status do_wait (bool);
 
diff --git a/libcc1/rpc.hh b/libcc1/rpc.hh
index a8e33577ea18..429aeb3c1278 100644
--- a/libcc1/rpc.hh
+++ b/libcc1/rpc.hh
@@ -39,6 +39,9 @@ namespace cc1_plugin
     argument_wrapper () { }
     ~argument_wrapper () { }
 
+    argument_wrapper (const argument_wrapper &) = delete;
+    argument_wrapper &operator= (const argument_wrapper &) = delete;
+
     operator T () const { return m_object; }
 
     status unmarshall (connection *conn)
@@ -49,10 +52,6 @@ namespace cc1_plugin
   private:
 
     T m_object;
-
-    // No copying or assignment allowed.
-    argument_wrapper (const argument_wrapper &);
-    argument_wrapper &operator= (const argument_wrapper &);
   };
 
   // Specialization for any kind of pointer.  This is declared but not
@@ -72,6 +71,9 @@ namespace cc1_plugin
       delete[] m_object;
     }
 
+    argument_wrapper (const argument_wrapper &) = delete;
+    argument_wrapper &operator= (const argument_wrapper &) = delete;
+
     operator const char * () const
     {
       return m_object;
@@ -85,10 +87,6 @@ namespace cc1_plugin
   private:
 
     char *m_object;
-
-    // No copying or assignment allowed.
-    argument_wrapper (const argument_wrapper &);
-    argument_wrapper &operator= (const argument_wrapper &);
   };
 
   // Specialization for gcc_type_array.
@@ -106,6 +104,9 @@ namespace cc1_plugin
       delete m_object;
     }
 
+    argument_wrapper (const argument_wrapper &) = delete;
+    argument_wrapper &operator= (const argument_wrapper &) = delete;
+
     operator const gcc_type_array * () const
     {
       return m_object;
@@ -119,10 +120,6 @@ namespace cc1_plugin
   private:
 
     gcc_type_array *m_object;
-
-    // No copying or assignment allowed.
-    argument_wrapper (const argument_wrapper &);
-    argument_wrapper &operator= (const argument_wrapper &);
   };
 
 #ifdef GCC_CP_INTERFACE_H
@@ -144,6 +141,9 @@ namespace cc1_plugin
       delete m_object;
     }
 
+    argument_wrapper (const argument_wrapper &) = delete;
+    argument_wrapper &operator= (const argument_wrapper &) = delete;
+
     operator const gcc_vbase_array * () const
     {
       return m_object;
@@ -157,10 +157,6 @@ namespace cc1_plugin
   private:
 
     gcc_vbase_array *m_object;
-
-    // No copying or assignment allowed.
-    argument_wrapper (const argument_wrapper &);
-    argument_wrapper &operator= (const argument_wrapper &);
   };
 
   // Specialization for gcc_cp_template_args.
@@ -181,6 +177,9 @@ namespace cc1_plugin
       delete m_object;
     }
 
+    argument_wrapper (const argument_wrapper &) = delete;
+    argument_wrapper &operator= (const argument_wrapper &) = delete;
+
     operator const gcc_cp_template_args * () const
     {
       return m_object;
@@ -194,10 +193,6 @@ namespace cc1_plugin
   private:
 
     gcc_cp_template_args *m_object;
-
-    // No copying or assignment allowed.
-    argument_wrapper (const argument_wrapper &);
-    argument_wrapper &operator= (const argument_wrapper &);
   };
 
   // Specialization for gcc_cp_function_args.
@@ -217,6 +212,9 @@ namespace cc1_plugin
       delete m_object;
     }
 
+    argument_wrapper (const argument_wrapper &) = delete;
+    argument_wrapper &operator= (const argument_wrapper &) = delete;
+
     operator const gcc_cp_function_args * () const
     {
       return m_object;
@@ -230,10 +228,6 @@ namespace cc1_plugin
   private:
 
     gcc_cp_function_args *m_object;
-
-    // No copying or assignment allowed.
-    argument_wrapper (const argument_wrapper &);
-    argument_wrapper &operator= (const argument_wrapper &);
   };
 #endif /* GCC_CP_INTERFACE_H */
 
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 05/21] libcc1: use variadic templates for "call"
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (3 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 04/21] libcc1: delete copy constructor and assignment operators Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-28 18:28   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 06/21] libcc1: use variadic templates for "rpc" Tom Tromey
                   ` (15 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

This changes libcc1 to use variadic templates for the "call"
functions.  The primary benefit is that this simplifies the code.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* rpc.hh (call): Use variadic template.  Remove overloads.
	* marshall.hh (marshall): Add base overload.  Use variadic
	template.
---
 libcc1/ChangeLog   |   6 ++
 libcc1/marshall.hh |  16 +++++
 libcc1/rpc.hh      | 168 +++------------------------------------------
 3 files changed, 31 insertions(+), 159 deletions(-)

diff --git a/libcc1/marshall.hh b/libcc1/marshall.hh
index 8d890eb9b6c7..4a28a8fe4ae2 100644
--- a/libcc1/marshall.hh
+++ b/libcc1/marshall.hh
@@ -52,6 +52,14 @@ namespace cc1_plugin
   status unmarshall_array_start (connection *, char, size_t *);
   status unmarshall_array_elmts (connection *, size_t, void *);
 
+  // An "empty" marshall call -- used to handle the base case for some
+  // variadic templates.
+  static inline
+  status marshall (connection *)
+  {
+    return OK;
+  }
+
   // A template function that can handle marshalling various integer
   // objects to the connection.
   template<typename T>
@@ -103,6 +111,14 @@ namespace cc1_plugin
   // resulting array must be freed by the caller, using 'delete[]' on
   // the elements, and 'delete' on the array object itself.
   status unmarshall (connection *, struct gcc_type_array **);
+
+  template<typename T1, typename T2, typename... Arg>
+  status marshall (connection *c, T1 arg1, T2 arg2, Arg... rest)
+  {
+    if (!marshall (c, arg1))
+      return FAIL;
+    return marshall (c, arg2, rest...);
+  }
 };
 
 #endif // CC1_PLUGIN_MARSHALL_HH
diff --git a/libcc1/rpc.hh b/libcc1/rpc.hh
index 429aeb3c1278..a3631cb5d7e2 100644
--- a/libcc1/rpc.hh
+++ b/libcc1/rpc.hh
@@ -232,10 +232,10 @@ namespace cc1_plugin
 #endif /* GCC_CP_INTERFACE_H */
 
   // There are two kinds of template functions here: "call" and
-  // "callback".  They are each repeated multiple times to handle
-  // different numbers of arguments.  (This would be improved with
-  // C++11, though applying a call is still tricky until C++14 can be
-  // used.)
+  // "callback".  "call" is implemented with variadic templates, but
+  // "callback" is repeated multiple times to handle different numbers
+  // of arguments.  (This could be improved with C++17 and
+  // std::apply.)
 
   // The "call" template is used for making a remote procedure call.
   // It starts a query ('Q') packet, marshalls its arguments, waits
@@ -248,15 +248,17 @@ namespace cc1_plugin
   // arguments, passes them to the wrapped function, and finally
   // marshalls a reply packet.
 
-  template<typename R>
+  template<typename R, typename... Arg>
   status
-  call (connection *conn, const char *method, R *result)
+  call (connection *conn, const char *method, R *result, Arg... args)
   {
     if (!conn->send ('Q'))
       return FAIL;
     if (!marshall (conn, method))
       return FAIL;
-    if (!marshall (conn, 0))
+    if (!marshall (conn, (int) sizeof... (Arg)))
+      return FAIL;
+    if (!marshall (conn, args...))
       return FAIL;
     if (!conn->wait_for_result ())
       return FAIL;
@@ -279,25 +281,6 @@ namespace cc1_plugin
     return marshall (conn, result);
   }
 
-  template<typename R, typename A>
-  status
-  call (connection *conn, const char *method, R *result, A arg)
-  {
-    if (!conn->send ('Q'))
-      return FAIL;
-    if (!marshall (conn, method))
-      return FAIL;
-    if (!marshall (conn, 1))
-      return FAIL;
-    if (!marshall (conn, arg))
-      return FAIL;
-    if (!conn->wait_for_result ())
-      return FAIL;
-    if (!unmarshall (conn, result))
-      return FAIL;
-    return OK;
-  }
-
   template<typename R, typename A, R (*func) (connection *, A)>
   status
   callback (connection *conn)
@@ -315,27 +298,6 @@ namespace cc1_plugin
     return marshall (conn, result);
   }
 
-  template<typename R, typename A1, typename A2>
-  status
-  call (connection *conn, const char *method, R *result, A1 arg1, A2 arg2)
-  {
-    if (!conn->send ('Q'))
-      return FAIL;
-    if (!marshall (conn, method))
-      return FAIL;
-    if (!marshall (conn, 2))
-      return FAIL;
-    if (!marshall (conn, arg1))
-      return FAIL;
-    if (!marshall (conn, arg2))
-      return FAIL;
-    if (!conn->wait_for_result ())
-      return FAIL;
-    if (!unmarshall (conn, result))
-      return FAIL;
-    return OK;
-  }
-
   template<typename R, typename A1, typename A2, R (*func) (connection *,
 							    A1, A2)>
   status
@@ -357,30 +319,6 @@ namespace cc1_plugin
     return marshall (conn, result);
   }
 
-  template<typename R, typename A1, typename A2, typename A3>
-  status
-  call (connection *conn, const char *method, R *result, A1 arg1, A2 arg2,
-	A3 arg3)
-  {
-    if (!conn->send ('Q'))
-      return FAIL;
-    if (!marshall (conn, method))
-      return FAIL;
-    if (!marshall (conn, 3))
-      return FAIL;
-    if (!marshall (conn, arg1))
-      return FAIL;
-    if (!marshall (conn, arg2))
-      return FAIL;
-    if (!marshall (conn, arg3))
-      return FAIL;
-    if (!conn->wait_for_result ())
-      return FAIL;
-    if (!unmarshall (conn, result))
-      return FAIL;
-    return OK;
-  }
-
   template<typename R, typename A1, typename A2, typename A3,
 	   R (*func) (connection *, A1, A2, A3)>
   status
@@ -405,32 +343,6 @@ namespace cc1_plugin
     return marshall (conn, result);
   }
 
-  template<typename R, typename A1, typename A2, typename A3, typename A4>
-  status
-  call (connection *conn, const char *method, R *result, A1 arg1, A2 arg2,
-	A3 arg3, A4 arg4)
-  {
-    if (!conn->send ('Q'))
-      return FAIL;
-    if (!marshall (conn, method))
-      return FAIL;
-    if (!marshall (conn, 4))
-      return FAIL;
-    if (!marshall (conn, arg1))
-      return FAIL;
-    if (!marshall (conn, arg2))
-      return FAIL;
-    if (!marshall (conn, arg3))
-      return FAIL;
-    if (!marshall (conn, arg4))
-      return FAIL;
-    if (!conn->wait_for_result ())
-      return FAIL;
-    if (!unmarshall (conn, result))
-      return FAIL;
-    return OK;
-  }
-
   template<typename R, typename A1, typename A2, typename A3, typename A4,
 	   R (*func) (connection *, A1, A2, A3, A4)>
   status
@@ -458,35 +370,6 @@ namespace cc1_plugin
     return marshall (conn, result);
   }
 
-  template<typename R, typename A1, typename A2, typename A3, typename A4,
-	   typename A5>
-  status
-  call (connection *conn, const char *method, R *result, A1 arg1, A2 arg2,
-	A3 arg3, A4 arg4, A5 arg5)
-  {
-    if (!conn->send ('Q'))
-      return FAIL;
-    if (!marshall (conn, method))
-      return FAIL;
-    if (!marshall (conn, 5))
-      return FAIL;
-    if (!marshall (conn, arg1))
-      return FAIL;
-    if (!marshall (conn, arg2))
-      return FAIL;
-    if (!marshall (conn, arg3))
-      return FAIL;
-    if (!marshall (conn, arg4))
-      return FAIL;
-    if (!marshall (conn, arg5))
-      return FAIL;
-    if (!conn->wait_for_result ())
-      return FAIL;
-    if (!unmarshall (conn, result))
-      return FAIL;
-    return OK;
-  }
-
   template<typename R, typename A1, typename A2, typename A3, typename A4,
 	   typename A5, R (*func) (connection *, A1, A2, A3, A4, A5)>
   status
@@ -517,39 +400,6 @@ namespace cc1_plugin
     return marshall (conn, result);
   }
 
-  template<typename R, typename A1, typename A2, typename A3, typename A4,
-	   typename A5, typename A6, typename A7>
-  status
-  call (connection *conn, const char *method, R *result, A1 arg1, A2 arg2,
-	A3 arg3, A4 arg4, A5 arg5, A6 arg6, A7 arg7)
-  {
-    if (!conn->send ('Q'))
-      return FAIL;
-    if (!marshall (conn, method))
-      return FAIL;
-    if (!marshall (conn, 7))
-      return FAIL;
-    if (!marshall (conn, arg1))
-      return FAIL;
-    if (!marshall (conn, arg2))
-      return FAIL;
-    if (!marshall (conn, arg3))
-      return FAIL;
-    if (!marshall (conn, arg4))
-      return FAIL;
-    if (!marshall (conn, arg5))
-      return FAIL;
-    if (!marshall (conn, arg6))
-      return FAIL;
-    if (!marshall (conn, arg7))
-      return FAIL;
-    if (!conn->wait_for_result ())
-      return FAIL;
-    if (!unmarshall (conn, result))
-      return FAIL;
-    return OK;
-  }
-
   template<typename R, typename A1, typename A2, typename A3, typename A4,
 	   typename A5, typename A6, typename A7,
 	   R (*func) (connection *, A1, A2, A3, A4, A5, A6, A7)>
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 06/21] libcc1: use variadic templates for "rpc"
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (4 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 05/21] libcc1: use variadic templates for "call" Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-28 18:28   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 07/21] libcc1: use std::vector when building function types Tom Tromey
                   ` (14 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

This changes libcc1 to use variadic templates for the "rpc" functions.
This simplifies the code and removes some possibility for mistakes.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* libcp1.cc (rpc): Use variadic template.  Remove overloads.
	* libcc1.cc (rpc): Use variadic template.  Remove overloads.
---
 libcc1/ChangeLog |  5 +++
 libcc1/libcc1.cc | 81 +++---------------------------------------------
 libcc1/libcp1.cc | 81 +++---------------------------------------------
 3 files changed, 13 insertions(+), 154 deletions(-)

diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index 2c08dabb1a49..3432f4e8b212 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -210,90 +210,17 @@ set_callbacks (struct gcc_c_context *s,
   self->oracle_datum = datum;
 }
 
-// Instances of these rpc<> template functions are installed into the
+// 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>
-R rpc (struct gcc_c_context *s)
+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, NAME, &result))
-    return 0;
-  return result;
-}
-
-template<typename R, const char *&NAME, typename A>
-R rpc (struct gcc_c_context *s, A arg)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg))
-    return 0;
-  return result;
-}
-
-template<typename R, const char *&NAME, typename A1, typename A2>
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2))
-    return 0;
-  return result;
-}
-
-template<typename R, const char *&NAME, typename A1, typename A2, typename A3>
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3))
-    return 0;
-  return result;
-}
-
-template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
-	 typename A4>
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
-			 arg4))
-    return 0;
-  return result;
-}
-
-template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
-	 typename A4, typename A5>
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
-			 arg4, arg5))
-    return 0;
-  return result;
-}
-
-template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
-	 typename A4, typename A5, typename A6, typename A7>
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5,
-       A6 arg6, A7 arg7)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
-			 arg4, arg5, arg6, arg7))
+  if (!cc1_plugin::call (self->connection, NAME, &result, rest...))
     return 0;
   return result;
 }
diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc
index fb91125ef0cf..4273f8d83826 100644
--- a/libcc1/libcp1.cc
+++ b/libcc1/libcp1.cc
@@ -233,90 +233,17 @@ set_callbacks (struct gcc_cp_context *s,
   self->oracle_datum = datum;
 }
 
-// Instances of these rpc<> template functions are installed into the
+// 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>
-R rpc (struct gcc_cp_context *s)
+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, NAME, &result))
-    return 0;
-  return result;
-}
-
-template<typename R, const char *&NAME, typename A>
-R rpc (struct gcc_cp_context *s, A arg)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg))
-    return 0;
-  return result;
-}
-
-template<typename R, const char *&NAME, typename A1, typename A2>
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2))
-    return 0;
-  return result;
-}
-
-template<typename R, const char *&NAME, typename A1, typename A2, typename A3>
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2, A3 arg3)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3))
-    return 0;
-  return result;
-}
-
-template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
-	 typename A4>
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
-			 arg4))
-    return 0;
-  return result;
-}
-
-template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
-	 typename A4, typename A5>
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
-			 arg4, arg5))
-    return 0;
-  return result;
-}
-
-template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
-	 typename A4, typename A5, typename A6, typename A7>
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5,
-       A6 arg6, A7 arg7)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
-			 arg4, arg5, arg6, arg7))
+  if (!cc1_plugin::call (self->connection, NAME, &result, rest...))
     return 0;
   return result;
 }
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 07/21] libcc1: use std::vector when building function types
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (5 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 06/21] libcc1: use variadic templates for "rpc" Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-28 16:01   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 08/21] libcc1: add deleter objects Tom Tromey
                   ` (13 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

This changes libcc1 to use std::vector in the code that builds
function types.  This avoids some explicit memory management.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* libcp1plugin.cc (plugin_build_function_type): Use std::vector.
	* libcc1plugin.cc (plugin_build_function_type): Use std::vector.
---
 libcc1/ChangeLog       |  5 +++++
 libcc1/libcc1plugin.cc | 11 +++++------
 libcc1/libcp1plugin.cc | 11 +++++------
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc
index 59e4851064a2..65e748258f40 100644
--- a/libcc1/libcc1plugin.cc
+++ b/libcc1/libcc1plugin.cc
@@ -67,6 +67,8 @@
 #include "rpc.hh"
 #include "gcc-c-interface.h"
 
+#include <vector>
+
 #ifdef __GNUC__
 #pragma GCC visibility push(default)
 #endif
@@ -672,24 +674,21 @@ plugin_build_function_type (cc1_plugin::connection *self,
 			    const struct gcc_type_array *argument_types_in,
 			    int is_varargs)
 {
-  tree *argument_types;
   tree return_type = convert_in (return_type_in);
   tree result;
 
-  argument_types = new tree[argument_types_in->n_elements];
+  std::vector<tree> argument_types (argument_types_in->n_elements);
   for (int i = 0; i < argument_types_in->n_elements; ++i)
     argument_types[i] = convert_in (argument_types_in->elements[i]);
 
   if (is_varargs)
     result = build_varargs_function_type_array (return_type,
 						argument_types_in->n_elements,
-						argument_types);
+						argument_types.data ());
   else
     result = build_function_type_array (return_type,
 					argument_types_in->n_elements,
-					argument_types);
-
-  delete[] argument_types;
+					argument_types.data ());
 
   plugin_context *ctx = static_cast<plugin_context *> (self);
   return convert_out (ctx->preserve (result));
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index 27a6175e34e6..1fc8e269f075 100644
--- a/libcc1/libcp1plugin.cc
+++ b/libcc1/libcp1plugin.cc
@@ -70,6 +70,8 @@
 #include "marshall-cp.hh"
 #include "rpc.hh"
 
+#include <vector>
+
 #ifdef __GNUC__
 #pragma GCC visibility push(default)
 #endif
@@ -1980,24 +1982,21 @@ plugin_build_function_type (cc1_plugin::connection *self,
 			    const struct gcc_type_array *argument_types_in,
 			    int is_varargs)
 {
-  tree *argument_types;
   tree return_type = convert_in (return_type_in);
   tree result;
 
-  argument_types = new tree[argument_types_in->n_elements];
+  std::vector<tree> argument_types (argument_types_in->n_elements);
   for (int i = 0; i < argument_types_in->n_elements; ++i)
     argument_types[i] = convert_in (argument_types_in->elements[i]);
 
   if (is_varargs)
     result = build_varargs_function_type_array (return_type,
 						argument_types_in->n_elements,
-						argument_types);
+						argument_types.data ());
   else
     result = build_function_type_array (return_type,
 					argument_types_in->n_elements,
-					argument_types);
-
-  delete[] argument_types;
+					argument_types.data ());
 
   plugin_context *ctx = static_cast<plugin_context *> (self);
   return convert_out (ctx->preserve (result));
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 08/21] libcc1: add deleter objects
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (6 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 07/21] libcc1: use std::vector when building function types Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-28 21:06   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 09/21] libcc1: add more uses of 'deleter' Tom Tromey
                   ` (12 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

This adds deleter objects for various kinds of protocol pointers to
libcc1.  Existing specializations of argument_wrapper are then
replaced with a single specialization that handles all pointer types
via the appropriate deleter.  The result here is a bit nicer because
the argument_wrapper boilerplate code is completely shared, leaving
just the memory-management detail to the particular specializations.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* rpc.hh (struct deleter): New template class and
	specializations.
	(argument_wrapper): Remove specializations.  Add specialization
	for any pointer type.
---
 libcc1/ChangeLog |   7 ++
 libcc1/rpc.hh    | 176 ++++++++++++-----------------------------------
 2 files changed, 52 insertions(+), 131 deletions(-)

diff --git a/libcc1/rpc.hh b/libcc1/rpc.hh
index a3631cb5d7e2..4e00d61ee98d 100644
--- a/libcc1/rpc.hh
+++ b/libcc1/rpc.hh
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "status.hh"
 #include "connection.hh"
+#include <memory>
 
 namespace cc1_plugin
 {
@@ -54,182 +55,95 @@ namespace cc1_plugin
     T m_object;
   };
 
-  // Specialization for any kind of pointer.  This is declared but not
-  // defined to avoid bugs if a new pointer type is introduced into
-  // the API.  Instead you will just get a compilation error.
-  template<typename T>
-  class argument_wrapper<const T *>;
+  // Any pointer type requires a deleter object that knows how to
+  // clean up.  These are used in multiple places.
+  template<typename T> struct deleter;
 
-  // Specialization for string types.
   template<>
-  class argument_wrapper<const char *>
+  struct deleter<char>
   {
-  public:
-    argument_wrapper () : m_object (NULL) { }
-    ~argument_wrapper ()
+    void operator() (char *s)
     {
-      delete[] m_object;
+      delete[] s;
     }
-
-    argument_wrapper (const argument_wrapper &) = delete;
-    argument_wrapper &operator= (const argument_wrapper &) = delete;
-
-    operator const char * () const
-    {
-      return m_object;
-    }
-
-    status unmarshall (connection *conn)
-    {
-      return ::cc1_plugin::unmarshall (conn, &m_object);
-    }
-
-  private:
-
-    char *m_object;
   };
 
-  // Specialization for gcc_type_array.
   template<>
-  class argument_wrapper<const gcc_type_array *>
+  struct deleter<gcc_type_array>
   {
-  public:
-    argument_wrapper () : m_object (NULL) { }
-    ~argument_wrapper ()
+    void operator() (gcc_type_array *p)
     {
-      // It would be nicer if gcc_type_array could have a destructor.
-      // But, it is in code shared with gdb and cannot.
-      if (m_object != NULL)
-	delete[] m_object->elements;
-      delete m_object;
+      delete[] p->elements;
+      delete p;
     }
-
-    argument_wrapper (const argument_wrapper &) = delete;
-    argument_wrapper &operator= (const argument_wrapper &) = delete;
-
-    operator const gcc_type_array * () const
-    {
-      return m_object;
-    }
-
-    status unmarshall (connection *conn)
-    {
-      return ::cc1_plugin::unmarshall (conn, &m_object);
-    }
-
-  private:
-
-    gcc_type_array *m_object;
   };
 
 #ifdef GCC_CP_INTERFACE_H
-  // Specialization for gcc_vbase_array.
   template<>
-  class argument_wrapper<const gcc_vbase_array *>
+  struct deleter<gcc_vbase_array>
   {
-  public:
-    argument_wrapper () : m_object (NULL) { }
-    ~argument_wrapper ()
-    {
-      // It would be nicer if gcc_type_array could have a destructor.
-      // But, it is in code shared with gdb and cannot.
-      if (m_object != NULL)
-	{
-	  delete[] m_object->flags;
-	  delete[] m_object->elements;
-	}
-      delete m_object;
-    }
-
-    argument_wrapper (const argument_wrapper &) = delete;
-    argument_wrapper &operator= (const argument_wrapper &) = delete;
-
-    operator const gcc_vbase_array * () const
+    void operator() (gcc_vbase_array *p)
     {
-      return m_object;
-    }
-
-    status unmarshall (connection *conn)
-    {
-      return ::cc1_plugin::unmarshall (conn, &m_object);
+      delete[] p->flags;
+      delete[] p->elements;
+      delete p;
     }
-
-  private:
-
-    gcc_vbase_array *m_object;
   };
 
-  // Specialization for gcc_cp_template_args.
   template<>
-  class argument_wrapper<const gcc_cp_template_args *>
+  struct deleter<gcc_cp_template_args>
   {
-  public:
-    argument_wrapper () : m_object (NULL) { }
-    ~argument_wrapper ()
-    {
-      // It would be nicer if gcc_type_array could have a destructor.
-      // But, it is in code shared with gdb and cannot.
-      if (m_object != NULL)
-	{
-	  delete[] m_object->elements;
-	  delete[] m_object->kinds;
-	}
-      delete m_object;
-    }
-
-    argument_wrapper (const argument_wrapper &) = delete;
-    argument_wrapper &operator= (const argument_wrapper &) = delete;
-
-    operator const gcc_cp_template_args * () const
+    void operator() (gcc_cp_template_args *p)
     {
-      return m_object;
+      delete[] p->elements;
+      delete[] p->kinds;
+      delete p;
     }
+  };
 
-    status unmarshall (connection *conn)
+  template<>
+  struct deleter<gcc_cp_function_args>
+  {
+    void operator() (gcc_cp_function_args *p)
     {
-      return ::cc1_plugin::unmarshall (conn, &m_object);
+      delete[] p->elements;
+      delete p;
     }
-
-  private:
-
-    gcc_cp_template_args *m_object;
   };
 
-  // Specialization for gcc_cp_function_args.
-  template<>
-  class argument_wrapper<const gcc_cp_function_args *>
+#endif // GCC_CP_INTERFACE_H
+
+  // Specialization for any kind of pointer.
+  template<typename T>
+  class argument_wrapper<T *>
   {
   public:
-    argument_wrapper () : m_object (NULL) { }
-    ~argument_wrapper ()
-    {
-      // It would be nicer if gcc_type_array could have a destructor.
-      // But, it is in code shared with gdb and cannot.
-      if (m_object != NULL)
-	{
-	  delete[] m_object->elements;
-	}
-      delete m_object;
-    }
+    argument_wrapper () = default;
+    ~argument_wrapper () = default;
 
     argument_wrapper (const argument_wrapper &) = delete;
     argument_wrapper &operator= (const argument_wrapper &) = delete;
 
-    operator const gcc_cp_function_args * () const
+    typedef typename std::remove_const<T>::type type;
+
+    operator const type * () const
     {
-      return m_object;
+      return m_object.get ();
     }
 
     status unmarshall (connection *conn)
     {
-      return ::cc1_plugin::unmarshall (conn, &m_object);
+      type *ptr;
+      if (!::cc1_plugin::unmarshall (conn, &ptr))
+	return FAIL;
+      m_object.reset (ptr);
+      return OK;
     }
 
   private:
 
-    gcc_cp_function_args *m_object;
+    std::unique_ptr<type, deleter<type>> m_object;
   };
-#endif /* GCC_CP_INTERFACE_H */
 
   // There are two kinds of template functions here: "call" and
   // "callback".  "call" is implemented with variadic templates, but
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 09/21] libcc1: add more uses of 'deleter'
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (7 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 08/21] libcc1: add deleter objects Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-29 12:43   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 10/21] libcc1: use unique_ptr more Tom Tromey
                   ` (11 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

This changes libcc1 to use the 'deleter' template in a few more
places.  The template and basic specializations are moved to a new
header, then some unmarshall functions are changed to use this code.
This change avoids the need to repeat cleanup code in the
unmarshallers.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* rpc.hh (deleter): Move template and some specializations to
	deleter.hh.
	(argument_wrapper<const T *>): Use cc1_plugin::unique_ptr.
	* marshall.cc (cc1_plugin::unmarshall): Use
	cc1_plugin::unique_ptr.
	* marshall-cp.hh (deleter): New specializations.
	(unmarshall): Use cc1_plugin::unique_ptr.
	* deleter.hh: New file.
---
 libcc1/ChangeLog      | 11 ++++++
 libcc1/deleter.hh     | 53 +++++++++++++++++++++++++++++
 libcc1/marshall-cp.hh | 79 +++++++++++++++++++++++++------------------
 libcc1/marshall.cc    | 11 +++---
 libcc1/rpc.hh         | 62 ++-------------------------------
 5 files changed, 116 insertions(+), 100 deletions(-)
 create mode 100644 libcc1/deleter.hh

diff --git a/libcc1/deleter.hh b/libcc1/deleter.hh
new file mode 100644
index 000000000000..70553eef8f8c
--- /dev/null
+++ b/libcc1/deleter.hh
@@ -0,0 +1,53 @@
+/* Deleter objects
+   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_DELETER_HH
+#define CC1_PLUGIN_DELETER_HH
+
+#include <memory>
+
+namespace cc1_plugin
+{
+  // Any pointer type requires a deleter object that knows how to
+  // clean up.  These are used in multiple places.
+  template<typename T> struct deleter;
+
+  template<>
+  struct deleter<char>
+  {
+    void operator() (char *s)
+    {
+      delete[] s;
+    }
+  };
+
+  template<>
+  struct deleter<gcc_type_array>
+  {
+    void operator() (gcc_type_array *p)
+    {
+      delete[] p->elements;
+      delete p;
+    }
+  };
+
+  template<typename T> using unique_ptr = std::unique_ptr<T, deleter<T>>;
+}
+
+#endif // CC1_PLUGIN_DELETER_HH
diff --git a/libcc1/marshall-cp.hh b/libcc1/marshall-cp.hh
index 3d6ae4126aee..ec616e09d952 100644
--- a/libcc1/marshall-cp.hh
+++ b/libcc1/marshall-cp.hh
@@ -22,9 +22,42 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "marshall.hh"
 #include "gcc-cp-interface.h"
+#include "deleter.hh"
 
 namespace cc1_plugin
 {
+  template<>
+  struct deleter<gcc_vbase_array>
+  {
+    void operator() (gcc_vbase_array *p)
+    {
+      delete[] p->flags;
+      delete[] p->elements;
+      delete p;
+    }
+  };
+
+  template<>
+  struct deleter<gcc_cp_template_args>
+  {
+    void operator() (gcc_cp_template_args *p)
+    {
+      delete[] p->elements;
+      delete[] p->kinds;
+      delete p;
+    }
+  };
+
+  template<>
+  struct deleter<gcc_cp_function_args>
+  {
+    void operator() (gcc_cp_function_args *p)
+    {
+      delete[] p->elements;
+      delete p;
+    }
+  };
+
   // Send a gcc_vbase_array marker followed by the array.
   status
   marshall (connection *conn, const gcc_vbase_array *a)
@@ -67,7 +100,7 @@ namespace cc1_plugin
 	return OK;
       }
 
-    struct gcc_vbase_array *gva = new gcc_vbase_array;
+    cc1_plugin::unique_ptr<gcc_vbase_array> gva (new gcc_vbase_array {});
 
     gva->n_elements = len;
     gva->elements = new gcc_type[len];
@@ -75,25 +108,16 @@ namespace cc1_plugin
     if (!unmarshall_array_elmts (conn,
 				 len * sizeof (gva->elements[0]),
 				 gva->elements))
-      {
-	delete[] gva->elements;
-	delete gva;
-	return FAIL;
-      }
+      return FAIL;
 
     gva->flags = new enum gcc_cp_symbol_kind[len];
 
     if (!unmarshall_array_elmts (conn,
 				 len * sizeof (gva->flags[0]),
 				 gva->flags))
-      {
-	delete[] gva->flags;
-	delete[] gva->elements;
-	delete gva;
-	return FAIL;
-      }
+      return FAIL;
 
-    *result = gva;
+    *result = gva.release ();
     return OK;
   }
 
@@ -139,7 +163,8 @@ namespace cc1_plugin
 	return OK;
       }
 
-    struct gcc_cp_template_args *gva = new gcc_cp_template_args;
+    cc1_plugin::unique_ptr<gcc_cp_template_args> gva
+      (new gcc_cp_template_args {});
 
     gva->n_elements = len;
     gva->kinds = new char[len];
@@ -147,25 +172,16 @@ namespace cc1_plugin
     if (!unmarshall_array_elmts (conn,
 				 len * sizeof (gva->kinds[0]),
 				 gva->kinds))
-      {
-	delete[] gva->kinds;
-	delete gva;
-	return FAIL;
-      }
+      return FAIL;
 
     gva->elements = new gcc_cp_template_arg[len];
 
     if (!unmarshall_array_elmts (conn,
 				 len * sizeof (gva->elements[0]),
 				 gva->elements))
-      {
-	delete[] gva->elements;
-	delete[] gva->kinds;
-	delete gva;
-	return FAIL;
-      }
+      return FAIL;
 
-    *result = gva;
+    *result = gva.release ();
     return OK;
   }
 
@@ -208,7 +224,8 @@ namespace cc1_plugin
 	return OK;
       }
 
-    struct gcc_cp_function_args *gva = new gcc_cp_function_args;
+    cc1_plugin::unique_ptr<gcc_cp_function_args> gva
+      (new gcc_cp_function_args {});
 
     gva->n_elements = len;
     gva->elements = new gcc_expr[len];
@@ -216,13 +233,9 @@ namespace cc1_plugin
     if (!unmarshall_array_elmts (conn,
 				 len * sizeof (gva->elements[0]),
 				 gva->elements))
-      {
-	delete[] gva->elements;
-	delete gva;
-	return FAIL;
-      }
+      return FAIL;
 
-    *result = gva;
+    *result = gva.release ();
 
     return OK;
   }
diff --git a/libcc1/marshall.cc b/libcc1/marshall.cc
index aac077e2d6cd..4a7a21f5cd1b 100644
--- a/libcc1/marshall.cc
+++ b/libcc1/marshall.cc
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 #include <string.h>
 #include "marshall.hh"
 #include "connection.hh"
+#include "rpc.hh"
 
 cc1_plugin::status
 cc1_plugin::unmarshall_check (connection *conn, unsigned long long check)
@@ -175,7 +176,7 @@ cc1_plugin::unmarshall (connection *conn, gcc_type_array **result)
       return OK;
     }
 
-  gcc_type_array *gta = new gcc_type_array;
+  cc1_plugin::unique_ptr<gcc_type_array> gta (new gcc_type_array {});
 
   gta->n_elements = len;
   gta->elements = new gcc_type[len];
@@ -183,13 +184,9 @@ cc1_plugin::unmarshall (connection *conn, gcc_type_array **result)
   if (!unmarshall_array_elmts (conn,
 			       len * sizeof (gta->elements[0]),
 			       gta->elements))
-    {
-      delete[] gta->elements;
-      delete *result;
-      return FAIL;
-    }
+    return FAIL;
 
-  *result = gta;
+  *result = gta.release ();
 
   return OK;
 }
diff --git a/libcc1/rpc.hh b/libcc1/rpc.hh
index 4e00d61ee98d..09cd7bdda616 100644
--- a/libcc1/rpc.hh
+++ b/libcc1/rpc.hh
@@ -22,7 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "status.hh"
 #include "connection.hh"
-#include <memory>
+#include "deleter.hh"
 
 namespace cc1_plugin
 {
@@ -55,64 +55,6 @@ namespace cc1_plugin
     T m_object;
   };
 
-  // Any pointer type requires a deleter object that knows how to
-  // clean up.  These are used in multiple places.
-  template<typename T> struct deleter;
-
-  template<>
-  struct deleter<char>
-  {
-    void operator() (char *s)
-    {
-      delete[] s;
-    }
-  };
-
-  template<>
-  struct deleter<gcc_type_array>
-  {
-    void operator() (gcc_type_array *p)
-    {
-      delete[] p->elements;
-      delete p;
-    }
-  };
-
-#ifdef GCC_CP_INTERFACE_H
-  template<>
-  struct deleter<gcc_vbase_array>
-  {
-    void operator() (gcc_vbase_array *p)
-    {
-      delete[] p->flags;
-      delete[] p->elements;
-      delete p;
-    }
-  };
-
-  template<>
-  struct deleter<gcc_cp_template_args>
-  {
-    void operator() (gcc_cp_template_args *p)
-    {
-      delete[] p->elements;
-      delete[] p->kinds;
-      delete p;
-    }
-  };
-
-  template<>
-  struct deleter<gcc_cp_function_args>
-  {
-    void operator() (gcc_cp_function_args *p)
-    {
-      delete[] p->elements;
-      delete p;
-    }
-  };
-
-#endif // GCC_CP_INTERFACE_H
-
   // Specialization for any kind of pointer.
   template<typename T>
   class argument_wrapper<T *>
@@ -142,7 +84,7 @@ namespace cc1_plugin
 
   private:
 
-    std::unique_ptr<type, deleter<type>> m_object;
+    unique_ptr<type> m_object;
   };
 
   // There are two kinds of template functions here: "call" and
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 10/21] libcc1: use unique_ptr more
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (8 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 09/21] libcc1: add more uses of 'deleter' Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-29 12:44   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 11/21] libcc1: unify compiler handling Tom Tromey
                   ` (10 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

This changes libcc1 to use unique_ptr in a few more places, removing
some manual memory management.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* libcp1.cc (struct libcp1) <connection, compilerp>: Use
	unique_ptr.
	(~libcp1): Remove.
	(libcp1_compile, libcp1_set_triplet_regexp)
	(libcp1_set_driver_filename): Update.
	* libcc1.cc (struct libcc1) <connection, compilerp>: Use
	unique_ptr.
	(~libcc1): Remove.
	(libcc1_set_triplet_regexp, libcc1_set_driver_filename)
	(libcc1_compile): Update.
---
 libcc1/ChangeLog | 13 +++++++++++++
 libcc1/libcc1.cc | 32 +++++++++++++-------------------
 libcc1/libcp1.cc | 32 +++++++++++++-------------------
 3 files changed, 39 insertions(+), 38 deletions(-)

diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index 3432f4e8b212..e00355955b6e 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -49,7 +49,6 @@ class libcc1_connection;
 struct libcc1 : public gcc_c_context
 {
   libcc1 (const gcc_base_vtable *, const gcc_c_fe_vtable *);
-  ~libcc1 ();
 
   // A convenience function to print something.
   void print (const char *str)
@@ -57,7 +56,7 @@ struct libcc1 : public gcc_c_context
     this->print_function (this->print_datum, str);
   }
 
-  libcc1_connection *connection;
+  std::unique_ptr<libcc1_connection> connection;
 
   gcc_c_oracle_function *binding_oracle;
   gcc_c_symbol_address_function *address_oracle;
@@ -85,7 +84,9 @@ struct libcc1 : public gcc_c_context
     virtual ~compiler ()
     {
     }
-  } *compilerp;
+  };
+
+  std::unique_ptr<compiler> compilerp;
 
   /* Compiler to set by set_triplet_regexp.  */
   class compiler_triplet_regexp : public compiler
@@ -142,8 +143,7 @@ public:
 
 libcc1::libcc1 (const gcc_base_vtable *v,
 		const gcc_c_fe_vtable *cv)
-  : connection (NULL),
-    binding_oracle (NULL),
+  : binding_oracle (NULL),
     address_oracle (NULL),
     oracle_datum (NULL),
     print_function (NULL),
@@ -157,12 +157,6 @@ libcc1::libcc1 (const gcc_base_vtable *v,
   c_ops = cv;
 }
 
-libcc1::~libcc1 ()
-{
-  delete connection;
-  delete compilerp;
-}
-
 \f
 
 // Enclose these functions in an anonymous namespace because they
@@ -220,7 +214,7 @@ R rpc (struct gcc_c_context *s, Arg... rest)
   libcc1 *self = (libcc1 *) s;
   R result;
 
-  if (!cc1_plugin::call (self->connection, NAME, &result, rest...))
+  if (!cc1_plugin::call (self->connection.get (), NAME, &result, rest...))
     return 0;
   return result;
 }
@@ -380,8 +374,8 @@ libcc1_set_triplet_regexp (struct gcc_base_context *s,
 {
   libcc1 *self = (libcc1 *) s;
 
-  delete self->compilerp;
-  self->compilerp = new libcc1::compiler_triplet_regexp (self, triplet_regexp);
+  self->compilerp.reset (new libcc1::compiler_triplet_regexp (self,
+							      triplet_regexp));
   return NULL;
 }
 
@@ -391,9 +385,8 @@ libcc1_set_driver_filename (struct gcc_base_context *s,
 {
   libcc1 *self = (libcc1 *) s;
 
-  delete self->compilerp;
-  self->compilerp = new libcc1::compiler_driver_filename (self,
-							  driver_filename);
+  self->compilerp.reset (new libcc1::compiler_driver_filename (self,
+							       driver_filename));
   return NULL;
 }
 
@@ -464,7 +457,8 @@ fork_exec (libcc1 *self, char **argv, int spair_fds[2], int stderr_fds[2])
 
       cc1_plugin::status result = cc1_plugin::FAIL;
       if (self->connection->send ('H')
-	  && ::cc1_plugin::marshall (self->connection, GCC_C_FE_VERSION_1))
+	  && ::cc1_plugin::marshall (self->connection.get (),
+				     GCC_C_FE_VERSION_1))
 	result = self->connection->wait_for_query ();
 
       close (spair_fds[0]);
@@ -527,7 +521,7 @@ libcc1_compile (struct gcc_base_context *s,
   if (self->verbose)
     self->args.push_back ("-v");
 
-  self->connection = new libcc1_connection (fds[0], stderr_fds[0], self);
+  self->connection.reset (new libcc1_connection (fds[0], stderr_fds[0], self));
 
   cc1_plugin::callback_ftype *fun
     = cc1_plugin::callback<int,
diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc
index 4273f8d83826..4bd8c6b00b65 100644
--- a/libcc1/libcp1.cc
+++ b/libcc1/libcp1.cc
@@ -48,7 +48,6 @@ class libcp1_connection;
 struct libcp1 : public gcc_cp_context
 {
   libcp1 (const gcc_base_vtable *, const gcc_cp_fe_vtable *);
-  ~libcp1 ();
 
   // A convenience function to print something.
   void print (const char *str)
@@ -56,7 +55,7 @@ struct libcp1 : public gcc_cp_context
     this->print_function (this->print_datum, str);
   }
 
-  libcp1_connection *connection;
+  std::unique_ptr<libcp1_connection> connection;
 
   gcc_cp_oracle_function *binding_oracle;
   gcc_cp_symbol_address_function *address_oracle;
@@ -86,7 +85,9 @@ struct libcp1 : public gcc_cp_context
     virtual ~compiler ()
     {
     }
-  } *compilerp;
+  };
+
+  std::unique_ptr<compiler> compilerp;
 
   /* Compiler to set by set_triplet_regexp.  */
   class compiler_triplet_regexp : public compiler
@@ -143,8 +144,7 @@ public:
 
 libcp1::libcp1 (const gcc_base_vtable *v,
 		  const gcc_cp_fe_vtable *cv)
-  : connection (NULL),
-    binding_oracle (NULL),
+  : binding_oracle (NULL),
     address_oracle (NULL),
     oracle_datum (NULL),
     print_function (NULL),
@@ -158,12 +158,6 @@ libcp1::libcp1 (const gcc_base_vtable *v,
   cp_ops = cv;
 }
 
-libcp1::~libcp1 ()
-{
-  delete connection;
-  delete compilerp;
-}
-
 \f
 
 // Enclose these functions in an anonymous namespace because they
@@ -243,7 +237,7 @@ R rpc (struct gcc_cp_context *s, Arg... rest)
   libcp1 *self = (libcp1 *) s;
   R result;
 
-  if (!cc1_plugin::call (self->connection, NAME, &result, rest...))
+  if (!cc1_plugin::call (self->connection.get (), NAME, &result, rest...))
     return 0;
   return result;
 }
@@ -403,8 +397,8 @@ libcp1_set_triplet_regexp (struct gcc_base_context *s,
 {
   libcp1 *self = (libcp1 *) s;
 
-  delete self->compilerp;
-  self->compilerp = new libcp1::compiler_triplet_regexp (self, triplet_regexp);
+  self->compilerp.reset (new libcp1::compiler_triplet_regexp (self,
+							      triplet_regexp));
   return NULL;
 }
 
@@ -414,9 +408,8 @@ libcp1_set_driver_filename (struct gcc_base_context *s,
 {
   libcp1 *self = (libcp1 *) s;
 
-  delete self->compilerp;
-  self->compilerp = new libcp1::compiler_driver_filename (self,
-							  driver_filename);
+  self->compilerp.reset (new libcp1::compiler_driver_filename (self,
+							       driver_filename));
   return NULL;
 }
 
@@ -487,7 +480,8 @@ fork_exec (libcp1 *self, char **argv, int spair_fds[2], int stderr_fds[2])
 
       cc1_plugin::status result = cc1_plugin::FAIL;
       if (self->connection->send ('H')
-	  && ::cc1_plugin::marshall (self->connection, GCC_CP_FE_VERSION_0))
+	  && ::cc1_plugin::marshall (self->connection.get (),
+				     GCC_CP_FE_VERSION_0))
 	result = self->connection->wait_for_query ();
 
       close (spair_fds[0]);
@@ -550,7 +544,7 @@ libcp1_compile (struct gcc_base_context *s,
   if (self->verbose)
     self->args.push_back ("-v");
 
-  self->connection = new libcp1_connection (fds[0], stderr_fds[0], self);
+  self->connection.reset (new libcp1_connection (fds[0], stderr_fds[0], self));
 
   cc1_plugin::callback_ftype *fun
     = cc1_plugin::callback<int,
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 11/21] libcc1: unify compiler handling
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (9 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 10/21] libcc1: use unique_ptr more Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-29 12:47   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 12/21] libcc1: use foreach Tom Tromey
                   ` (9 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

Both libcc1 plugins have nearly identical copies of code to find the
underlying compiler.  This seemed wasteful to me, so this patch
unifies the copies.

Two minor API changes were needed.

First, the old code used a back-link from the compiler object to the
plugin object to check the 'verbose' setting.  This patch adds a
'verbose' setting directly to the compiler object instead.

Second, the 'find' method implicitly knew which compiler base name
("gcc" or "g++") to use.  This patch makes this a parameter that is
passed in by the plugin.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* libcc1.cc (compiler, compiler_triplet_regexp)
	(compiler_driver_filename): Remove.
	(libcp1::libcp1): Update.
	(make_regexp, libcp1::compiler::find)
	(libcp1::compiler_triplet_regexp::find)
	(libcp1::compiler_driver_filename::find): Remove.
	(libcp1_set_verbose, libcp1_set_arguments)
	(libcp1_set_triplet_regexp, libcp1_set_driver_filename): Update.
	* libcc1.cc (compiler, compiler_triplet_regexp)
	(compiler_driver_filename): Remove.
	(libcc1::libcc1): Update.
	(make_regexp, libcc1::compiler::find)
	(libcc1::compiler_triplet_regexp::find)
	(libcc1::compiler_driver_filename::find): Remove.
	(libcc1_set_verbose, libcc1_set_arguments)
	(libcc1_set_triplet_regexp, libcc1_set_driver_filename): Update.
	* compiler.cc: New file.
	* compiler.hh: New file.
	* Makefile.in: Rebuild.
	* Makefile.am (libcc1_la_SOURCES): Add compiler.hh, compiler.cc.
---
 libcc1/ChangeLog   |  23 +++++++
 libcc1/Makefile.am |   2 +-
 libcc1/Makefile.in |   7 +-
 libcc1/compiler.cc | 118 +++++++++++++++++++++++++++++++++
 libcc1/compiler.hh |  83 +++++++++++++++++++++++
 libcc1/libcc1.cc   | 159 ++++-----------------------------------------
 libcc1/libcp1.cc   | 159 ++++-----------------------------------------
 7 files changed, 253 insertions(+), 298 deletions(-)
 create mode 100644 libcc1/compiler.cc
 create mode 100644 libcc1/compiler.hh

diff --git a/libcc1/Makefile.am b/libcc1/Makefile.am
index f148fdd7aa28..3f20513d11b7 100644
--- a/libcc1/Makefile.am
+++ b/libcc1/Makefile.am
@@ -75,7 +75,7 @@ libcp1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
 libcc1_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1.sym
 libcc1_la_SOURCES = findcomp.cc libcc1.cc libcp1.cc \
-		names.cc names.hh $(shared_source) \
+		compiler.cc compiler.hh names.cc names.hh $(shared_source) \
 		$(marshall_c_source) $(marshall_cxx_source)
 libcc1_la_LIBADD = $(libiberty)
 libcc1_la_DEPENDENCIES = $(libiberty_dep)
diff --git a/libcc1/Makefile.in b/libcc1/Makefile.in
index 753d435c9cbe..d76893e3a24e 100644
--- a/libcc1/Makefile.in
+++ b/libcc1/Makefile.in
@@ -144,8 +144,8 @@ am__installdirs = "$(DESTDIR)$(cc1libdir)" "$(DESTDIR)$(plugindir)"
 LTLIBRARIES = $(cc1lib_LTLIBRARIES) $(plugin_LTLIBRARIES)
 am__objects_1 = callbacks.lo connection.lo marshall.lo
 am__objects_2 =
-am_libcc1_la_OBJECTS = findcomp.lo libcc1.lo libcp1.lo names.lo \
-	$(am__objects_1) $(am__objects_2) $(am__objects_2)
+am_libcc1_la_OBJECTS = findcomp.lo libcc1.lo libcp1.lo compiler.lo \
+	names.lo $(am__objects_1) $(am__objects_2) $(am__objects_2)
 libcc1_la_OBJECTS = $(am_libcc1_la_OBJECTS)
 @ENABLE_PLUGIN_TRUE@am_libcc1_la_rpath = -rpath $(cc1libdir)
 am_libcc1plugin_la_OBJECTS = libcc1plugin.lo $(am__objects_1) \
@@ -428,7 +428,7 @@ libcp1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
 libcc1_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1.sym
 libcc1_la_SOURCES = findcomp.cc libcc1.cc libcp1.cc \
-		names.cc names.hh $(shared_source) \
+		compiler.cc compiler.hh names.cc names.hh $(shared_source) \
 		$(marshall_c_source) $(marshall_cxx_source)
 
 libcc1_la_LIBADD = $(libiberty)
@@ -577,6 +577,7 @@ distclean-compile:
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compiler.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findcomp.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcc1.Plo@am__quote@
diff --git a/libcc1/compiler.cc b/libcc1/compiler.cc
new file mode 100644
index 000000000000..fede84968625
--- /dev/null
+++ b/libcc1/compiler.cc
@@ -0,0 +1,118 @@
+/* Compiler handling for plugin
+   Copyright (C) 2014-2021 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/>.  */
+
+#include <cc1plugin-config.h>
+#include <string>
+#include <sstream>
+#include "libiberty.h"
+#include "compiler.hh"
+#include "xregex.h"
+#include "findcomp.hh"
+#include "intl.h"
+
+// Construct an appropriate regexp to match the compiler name.
+static std::string
+make_regexp (const char *triplet_regexp, const char *compiler)
+{
+  std::stringstream buf;
+
+  buf << "^" << triplet_regexp << "-";
+
+  // Quote the compiler name in case it has something funny in it.
+  for (const char *p = compiler; *p; ++p)
+    {
+      switch (*p)
+	{
+	case '.':
+	case '^':
+	case '$':
+	case '*':
+	case '+':
+	case '?':
+	case '(':
+	case ')':
+	case '[':
+	case '{':
+	case '\\':
+	case '|':
+	  buf << '\\';
+	  break;
+	}
+      buf << *p;
+    }
+  buf << "$";
+
+  return buf.str ();
+}
+
+char *
+cc1_plugin::compiler::find (const char *, std::string &) const
+{
+  return xstrdup (_("Compiler has not been specified"));
+}
+
+char *
+cc1_plugin::compiler_triplet_regexp::find (const char *base,
+					   std::string &compiler) const
+{
+  std::string rx = make_regexp (triplet_regexp_.c_str (), base);
+  if (verbose)
+    fprintf (stderr, _("searching for compiler matching regex %s\n"),
+	     rx.c_str());
+  regex_t triplet;
+  int code = regcomp (&triplet, rx.c_str (), REG_EXTENDED | REG_NOSUB);
+  if (code != 0)
+    {
+      size_t len = regerror (code, &triplet, NULL, 0);
+      char err[len];
+
+      regerror (code, &triplet, err, len);
+
+      return concat ("Could not compile regexp \"",
+		     rx.c_str (),
+		     "\": ",
+		     err,
+		     (char *) NULL);
+    }
+
+  if (!find_compiler (triplet, &compiler))
+    {
+      regfree (&triplet);
+      return concat ("Could not find a compiler matching \"",
+		     rx.c_str (),
+		     "\"",
+		     (char *) NULL);
+    }
+  regfree (&triplet);
+  if (verbose)
+    fprintf (stderr, _("found compiler %s\n"), compiler.c_str());
+  return NULL;
+}
+
+char *
+cc1_plugin::compiler_driver_filename::find (const char *,
+					    std::string &compiler) const
+{
+  // Simulate fnotice by fprintf.
+  if (verbose)
+    fprintf (stderr, _("using explicit compiler filename %s\n"),
+	     driver_filename_.c_str());
+  compiler = driver_filename_;
+  return NULL;
+}
diff --git a/libcc1/compiler.hh b/libcc1/compiler.hh
new file mode 100644
index 000000000000..638f7c09f634
--- /dev/null
+++ b/libcc1/compiler.hh
@@ -0,0 +1,83 @@
+/* Compiler handling for plugin
+   Copyright (C) 2014-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_COMPILER_HH
+#define CC1_PLUGIN_COMPILER_HH
+
+namespace cc1_plugin
+{
+
+  // Base class for compiler.
+  class compiler
+  {
+  public:
+    explicit compiler (bool v)
+      : verbose (v)
+    {
+    }
+
+    virtual ~compiler () = default;
+
+    // Find the compiler.  BASE is the base name of the compiler, see
+    // compiler-name.hh.  This sets COMPILER to the resulting path.
+    // Returns nullptr on success, or a malloc'd error string on
+    // failure.
+    virtual char *find (const char *base, std::string &compiler) const;
+
+    void set_verbose (bool v)
+    {
+      verbose = v;
+    }
+
+  protected:
+    bool verbose;
+  };
+
+  /* Compiler to set by set_triplet_regexp.  */
+  class compiler_triplet_regexp : public compiler
+  {
+  private:
+    std::string triplet_regexp_;
+  public:
+
+    char *find (const char *base, std::string &compiler) const override;
+
+    compiler_triplet_regexp (bool v, std::string triplet_regexp)
+      : compiler (v), triplet_regexp_ (triplet_regexp)
+    {
+    }
+  };
+
+  /* Compiler to set by set_driver_filename.  */
+  class compiler_driver_filename : public compiler
+  {
+  private:
+    std::string driver_filename_;
+  public:
+    char *find (const char *base, std::string &compiler) const override;
+
+    compiler_driver_filename (bool v, std::string driver_filename)
+      : compiler (v), driver_filename_ (driver_filename)
+    {
+    }
+  };
+
+}
+
+#endif // CC1_PLUGIN_COMPILER_HH
diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index e00355955b6e..ea52c26d7832 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -28,18 +28,15 @@ along with GCC; see the file COPYING3.  If not see
 #include <errno.h>
 #include <sys/stat.h>
 #include <stdlib.h>
-#include <sstream>
 #include "marshall.hh"
 #include "rpc.hh"
 #include "connection.hh"
 #include "names.hh"
 #include "callbacks.hh"
 #include "libiberty.h"
-#include "xregex.h"
-#include "findcomp.hh"
 #include "compiler-name.hh"
-#include "intl.h"
 #include "gcc-c-interface.h"
+#include "compiler.hh"
 
 struct libcc1;
 
@@ -71,54 +68,7 @@ struct libcc1 : public gcc_c_context
   /* Non-zero as an equivalent to gcc driver option "-v".  */
   bool verbose;
 
-  /* Compiler to set by set_triplet_regexp or set_driver_filename.  */
-  class compiler
-  {
-  protected:
-    libcc1 *self_;
-  public:
-    compiler (libcc1 *self) : self_ (self)
-    {
-    }
-    virtual char *find (std::string &compiler) const;
-    virtual ~compiler ()
-    {
-    }
-  };
-
-  std::unique_ptr<compiler> compilerp;
-
-  /* Compiler to set by set_triplet_regexp.  */
-  class compiler_triplet_regexp : public compiler
-  {
-  private:
-    std::string triplet_regexp_;
-  public:
-    char *find (std::string &compiler) const override;
-    compiler_triplet_regexp (libcc1 *self, std::string triplet_regexp)
-      : compiler (self), triplet_regexp_ (triplet_regexp)
-    {
-    }
-    virtual ~compiler_triplet_regexp ()
-    {
-    }
-  };
-
-  /* Compiler to set by set_driver_filename.  */
-  class compiler_driver_filename : public compiler
-  {
-  private:
-    std::string driver_filename_;
-  public:
-    char *find (std::string &compiler) const override;
-    compiler_driver_filename (libcc1 *self, std::string driver_filename)
-      : compiler (self), driver_filename_ (driver_filename)
-    {
-    }
-    virtual ~compiler_driver_filename ()
-    {
-    }
-  };
+  std::unique_ptr<cc1_plugin::compiler> compilerp;
 };
 
 // A local subclass of connection that holds a back-pointer to the
@@ -151,7 +101,7 @@ libcc1::libcc1 (const gcc_base_vtable *v,
     args (),
     source_file (),
     verbose (false),
-    compilerp (new libcc1::compiler (this))
+    compilerp (new cc1_plugin::compiler (verbose))
 {
   base.ops = v;
   c_ops = cv;
@@ -252,101 +202,14 @@ static const struct gcc_c_fe_vtable c_vtable =
 
 \f
 
-// Construct an appropriate regexp to match the compiler name.
-static std::string
-make_regexp (const char *triplet_regexp, const char *compiler)
-{
-  std::stringstream buf;
-
-  buf << "^" << triplet_regexp << "-";
-
-  // Quote the compiler name in case it has something funny in it.
-  for (const char *p = compiler; *p; ++p)
-    {
-      switch (*p)
-	{
-	case '.':
-	case '^':
-	case '$':
-	case '*':
-	case '+':
-	case '?':
-	case '(':
-	case ')':
-	case '[':
-	case '{':
-	case '\\':
-	case '|':
-	  buf << '\\';
-	  break;
-	}
-      buf << *p;
-    }
-  buf << "$";
-
-  return buf.str ();
-}
-
 static void
 libcc1_set_verbose (struct gcc_base_context *s, int /* bool */ verbose)
 {
   libcc1 *self = (libcc1 *) s;
 
   self->verbose = verbose != 0;
-}
-
-char *
-libcc1::compiler::find (std::string &compiler ATTRIBUTE_UNUSED) const
-{
-  return xstrdup (_("Compiler has not been specified"));
-}
-
-char *
-libcc1::compiler_triplet_regexp::find (std::string &compiler) const
-{
-  std::string rx = make_regexp (triplet_regexp_.c_str (), C_COMPILER_NAME);
-  if (self_->verbose)
-    fprintf (stderr, _("searching for compiler matching regex %s\n"),
-	     rx.c_str());
-  regex_t triplet;
-  int code = regcomp (&triplet, rx.c_str (), REG_EXTENDED | REG_NOSUB);
-  if (code != 0)
-    {
-      size_t len = regerror (code, &triplet, NULL, 0);
-      char err[len];
-
-      regerror (code, &triplet, err, len);
-
-      return concat ("Could not compile regexp \"",
-		     rx.c_str (),
-		     "\": ",
-		     err,
-		     (char *) NULL);
-    }
-
-  if (!find_compiler (triplet, &compiler))
-    {
-      regfree (&triplet);
-      return concat ("Could not find a compiler matching \"",
-		     rx.c_str (),
-		     "\"",
-		     (char *) NULL);
-    }
-  regfree (&triplet);
-  if (self_->verbose)
-    fprintf (stderr, _("found compiler %s\n"), compiler.c_str());
-  return NULL;
-}
-
-char *
-libcc1::compiler_driver_filename::find (std::string &compiler) const
-{
-  // Simulate fnotice by fprintf.
-  if (self_->verbose)
-    fprintf (stderr, _("using explicit compiler filename %s\n"),
-	     driver_filename_.c_str());
-  compiler = driver_filename_;
-  return NULL;
+  if (self->compilerp != nullptr)
+    self->compilerp->set_verbose (self->verbose);
 }
 
 static char *
@@ -356,7 +219,7 @@ libcc1_set_arguments (struct gcc_base_context *s,
   libcc1 *self = (libcc1 *) s;
 
   std::string compiler;
-  char *errmsg = self->compilerp->find (compiler);
+  char *errmsg = self->compilerp->find (C_COMPILER_NAME, compiler);
   if (errmsg != NULL)
     return errmsg;
 
@@ -374,8 +237,9 @@ libcc1_set_triplet_regexp (struct gcc_base_context *s,
 {
   libcc1 *self = (libcc1 *) s;
 
-  self->compilerp.reset (new libcc1::compiler_triplet_regexp (self,
-							      triplet_regexp));
+  self->compilerp.reset
+    (new cc1_plugin::compiler_triplet_regexp (self->verbose,
+					      triplet_regexp));
   return NULL;
 }
 
@@ -385,8 +249,9 @@ libcc1_set_driver_filename (struct gcc_base_context *s,
 {
   libcc1 *self = (libcc1 *) s;
 
-  self->compilerp.reset (new libcc1::compiler_driver_filename (self,
-							       driver_filename));
+  self->compilerp.reset
+    (new cc1_plugin::compiler_driver_filename (self->verbose,
+					       driver_filename));
   return NULL;
 }
 
diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc
index 4bd8c6b00b65..c57ac8c66a6b 100644
--- a/libcc1/libcp1.cc
+++ b/libcc1/libcp1.cc
@@ -28,17 +28,14 @@ along with GCC; see the file COPYING3.  If not see
 #include <errno.h>
 #include <sys/stat.h>
 #include <stdlib.h>
-#include <sstream>
 #include "marshall-cp.hh"
 #include "rpc.hh"
 #include "connection.hh"
 #include "names.hh"
 #include "callbacks.hh"
 #include "libiberty.h"
-#include "xregex.h"
-#include "findcomp.hh"
 #include "compiler-name.hh"
-#include "intl.h"
+#include "compiler.hh"
 
 struct libcp1;
 
@@ -72,54 +69,7 @@ struct libcp1 : public gcc_cp_context
   /* Non-zero as an equivalent to gcc driver option "-v".  */
   bool verbose;
 
-  /* Compiler to set by set_triplet_regexp or set_driver_filename.  */
-  class compiler
-  {
-  protected:
-    libcp1 *self_;
-  public:
-    compiler (libcp1 *self) : self_ (self)
-    {
-    }
-    virtual char *find (std::string &compiler) const;
-    virtual ~compiler ()
-    {
-    }
-  };
-
-  std::unique_ptr<compiler> compilerp;
-
-  /* Compiler to set by set_triplet_regexp.  */
-  class compiler_triplet_regexp : public compiler
-  {
-  private:
-    std::string triplet_regexp_;
-  public:
-    char *find (std::string &compiler) const override;
-    compiler_triplet_regexp (libcp1 *self, std::string triplet_regexp)
-      : compiler (self), triplet_regexp_ (triplet_regexp)
-    {
-    }
-    virtual ~compiler_triplet_regexp ()
-    {
-    }
-  };
-
-  /* Compiler to set by set_driver_filename.  */
-  class compiler_driver_filename : public compiler
-  {
-  private:
-    std::string driver_filename_;
-  public:
-    char *find (std::string &compiler) const override;
-    compiler_driver_filename (libcp1 *self, std::string driver_filename)
-      : compiler (self), driver_filename_ (driver_filename)
-    {
-    }
-    virtual ~compiler_driver_filename ()
-    {
-    }
-  };
+  std::unique_ptr<cc1_plugin::compiler> compilerp;
 };
 
 // A local subclass of connection that holds a back-pointer to the
@@ -152,7 +102,7 @@ libcp1::libcp1 (const gcc_base_vtable *v,
     args (),
     source_file (),
     verbose (false),
-    compilerp (new libcp1::compiler (this))
+    compilerp (new cc1_plugin::compiler (verbose))
 {
   base.ops = v;
   cp_ops = cv;
@@ -275,101 +225,14 @@ static const struct gcc_cp_fe_vtable cp_vtable =
 
 \f
 
-// Construct an appropriate regexp to match the compiler name.
-static std::string
-make_regexp (const char *triplet_regexp, const char *compiler)
-{
-  std::stringstream buf;
-
-  buf << "^" << triplet_regexp << "-";
-
-  // Quote the compiler name in case it has something funny in it.
-  for (const char *p = compiler; *p; ++p)
-    {
-      switch (*p)
-	{
-	case '.':
-	case '^':
-	case '$':
-	case '*':
-	case '+':
-	case '?':
-	case '(':
-	case ')':
-	case '[':
-	case '{':
-	case '\\':
-	case '|':
-	  buf << '\\';
-	  break;
-	}
-      buf << *p;
-    }
-  buf << "$";
-
-  return buf.str ();
-}
-
 static void
 libcp1_set_verbose (struct gcc_base_context *s, int /* bool */ verbose)
 {
   libcp1 *self = (libcp1 *) s;
 
   self->verbose = verbose != 0;
-}
-
-char *
-libcp1::compiler::find (std::string &compiler ATTRIBUTE_UNUSED) const
-{
-  return xstrdup (_("Compiler has not been specified"));
-}
-
-char *
-libcp1::compiler_triplet_regexp::find (std::string &compiler) const
-{
-  std::string rx = make_regexp (triplet_regexp_.c_str (), CP_COMPILER_NAME);
-  if (self_->verbose)
-    fprintf (stderr, _("searching for compiler matching regex %s\n"),
-	     rx.c_str());
-  regex_t triplet;
-  int code = regcomp (&triplet, rx.c_str (), REG_EXTENDED | REG_NOSUB);
-  if (code != 0)
-    {
-      size_t len = regerror (code, &triplet, NULL, 0);
-      char err[len];
-
-      regerror (code, &triplet, err, len);
-
-      return concat ("Could not compile regexp \"",
-		     rx.c_str (),
-		     "\": ",
-		     err,
-		     (char *) NULL);
-    }
-
-  if (!find_compiler (triplet, &compiler))
-    {
-      regfree (&triplet);
-      return concat ("Could not find a compiler matching \"",
-		     rx.c_str (),
-		     "\"",
-		     (char *) NULL);
-    }
-  regfree (&triplet);
-  if (self_->verbose)
-    fprintf (stderr, _("found compiler %s\n"), compiler.c_str());
-  return NULL;
-}
-
-char *
-libcp1::compiler_driver_filename::find (std::string &compiler) const
-{
-  // Simulate fnotice by fprintf.
-  if (self_->verbose)
-    fprintf (stderr, _("using explicit compiler filename %s\n"),
-	     driver_filename_.c_str());
-  compiler = driver_filename_;
-  return NULL;
+  if (self->compilerp != nullptr)
+    self->compilerp->set_verbose (self->verbose);
 }
 
 static char *
@@ -379,7 +242,7 @@ libcp1_set_arguments (struct gcc_base_context *s,
   libcp1 *self = (libcp1 *) s;
 
   std::string compiler;
-  char *errmsg = self->compilerp->find (compiler);
+  char *errmsg = self->compilerp->find (CP_COMPILER_NAME, compiler);
   if (errmsg != NULL)
     return errmsg;
 
@@ -397,8 +260,9 @@ libcp1_set_triplet_regexp (struct gcc_base_context *s,
 {
   libcp1 *self = (libcp1 *) s;
 
-  self->compilerp.reset (new libcp1::compiler_triplet_regexp (self,
-							      triplet_regexp));
+  self->compilerp.reset
+    (new cc1_plugin::compiler_triplet_regexp (self->verbose,
+					      triplet_regexp));
   return NULL;
 }
 
@@ -408,8 +272,9 @@ libcp1_set_driver_filename (struct gcc_base_context *s,
 {
   libcp1 *self = (libcp1 *) s;
 
-  self->compilerp.reset (new libcp1::compiler_driver_filename (self,
-							       driver_filename));
+  self->compilerp.reset
+    (new cc1_plugin::compiler_driver_filename (self->verbose,
+					       driver_filename));
   return NULL;
 }
 
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 12/21] libcc1: use foreach
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (10 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 11/21] libcc1: unify compiler handling Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-28 16:04   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 13/21] libcc1: use static_assert Tom Tromey
                   ` (8 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

This changes libcc1 to ues foreach in a couple of spots.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* libcp1plugin.cc (plugin_context::mark): Use foreach.
	* libcc1plugin.cc (plugin_context::mark): Use foreach.
---
 libcc1/ChangeLog       |  5 +++++
 libcc1/libcc1plugin.cc | 13 +++++--------
 libcc1/libcp1plugin.cc | 13 +++++--------
 3 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc
index 65e748258f40..2a75faba7652 100644
--- a/libcc1/libcc1plugin.cc
+++ b/libcc1/libcc1plugin.cc
@@ -235,17 +235,14 @@ plugin_context::plugin_context (int fd)
 void
 plugin_context::mark ()
 {
-  for (hash_table<decl_addr_hasher>::iterator it = address_map.begin ();
-       it != address_map.end ();
-       ++it)
+  for (const auto &item : address_map)
     {
-      ggc_mark ((*it)->decl);
-      ggc_mark ((*it)->address);
+      ggc_mark (item->decl);
+      ggc_mark (item->address);
     }
 
-  for (hash_table< nofree_ptr_hash<tree_node> >::iterator
-	 it = preserved.begin (); it != preserved.end (); ++it)
-    ggc_mark (&*it);
+  for (const auto &item : preserved)
+    ggc_mark (&item);
 }
 
 static void
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index 1fc8e269f075..3cbad5c6f021 100644
--- a/libcc1/libcp1plugin.cc
+++ b/libcc1/libcp1plugin.cc
@@ -225,17 +225,14 @@ plugin_context::plugin_context (int fd)
 void
 plugin_context::mark ()
 {
-  for (hash_table<decl_addr_hasher>::iterator it = address_map.begin ();
-       it != address_map.end ();
-       ++it)
+  for (const auto &item : address_map)
     {
-      ggc_mark ((*it)->decl);
-      ggc_mark ((*it)->address);
+      ggc_mark (item->decl);
+      ggc_mark (item->address);
     }
 
-  for (hash_table< nofree_ptr_hash<tree_node> >::iterator
-	 it = preserved.begin (); it != preserved.end (); ++it)
-    ggc_mark (&*it);
+  for (const auto &item : preserved)
+    ggc_mark (&item);
 }
 
 static void
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 13/21] libcc1: use static_assert
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (11 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 12/21] libcc1: use foreach Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-28 16:06   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 14/21] libcc1: share basic context code Tom Tromey
                   ` (7 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

This changes one spot in libcc1 to use static_assert rather than the
old-style array declaration.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* libcp1plugin.cc: Use static assert.
---
 libcc1/ChangeLog       | 4 ++++
 libcc1/libcp1plugin.cc | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index 3cbad5c6f021..ba6c5ef2efce 100644
--- a/libcc1/libcp1plugin.cc
+++ b/libcc1/libcp1plugin.cc
@@ -82,8 +82,8 @@ int plugin_is_GPL_compatible;
 
 \f
 
-static int ATTRIBUTE_UNUSED
-check_symbol_mask[GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END ? 1 : -1];
+static_assert (GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END,
+	       "GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END");
 
 // This is put into the lang hooks when the plugin starts.
 
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 14/21] libcc1: share basic context code
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (12 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 13/21] libcc1: use static_assert Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-29 12:50   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 15/21] libcc1: share GDB plugin code Tom Tromey
                   ` (6 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

Both plugins in libcc1 share a fair amount of boilerplate.  They both
share error-emission code, context management code, and tree GC code.
This patch unifies these two bodies of code, avoiding needless
duplication.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* libcc1plugin.cc: Move code to context.cc.
	* libcp1plugin.cc: Move code to context.cc.
	* context.hh: New file.
	* context.cc: New file.
	* Makefile.in: Rebuild.
	* Makefile.am (AM_CPPFLAGS): Add more gcc flags.
	(CPPFLAGS_FOR_C, CPPFLAGS_FOR_CXX): Update.
	(libcc1plugin_la_SOURCES): Add context.hh, context.cc.
	(libcp1plugin_la_SOURCES): Likewise.
---
 libcc1/ChangeLog       |  12 +++
 libcc1/Makefile.am     |  15 +--
 libcc1/Makefile.in     |  27 +++---
 libcc1/context.cc      | 171 ++++++++++++++++++++++++++++++++++
 libcc1/context.hh      | 121 ++++++++++++++++++++++++
 libcc1/libcc1plugin.cc | 204 +----------------------------------------
 libcc1/libcp1plugin.cc | 203 +---------------------------------------
 7 files changed, 333 insertions(+), 420 deletions(-)
 create mode 100644 libcc1/context.cc
 create mode 100644 libcc1/context.hh

diff --git a/libcc1/Makefile.am b/libcc1/Makefile.am
index 3f20513d11b7..9ec021030e2d 100644
--- a/libcc1/Makefile.am
+++ b/libcc1/Makefile.am
@@ -19,11 +19,10 @@
 ACLOCAL_AMFLAGS = -I .. -I ../config
 gcc_build_dir = ../gcc
 AM_CPPFLAGS = -I $(srcdir)/../include -I $(srcdir)/../libgcc \
-	-I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC)
-CPPFLAGS_FOR_C_FAMILY = -I $(srcdir)/../gcc/c-family \
-	-I $(srcdir)/../libcpp/include
-CPPFLAGS_FOR_C = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/c
-CPPFLAGS_FOR_CXX = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/cp
+	-I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC) \
+	-I $(srcdir)/../gcc/c-family -I $(srcdir)/../libcpp/include
+CPPFLAGS_FOR_C = -I $(srcdir)/../gcc/c
+CPPFLAGS_FOR_CXX = -I $(srcdir)/../gcc/cp
 AM_CXXFLAGS = $(WARN_FLAGS) $(WERROR) $(visibility) $(CET_HOST_FLAGS)
 if DARWIN_DYNAMIC_LOOKUP
 AM_CXXFLAGS += -Wl,-undefined,dynamic_lookup
@@ -55,7 +54,8 @@ marshall_c_source = marshall-c.hh
 marshall_cxx_source = marshall-cp.hh
 
 libcc1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1plugin.sym
-libcc1plugin_la_SOURCES = libcc1plugin.cc $(shared_source) $(marshall_c_source)
+libcc1plugin_la_SOURCES = libcc1plugin.cc context.cc context.hh \
+	$(shared_source) $(marshall_c_source)
 libcc1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_C)
 libcc1plugin_la_LIBADD = $(libiberty)
 libcc1plugin_la_DEPENDENCIES = $(libiberty_dep)
@@ -64,7 +64,8 @@ libcc1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
 	$(CXXFLAGS) $(libcc1plugin_la_LDFLAGS) $(LTLDFLAGS) -o $@
 
 libcp1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcp1plugin.sym
-libcp1plugin_la_SOURCES = libcp1plugin.cc $(shared_source) $(marshall_cxx_source)
+libcp1plugin_la_SOURCES = libcp1plugin.cc context.cc context.hh \
+	$(shared_source) $(marshall_cxx_source)
 libcp1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_CXX)
 libcp1plugin_la_LIBADD = $(libiberty)
 libcp1plugin_la_DEPENDENCIES = $(libiberty_dep)
diff --git a/libcc1/Makefile.in b/libcc1/Makefile.in
index d76893e3a24e..395f01a98215 100644
--- a/libcc1/Makefile.in
+++ b/libcc1/Makefile.in
@@ -148,12 +148,12 @@ am_libcc1_la_OBJECTS = findcomp.lo libcc1.lo libcp1.lo compiler.lo \
 	names.lo $(am__objects_1) $(am__objects_2) $(am__objects_2)
 libcc1_la_OBJECTS = $(am_libcc1_la_OBJECTS)
 @ENABLE_PLUGIN_TRUE@am_libcc1_la_rpath = -rpath $(cc1libdir)
-am_libcc1plugin_la_OBJECTS = libcc1plugin.lo $(am__objects_1) \
-	$(am__objects_2)
+am_libcc1plugin_la_OBJECTS = libcc1plugin.lo context.lo \
+	$(am__objects_1) $(am__objects_2)
 libcc1plugin_la_OBJECTS = $(am_libcc1plugin_la_OBJECTS)
 @ENABLE_PLUGIN_TRUE@am_libcc1plugin_la_rpath = -rpath $(plugindir)
-am_libcp1plugin_la_OBJECTS = libcp1plugin.lo $(am__objects_1) \
-	$(am__objects_2)
+am_libcp1plugin_la_OBJECTS = libcp1plugin.lo context.lo \
+	$(am__objects_1) $(am__objects_2)
 libcp1plugin_la_OBJECTS = $(am_libcp1plugin_la_OBJECTS)
 @ENABLE_PLUGIN_TRUE@am_libcp1plugin_la_rpath = -rpath $(plugindir)
 AM_V_P = $(am__v_P_@AM_V@)
@@ -379,13 +379,11 @@ visibility = @visibility@
 ACLOCAL_AMFLAGS = -I .. -I ../config
 gcc_build_dir = ../gcc
 AM_CPPFLAGS = -I $(srcdir)/../include -I $(srcdir)/../libgcc \
-	-I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC)
+	-I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC) \
+	-I $(srcdir)/../gcc/c-family -I $(srcdir)/../libcpp/include
 
-CPPFLAGS_FOR_C_FAMILY = -I $(srcdir)/../gcc/c-family \
-	-I $(srcdir)/../libcpp/include
-
-CPPFLAGS_FOR_C = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/c
-CPPFLAGS_FOR_CXX = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/cp
+CPPFLAGS_FOR_C = -I $(srcdir)/../gcc/c
+CPPFLAGS_FOR_CXX = -I $(srcdir)/../gcc/cp
 AM_CXXFLAGS = $(WARN_FLAGS) $(WERROR) $(visibility) $(CET_HOST_FLAGS) \
 	$(am__append_1)
 # Can be simplified when libiberty becomes a normal convenience library.
@@ -408,7 +406,9 @@ shared_source = callbacks.cc callbacks.hh connection.cc connection.hh \
 marshall_c_source = marshall-c.hh
 marshall_cxx_source = marshall-cp.hh
 libcc1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1plugin.sym
-libcc1plugin_la_SOURCES = libcc1plugin.cc $(shared_source) $(marshall_c_source)
+libcc1plugin_la_SOURCES = libcc1plugin.cc context.cc context.hh \
+	$(shared_source) $(marshall_c_source)
+
 libcc1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_C)
 libcc1plugin_la_LIBADD = $(libiberty)
 libcc1plugin_la_DEPENDENCIES = $(libiberty_dep)
@@ -417,7 +417,9 @@ libcc1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
 	$(CXXFLAGS) $(libcc1plugin_la_LDFLAGS) $(LTLDFLAGS) -o $@
 
 libcp1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcp1plugin.sym
-libcp1plugin_la_SOURCES = libcp1plugin.cc $(shared_source) $(marshall_cxx_source)
+libcp1plugin_la_SOURCES = libcp1plugin.cc context.cc context.hh \
+	$(shared_source) $(marshall_cxx_source)
+
 libcp1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_CXX)
 libcp1plugin_la_LIBADD = $(libiberty)
 libcp1plugin_la_DEPENDENCIES = $(libiberty_dep)
@@ -579,6 +581,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compiler.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/context.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findcomp.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcc1.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcc1plugin.Plo@am__quote@
diff --git a/libcc1/context.cc b/libcc1/context.cc
new file mode 100644
index 000000000000..3d5ff921df8a
--- /dev/null
+++ b/libcc1/context.cc
@@ -0,0 +1,171 @@
+/* Generic plugin context
+   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/>.  */
+
+#include <cc1plugin-config.h>
+
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include "../gcc/config.h"
+
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include "gcc-plugin.h"
+#include "system.h"
+#include "coretypes.h"
+#include "stringpool.h"
+#include "hash-set.h"
+#include "diagnostic.h"
+#include "langhooks.h"
+#include "langhooks-def.h"
+
+#include "gcc-interface.h"
+
+#include "context.hh"
+#include "marshall.hh"
+
+\f
+
+#ifdef __GNUC__
+#pragma GCC visibility push(default)
+#endif
+int plugin_is_GPL_compatible;
+#ifdef __GNUC__
+#pragma GCC visibility pop
+#endif
+
+cc1_plugin::plugin_context *cc1_plugin::current_context;
+
+\f
+
+// This is put into the lang hooks when the plugin starts.
+
+static void
+plugin_print_error_function (diagnostic_context *context, const char *file,
+			     diagnostic_info *diagnostic)
+{
+  if (current_function_decl != NULL_TREE
+      && DECL_NAME (current_function_decl) != NULL_TREE
+      && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
+		 GCC_FE_WRAPPER_FUNCTION) == 0)
+    return;
+  lhd_print_error_function (context, file, diagnostic);
+}
+
+\f
+
+location_t
+cc1_plugin::plugin_context::get_location_t (const char *filename,
+					    unsigned int line_number)
+{
+  if (filename == NULL)
+    return UNKNOWN_LOCATION;
+
+  filename = intern_filename (filename);
+  linemap_add (line_table, LC_ENTER, false, filename, line_number);
+  location_t loc = linemap_line_start (line_table, line_number, 0);
+  linemap_add (line_table, LC_LEAVE, false, NULL, 0);
+  return loc;
+}
+
+// Add a file name to FILE_NAMES and return the canonical copy.
+const char *
+cc1_plugin::plugin_context::intern_filename (const char *filename)
+{
+  const char **slot = file_names.find_slot (filename, INSERT);
+  if (*slot == NULL)
+    {
+      /* The file name must live as long as the line map, which
+	 effectively means as long as this compilation.  So, we copy
+	 the string here but never free it.  */
+      *slot = xstrdup (filename);
+    }
+  return *slot;
+}
+
+void
+cc1_plugin::plugin_context::mark ()
+{
+  for (const auto &item : address_map)
+    {
+      ggc_mark (item->decl);
+      ggc_mark (item->address);
+    }
+
+  for (const auto &item : preserved)
+    ggc_mark (&item);
+}
+
+\f
+
+// Perform GC marking.
+
+static void
+gc_mark (void *, void *)
+{
+  if (cc1_plugin::current_context != NULL)
+    cc1_plugin::current_context->mark ();
+}
+
+void
+cc1_plugin::generic_plugin_init (struct plugin_name_args *plugin_info,
+				 unsigned int version)
+{
+  long fd = -1;
+  for (int i = 0; i < plugin_info->argc; ++i)
+    {
+      if (strcmp (plugin_info->argv[i].key, "fd") == 0)
+	{
+	  char *tail;
+	  errno = 0;
+	  fd = strtol (plugin_info->argv[i].value, &tail, 0);
+	  if (*tail != '\0' || errno != 0)
+	    fatal_error (input_location,
+			 "%s: invalid file descriptor argument to plugin",
+			 plugin_info->base_name);
+	  break;
+	}
+    }
+  if (fd == -1)
+    fatal_error (input_location,
+		 "%s: required plugin argument %<fd%> is missing",
+		 plugin_info->base_name);
+
+  current_context = new plugin_context (fd);
+
+  // Handshake.
+  cc1_plugin::protocol_int h_version;
+  if (!current_context->require ('H')
+      || ! ::cc1_plugin::unmarshall (current_context, &h_version))
+    fatal_error (input_location,
+		 "%s: handshake failed", plugin_info->base_name);
+  if (h_version != version)
+    fatal_error (input_location,
+		 "%s: unknown version in handshake", plugin_info->base_name);
+
+  register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING,
+		     gc_mark, NULL);
+
+  lang_hooks.print_error_function = plugin_print_error_function;
+}
diff --git a/libcc1/context.hh b/libcc1/context.hh
new file mode 100644
index 000000000000..21a8262ad4be
--- /dev/null
+++ b/libcc1/context.hh
@@ -0,0 +1,121 @@
+/* Generic plugin context
+   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_CONTEXT_HH
+#define CC1_PLUGIN_CONTEXT_HH
+
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+
+#include "connection.hh"
+
+namespace cc1_plugin
+{
+  static inline unsigned long long
+  convert_out (tree t)
+  {
+    return (unsigned long long) (uintptr_t) t;
+  }
+
+  static inline tree
+  convert_in (unsigned long long v)
+  {
+    return (tree) (uintptr_t) v;
+  }
+
+  struct decl_addr_value
+  {
+    tree decl;
+    tree address;
+  };
+
+  struct decl_addr_hasher : free_ptr_hash<decl_addr_value>
+  {
+    static hashval_t hash (const decl_addr_value *e)
+    {
+      return DECL_UID (e->decl);
+    }
+
+    static bool equal (const decl_addr_value *p1,
+		       const decl_addr_value *p2)
+    {
+      return p1->decl == p2->decl;
+    }
+  };
+
+  struct string_hasher : nofree_ptr_hash<const char>
+  {
+    static inline hashval_t hash (const char *s)
+    {
+      return htab_hash_string (s);
+    }
+
+    static inline bool equal (const char *p1, const char *p2)
+    {
+      return strcmp (p1, p2) == 0;
+    }
+  };
+
+  struct plugin_context : public cc1_plugin::connection
+  {
+    plugin_context (int fd)
+      : cc1_plugin::connection (fd),
+	address_map (30),
+	preserved (30),
+	file_names (30)
+    {
+    }
+
+    // Map decls to addresses.
+    hash_table<decl_addr_hasher> address_map;
+
+    // A collection of trees that are preserved for the GC.
+    hash_table< nofree_ptr_hash<tree_node> > preserved;
+
+    // File name cache.
+    hash_table<string_hasher> file_names;
+
+    // Perform GC marking.
+    void mark ();
+
+    // Preserve a tree during the plugin's operation.
+    tree preserve (tree t)
+    {
+      tree_node **slot = preserved.find_slot (t, INSERT);
+      *slot = t;
+      return t;
+    }
+
+    location_t get_location_t (const char *filename,
+			       unsigned int line_number);
+
+  private:
+
+    // Add a file name to FILE_NAMES and return the canonical copy.
+    const char *intern_filename (const char *filename);
+  };
+
+  extern plugin_context *current_context;
+
+  void generic_plugin_init (struct plugin_name_args *plugin_info,
+			    unsigned int version);
+}
+
+#endif // CC1_PLUGIN_CONTEXT_HH
diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc
index 2a75faba7652..d6951ab1a4d2 100644
--- a/libcc1/libcc1plugin.cc
+++ b/libcc1/libcc1plugin.cc
@@ -66,87 +66,11 @@
 #include "marshall.hh"
 #include "rpc.hh"
 #include "gcc-c-interface.h"
+#include "context.hh"
 
 #include <vector>
 
-#ifdef __GNUC__
-#pragma GCC visibility push(default)
-#endif
-int plugin_is_GPL_compatible;
-#ifdef __GNUC__
-#pragma GCC visibility pop
-#endif
-
-\f
-
-// This is put into the lang hooks when the plugin starts.
-
-static void
-plugin_print_error_function (diagnostic_context *context, const char *file,
-			     diagnostic_info *diagnostic)
-{
-  if (current_function_decl != NULL_TREE
-      && DECL_NAME (current_function_decl) != NULL_TREE
-      && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
-		 GCC_FE_WRAPPER_FUNCTION) == 0)
-    return;
-  lhd_print_error_function (context, file, diagnostic);
-}
-
-\f
-
-static unsigned long long
-convert_out (tree t)
-{
-  return (unsigned long long) (uintptr_t) t;
-}
-
-static tree
-convert_in (unsigned long long v)
-{
-  return (tree) (uintptr_t) v;
-}
-
-\f
-
-struct decl_addr_value
-{
-  tree decl;
-  tree address;
-};
-
-struct decl_addr_hasher : free_ptr_hash<decl_addr_value>
-{
-  static inline hashval_t hash (const decl_addr_value *);
-  static inline bool equal (const decl_addr_value *, const decl_addr_value *);
-};
-
-inline hashval_t
-decl_addr_hasher::hash (const decl_addr_value *e)
-{
-  return IDENTIFIER_HASH_VALUE (DECL_NAME (e->decl));
-}
-
-inline bool
-decl_addr_hasher::equal (const decl_addr_value *p1, const decl_addr_value *p2)
-{
-  return p1->decl == p2->decl;
-}
-
-\f
-
-struct string_hasher : nofree_ptr_hash<const char>
-{
-  static inline hashval_t hash (const char *s)
-  {
-    return htab_hash_string (s);
-  }
-
-  static inline bool equal (const char *p1, const char *p2)
-  {
-    return strcmp (p1, p2) == 0;
-  }
-};
+using namespace cc1_plugin;
 
 \f
 
@@ -166,85 +90,6 @@ pushdecl_safe (tree decl)
 
 \f
 
-struct plugin_context : public cc1_plugin::connection
-{
-  plugin_context (int fd);
-
-  // Map decls to addresses.
-  hash_table<decl_addr_hasher> address_map;
-
-  // A collection of trees that are preserved for the GC.
-  hash_table< nofree_ptr_hash<tree_node> > preserved;
-
-  // File name cache.
-  hash_table<string_hasher> file_names;
-
-  // Perform GC marking.
-  void mark ();
-
-  // Preserve a tree during the plugin's operation.
-  tree preserve (tree t)
-  {
-    tree_node **slot = preserved.find_slot (t, INSERT);
-    *slot = t;
-    return t;
-  }
-
-  location_t get_location_t (const char *filename,
-			     unsigned int line_number)
-  {
-    if (filename == NULL)
-      return UNKNOWN_LOCATION;
-
-    filename = intern_filename (filename);
-    linemap_add (line_table, LC_ENTER, false, filename, line_number);
-    location_t loc = linemap_line_start (line_table, line_number, 0);
-    linemap_add (line_table, LC_LEAVE, false, NULL, 0);
-    return loc;
-  }
-
-private:
-
-  // Add a file name to FILE_NAMES and return the canonical copy.
-  const char *intern_filename (const char *filename)
-  {
-    const char **slot = file_names.find_slot (filename, INSERT);
-    if (*slot == NULL)
-      {
-	/* The file name must live as long as the line map, which
-	   effectively means as long as this compilation.  So, we copy
-	   the string here but never free it.  */
-	*slot = xstrdup (filename);
-      }
-    return *slot;
-  }
-};
-
-static plugin_context *current_context;
-
-\f
-
-plugin_context::plugin_context (int fd)
-  : cc1_plugin::connection (fd),
-    address_map (30),
-    preserved (30),
-    file_names (30)
-{
-}
-
-void
-plugin_context::mark ()
-{
-  for (const auto &item : address_map)
-    {
-      ggc_mark (item->decl);
-      ggc_mark (item->address);
-    }
-
-  for (const auto &item : preserved)
-    ggc_mark (&item);
-}
-
 static void
 plugin_binding_oracle (enum c_oracle_request kind, tree identifier)
 {
@@ -899,15 +744,6 @@ plugin_error (cc1_plugin::connection *,
 
 \f
 
-// Perform GC marking.
-
-static void
-gc_mark (void *, void *)
-{
-  if (current_context != NULL)
-    current_context->mark ();
-}
-
 #ifdef __GNUC__
 #pragma GCC visibility push(default)
 #endif
@@ -916,46 +752,12 @@ int
 plugin_init (struct plugin_name_args *plugin_info,
 	     struct plugin_gcc_version *)
 {
-  long fd = -1;
-  for (int i = 0; i < plugin_info->argc; ++i)
-    {
-      if (strcmp (plugin_info->argv[i].key, "fd") == 0)
-	{
-	  char *tail;
-	  errno = 0;
-	  fd = strtol (plugin_info->argv[i].value, &tail, 0);
-	  if (*tail != '\0' || errno != 0)
-	    fatal_error (input_location,
-			 "%s: invalid file descriptor argument to plugin",
-			 plugin_info->base_name);
-	  break;
-	}
-    }
-  if (fd == -1)
-    fatal_error (input_location,
-		 "%s: required plugin argument %<fd%> is missing",
-		 plugin_info->base_name);
-
-  current_context = new plugin_context (fd);
-
-  // Handshake.
-  cc1_plugin::protocol_int version;
-  if (!current_context->require ('H')
-      || ! ::cc1_plugin::unmarshall (current_context, &version))
-    fatal_error (input_location,
-		 "%s: handshake failed", plugin_info->base_name);
-  if (version != GCC_C_FE_VERSION_1)
-    fatal_error (input_location,
-		 "%s: unknown version in handshake", plugin_info->base_name);
+  generic_plugin_init (plugin_info, GCC_C_FE_VERSION_1);
 
   register_callback (plugin_info->base_name, PLUGIN_PRAGMAS,
 		     plugin_init_extra_pragmas, NULL);
   register_callback (plugin_info->base_name, PLUGIN_PRE_GENERICIZE,
 		     rewrite_decls_to_addresses, NULL);
-  register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING,
-		     gc_mark, NULL);
-
-  lang_hooks.print_error_function = plugin_print_error_function;
 
 #define GCC_METHOD0(R, N)			\
   {						\
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index ba6c5ef2efce..64cde651139c 100644
--- a/libcc1/libcp1plugin.cc
+++ b/libcc1/libcp1plugin.cc
@@ -38,7 +38,6 @@
 #include "stringpool.h"
 
 #include "gcc-interface.h"
-#include "hash-set.h"
 #include "machmode.h"
 #include "vec.h"
 #include "double-int.h"
@@ -69,172 +68,19 @@
 #include "connection.hh"
 #include "marshall-cp.hh"
 #include "rpc.hh"
+#include "context.hh"
 
 #include <vector>
 
-#ifdef __GNUC__
-#pragma GCC visibility push(default)
-#endif
-int plugin_is_GPL_compatible;
-#ifdef __GNUC__
-#pragma GCC visibility pop
-#endif
+using namespace cc1_plugin;
 
 \f
 
 static_assert (GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END,
 	       "GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END");
 
-// This is put into the lang hooks when the plugin starts.
-
-static void
-plugin_print_error_function (diagnostic_context *context, const char *file,
-			     diagnostic_info *diagnostic)
-{
-  if (current_function_decl != NULL_TREE
-      && DECL_NAME (current_function_decl) != NULL_TREE
-      && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
-		 GCC_FE_WRAPPER_FUNCTION) == 0)
-    return;
-  lhd_print_error_function (context, file, diagnostic);
-}
-
 \f
 
-static unsigned long long
-convert_out (tree t)
-{
-  return (unsigned long long) (uintptr_t) t;
-}
-
-static tree
-convert_in (unsigned long long v)
-{
-  return (tree) (uintptr_t) v;
-}
-
-\f
-
-struct decl_addr_value
-{
-  tree decl;
-  tree address;
-};
-
-struct decl_addr_hasher : free_ptr_hash<decl_addr_value>
-{
-  static inline hashval_t hash (const decl_addr_value *);
-  static inline bool equal (const decl_addr_value *, const decl_addr_value *);
-};
-
-inline hashval_t
-decl_addr_hasher::hash (const decl_addr_value *e)
-{
-  return DECL_UID (e->decl);
-}
-
-inline bool
-decl_addr_hasher::equal (const decl_addr_value *p1, const decl_addr_value *p2)
-{
-  return p1->decl == p2->decl;
-}
-
-\f
-
-struct string_hasher : nofree_ptr_hash<const char>
-{
-  static inline hashval_t hash (const char *s)
-  {
-    return htab_hash_string (s);
-  }
-
-  static inline bool equal (const char *p1, const char *p2)
-  {
-    return strcmp (p1, p2) == 0;
-  }
-};
-
-\f
-
-struct plugin_context : public cc1_plugin::connection
-{
-  plugin_context (int fd);
-
-  // Map decls to addresses.
-  hash_table<decl_addr_hasher> address_map;
-
-  // A collection of trees that are preserved for the GC.
-  hash_table< nofree_ptr_hash<tree_node> > preserved;
-
-  // File name cache.
-  hash_table<string_hasher> file_names;
-
-  // Perform GC marking.
-  void mark ();
-
-  // Preserve a tree during the plugin's operation.
-  tree preserve (tree t)
-  {
-    tree_node **slot = preserved.find_slot (t, INSERT);
-    *slot = t;
-    return t;
-  }
-
-  location_t get_location_t (const char *filename,
-			     unsigned int line_number)
-  {
-    if (filename == NULL)
-      return UNKNOWN_LOCATION;
-
-    filename = intern_filename (filename);
-    linemap_add (line_table, LC_ENTER, false, filename, line_number);
-    location_t loc = linemap_line_start (line_table, line_number, 0);
-    linemap_add (line_table, LC_LEAVE, false, NULL, 0);
-    return loc;
-  }
-
-private:
-
-  // Add a file name to FILE_NAMES and return the canonical copy.
-  const char *intern_filename (const char *filename)
-  {
-    const char **slot = file_names.find_slot (filename, INSERT);
-    if (*slot == NULL)
-      {
-	/* The file name must live as long as the line map, which
-	   effectively means as long as this compilation.  So, we copy
-	   the string here but never free it.  */
-	*slot = xstrdup (filename);
-      }
-    return *slot;
-  }
-};
-
-static plugin_context *current_context;
-
-\f
-
-plugin_context::plugin_context (int fd)
-  : cc1_plugin::connection (fd),
-    address_map (30),
-    preserved (30),
-    file_names (30)
-{
-}
-
-void
-plugin_context::mark ()
-{
-  for (const auto &item : address_map)
-    {
-      ggc_mark (item->decl);
-      ggc_mark (item->address);
-    }
-
-  for (const auto &item : preserved)
-    ggc_mark (&item);
-}
-
 static void
 plugin_binding_oracle (enum cp_oracle_request kind, tree identifier)
 {
@@ -3645,15 +3491,6 @@ plugin_add_static_assert (cc1_plugin::connection *self,
 
 \f
 
-// Perform GC marking.
-
-static void
-gc_mark (void *, void *)
-{
-  if (current_context != NULL)
-    current_context->mark ();
-}
-
 #ifdef __GNUC__
 #pragma GCC visibility push(default)
 #endif
@@ -3662,46 +3499,12 @@ int
 plugin_init (struct plugin_name_args *plugin_info,
 	     struct plugin_gcc_version *)
 {
-  long fd = -1;
-  for (int i = 0; i < plugin_info->argc; ++i)
-    {
-      if (strcmp (plugin_info->argv[i].key, "fd") == 0)
-	{
-	  char *tail;
-	  errno = 0;
-	  fd = strtol (plugin_info->argv[i].value, &tail, 0);
-	  if (*tail != '\0' || errno != 0)
-	    fatal_error (input_location,
-			 "%s: invalid file descriptor argument to plugin",
-			 plugin_info->base_name);
-	  break;
-	}
-    }
-  if (fd == -1)
-    fatal_error (input_location,
-		 "%s: required plugin argument %<fd%> is missing",
-		 plugin_info->base_name);
-
-  current_context = new plugin_context (fd);
-
-  // Handshake.
-  cc1_plugin::protocol_int version;
-  if (!current_context->require ('H')
-      || ! ::cc1_plugin::unmarshall (current_context, &version))
-    fatal_error (input_location,
-		 "%s: handshake failed", plugin_info->base_name);
-  if (version != GCC_CP_FE_VERSION_0)
-    fatal_error (input_location,
-		 "%s: unknown version in handshake", plugin_info->base_name);
+  generic_plugin_init (plugin_info, GCC_CP_FE_VERSION_0);
 
   register_callback (plugin_info->base_name, PLUGIN_PRAGMAS,
 		     plugin_init_extra_pragmas, NULL);
   register_callback (plugin_info->base_name, PLUGIN_PRE_GENERICIZE,
 		     rewrite_decls_to_addresses, NULL);
-  register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING,
-		     gc_mark, NULL);
-
-  lang_hooks.print_error_function = plugin_print_error_function;
 
 #define GCC_METHOD0(R, N)			\
   {						\
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 15/21] libcc1: share GDB plugin code
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (13 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 14/21] libcc1: share basic context code Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-30 14:50   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 16/21] libcc1: use GCC_FE_VERSION_1 in C++ plugin Tom Tromey
                   ` (5 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

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/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* 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/ChangeLog |  17 +++++++
 libcc1/gdbctx.hh | 105 +++++++++++++++++++++++++++++++++++++++++++
 libcc1/libcc1.cc | 105 ++++++++-----------------------------------
 libcc1/libcp1.cc | 113 +++++++++--------------------------------------
 4 files changed, 162 insertions(+), 178 deletions(-)
 create mode 100644 libcc1/gdbctx.hh

diff --git a/libcc1/gdbctx.hh b/libcc1/gdbctx.hh
new file mode 100644
index 000000000000..1c8d87dff021
--- /dev/null
+++ b/libcc1/gdbctx.hh
@@ -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
diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index ea52c26d7832..b9f1eb343aaf 100644
--- a/libcc1/libcc1.cc
+++ b/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,
diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc
index c57ac8c66a6b..6fb9fb4c9a6c 100644
--- a/libcc1/libcp1.cc
+++ b/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,
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 16/21] libcc1: use GCC_FE_VERSION_1 in C++ plugin
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (14 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 15/21] libcc1: share GDB plugin code Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-28 16:06   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 17/21] libcc1: share the GCC interface code Tom Tromey
                   ` (4 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

The C++ plugin defaults to version 0 of the base compiler API.
However, this is a mistake -- version 1 was introduced before the C++
API was even implemented.  This switches the default to version 1.
Note that the compiler-side plugin will accept this version, so it
should remain compatible.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* libcp1.cc (vtable): Use GCC_FE_VERSION_1.
---
 libcc1/ChangeLog | 4 ++++
 libcc1/libcp1.cc | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc
index 6fb9fb4c9a6c..65e9770205c0 100644
--- a/libcc1/libcp1.cc
+++ b/libcc1/libcp1.cc
@@ -391,7 +391,7 @@ libcp1_destroy (struct gcc_base_context *s)
 
 static const struct gcc_base_vtable vtable =
 {
-  GCC_FE_VERSION_0,
+  GCC_FE_VERSION_1,
   libcp1_set_arguments_v0,
   libcp1_set_source_file,
   libcp1_set_print_callback,
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 17/21] libcc1: share the GCC interface code
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (15 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 16/21] libcc1: use GCC_FE_VERSION_1 in C++ plugin Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-30 15:07   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 18/21] libcc1: fix a memory leak Tom Tromey
                   ` (3 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

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  <tom@tromey.com>

	* 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.
	<add_callbacks>: New virtual method.
	<plugin_name, fe_version, compiler_name, vtable>: 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<typename T>
   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<cc1_plugin::compiler> compilerp;
+
+  private:
+
+    struct gcc_base_vtable vtable;
+
+    static inline base_gdb_plugin<T> *
+    get_self (gcc_base_context *s)
+    {
+      T *sub = (T *) s;
+      return static_cast<base_gdb_plugin<T> *> (sub);
+    }
+
+    static void
+    do_set_verbose (struct gcc_base_context *s, int /* bool */ verbose)
+    {
+      base_gdb_plugin<T> *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<T> *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<T> *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<T> *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<T> *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<T> *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<T> *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<char *> (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<T> *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<gcc_c_context>
 {
-  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<gcc_c_context> (v)
+libcc1::libcc1 (const gcc_c_fe_vtable *cv)
+  : cc1_plugin::base_gdb_plugin<gcc_c_context> ("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 =
 
 \f
 
-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<int,
 			   enum gcc_c_oracle_request,
 			   const char *,
 			   c_call_binding_oracle>;
-  self->connection->add_callback ("binding_oracle", fun);
+  connection->add_callback ("binding_oracle", fun);
 
   fun = cc1_plugin::callback<gcc_address,
 			     const char *,
 			     c_call_symbol_address>;
-  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<char *> (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<gcc_cp_context>
 {
-  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<gcc_cp_context>
   void *oracle_datum = nullptr;
 };
 
-libcp1::libcp1 (const gcc_base_vtable *v, const gcc_cp_fe_vtable *cv)
-  : cc1_plugin::base_gdb_plugin<gcc_cp_context> (v)
+libcp1::libcp1 (const gcc_cp_fe_vtable *cv)
+  : cc1_plugin::base_gdb_plugin<gcc_cp_context> ("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 =
 
 \f
 
-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<int,
 			   enum gcc_cp_oracle_request,
 			   const char *,
 			   cp_call_binding_oracle>;
-  self->connection->add_callback ("binding_oracle", fun);
+  connection->add_callback ("binding_oracle", fun);
 
   fun = cc1_plugin::callback<gcc_address,
 			     const char *,
 			     cp_call_symbol_address>;
-  self->connection->add_callback ("address_oracle", fun);
+  connection->add_callback ("address_oracle", fun);
 
   fun = cc1_plugin::callback<int,
 			     cp_call_enter_scope>;
-  self->connection->add_callback ("enter_scope", fun);
+  connection->add_callback ("enter_scope", fun);
 
   fun = cc1_plugin::callback<int,
 			     cp_call_leave_scope>;
-  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<char *> (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


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 18/21] libcc1: fix a memory leak
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (16 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 17/21] libcc1: share the GCC interface code Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-28 16:07   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 19/21] libcc1: use variadic templates for callbacks Tom Tromey
                   ` (2 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

libcc1 has a memory leak when calling fork_exec -- it allocates a new
vector of arguments, but then does not free it anywhere.  This patch
changes this code to use std::vector instead.

Note that the previous code tried to avoid bad_alloc.  I don't believe
this is very important.  For one thing, plenty of other allocations do
not bother with this.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* gdbctx.hh (do_compile): Use std::vector.
---
 libcc1/ChangeLog | 4 ++++
 libcc1/gdbctx.hh | 8 ++------
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/libcc1/gdbctx.hh b/libcc1/gdbctx.hh
index 4a48381f2b4a..4d2488344bc8 100644
--- a/libcc1/gdbctx.hh
+++ b/libcc1/gdbctx.hh
@@ -308,15 +308,11 @@ namespace cc1_plugin
 
       self->add_callbacks ();
 
-      char **argv = new (std::nothrow) char *[self->args.size () + 1];
-      if (argv == NULL)
-	return 0;
-
+      std::vector<char *> argv (self->args.size () + 1);
       for (unsigned int i = 0; i < self->args.size (); ++i)
 	argv[i] = const_cast<char *> (self->args[i].c_str ());
-      argv[self->args.size ()] = NULL;
 
-      return self->fork_exec (argv, fds, stderr_fds);
+      return self->fork_exec (argv.data (), fds, stderr_fds);
     }
 
     static int
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 19/21] libcc1: use variadic templates for callbacks
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (17 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 18/21] libcc1: fix a memory leak Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-30 15:08   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 20/21] libcc1: avoid extra string copies Tom Tromey
  2021-04-28  1:01 ` [PATCH v2 21/21] libcc1: avoid a call to c_str Tom Tromey
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

This patch completes the transition of libcc1 from the use of separate
template functions for different arities to the use of variadic
functions.  This is how I had wanted it to work from the very
beginning, and is possible now with C++11.

I had thought that variadic callbacks required C++17, but it turns out
that the approach taken here is basically equivalent to std::apply --
just a bit wordier.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* rpc.hh (argument_wrapper) <get>: Replace cast operator.
	(argument_wrapper<T *>) <get>: Likewise.
	(unmarshall): Add std::tuple overloads.
	(callback): Remove.
	(class invoker): New.
	* libcp1plugin.cc (plugin_init): Update.
	* libcp1.cc (libcp1::add_callbacks): Update.
	* libcc1plugin.cc (plugin_init): Update.
	* libcc1.cc (libcc1::add_callbacks): Update.
	* connection.cc (cc1_plugin::connection::do_wait): Update.
---
 libcc1/ChangeLog       |  13 +++
 libcc1/connection.cc   |   2 +-
 libcc1/libcc1.cc       |  12 +--
 libcc1/libcc1plugin.cc |  20 ++--
 libcc1/libcp1.cc       |  17 ++--
 libcc1/libcp1plugin.cc |  20 ++--
 libcc1/rpc.hh          | 219 +++++++++++------------------------------
 7 files changed, 101 insertions(+), 202 deletions(-)

diff --git a/libcc1/connection.cc b/libcc1/connection.cc
index 66d573911080..45560b9b790e 100644
--- a/libcc1/connection.cc
+++ b/libcc1/connection.cc
@@ -129,7 +129,7 @@ cc1_plugin::connection::do_wait (bool want_result)
 		  return FAIL;
 
 		callback_ftype *callback
-		  = m_callbacks.find_callback (method_name);
+		  = m_callbacks.find_callback (method_name.get ());
 		// The call to CALLBACK is where we may end up in a
 		// reentrant call.
 		if (callback == NULL || !callback (this))
diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index cbc54ee0a044..febadc8420b0 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -143,15 +143,13 @@ void
 libcc1::add_callbacks ()
 {
   cc1_plugin::callback_ftype *fun
-    = cc1_plugin::callback<int,
-			   enum gcc_c_oracle_request,
-			   const char *,
-			   c_call_binding_oracle>;
+    = cc1_plugin::invoker<int,
+			  enum gcc_c_oracle_request,
+			  const char *>::invoke<c_call_binding_oracle>;
   connection->add_callback ("binding_oracle", fun);
 
-  fun = cc1_plugin::callback<gcc_address,
-			     const char *,
-			     c_call_symbol_address>;
+  fun = cc1_plugin::invoker<gcc_address,
+			    const char *>::invoke<c_call_symbol_address>;
   connection->add_callback ("address_oracle", fun);
 }
 
diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc
index d6951ab1a4d2..4d6a3a11ee22 100644
--- a/libcc1/libcc1plugin.cc
+++ b/libcc1/libcc1plugin.cc
@@ -762,46 +762,46 @@ plugin_init (struct plugin_name_args *plugin_info,
 #define GCC_METHOD0(R, N)			\
   {						\
     cc1_plugin::callback_ftype *fun		\
-      = cc1_plugin::callback<R, plugin_ ## N>;	\
+      = cc1_plugin::invoker<R>::invoke<plugin_ ## N>;	\
     current_context->add_callback (# N, fun);	\
   }
 #define GCC_METHOD1(R, N, A)				\
   {							\
     cc1_plugin::callback_ftype *fun			\
-      = cc1_plugin::callback<R, A, plugin_ ## N>;	\
+      = cc1_plugin::invoker<R, A>::invoke<plugin_ ## N>;	\
     current_context->add_callback (# N, fun);		\
   }
 #define GCC_METHOD2(R, N, A, B)				\
   {							\
     cc1_plugin::callback_ftype *fun			\
-      = cc1_plugin::callback<R, A, B, plugin_ ## N>;	\
+      = cc1_plugin::invoker<R, A, B>::invoke<plugin_ ## N>;	\
     current_context->add_callback (# N, fun);		\
   }
 #define GCC_METHOD3(R, N, A, B, C)			\
   {							\
     cc1_plugin::callback_ftype *fun			\
-      = cc1_plugin::callback<R, A, B, C, plugin_ ## N>;	\
+      = cc1_plugin::invoker<R, A, B, C>::invoke<plugin_ ## N>;	\
     current_context->add_callback (# N, fun);		\
   }
 #define GCC_METHOD4(R, N, A, B, C, D)		\
   {						\
     cc1_plugin::callback_ftype *fun		\
-      = cc1_plugin::callback<R, A, B, C, D,	\
-			     plugin_ ## N>;	\
+      = cc1_plugin::invoker<R, A, B, C,		\
+			    D>::invoke<plugin_ ## N>;	\
     current_context->add_callback (# N, fun);	\
   }
 #define GCC_METHOD5(R, N, A, B, C, D, E)	\
   {						\
     cc1_plugin::callback_ftype *fun		\
-      = cc1_plugin::callback<R, A, B, C, D, E,	\
-			     plugin_ ## N>;	\
+      = cc1_plugin::invoker<R, A, B, C, D,	\
+			    E>::invoke<plugin_ ## N>;	\
     current_context->add_callback (# N, fun);	\
   }
 #define GCC_METHOD7(R, N, A, B, C, D, E, F, G)		\
   {							\
     cc1_plugin::callback_ftype *fun			\
-      = cc1_plugin::callback<R, A, B, C, D, E, F, G,	\
-			     plugin_ ## N>;		\
+      = cc1_plugin::invoker<R, A, B, C, D,		\
+			    E, F, G>::invoke<plugin_ ## N>;		\
     current_context->add_callback (# N, fun);		\
   }
 
diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc
index d22d9dc6af8c..a93349833901 100644
--- a/libcc1/libcp1.cc
+++ b/libcc1/libcp1.cc
@@ -166,23 +166,18 @@ void
 libcp1::add_callbacks ()
 {
   cc1_plugin::callback_ftype *fun
-    = cc1_plugin::callback<int,
-			   enum gcc_cp_oracle_request,
-			   const char *,
-			   cp_call_binding_oracle>;
+    = cc1_plugin::invoker<int, enum gcc_cp_oracle_request,
+			  const char *>::invoke<cp_call_binding_oracle>;
   connection->add_callback ("binding_oracle", fun);
 
-  fun = cc1_plugin::callback<gcc_address,
-			     const char *,
-			     cp_call_symbol_address>;
+  fun = cc1_plugin::invoker<gcc_address,
+			    const char *>::invoke<cp_call_symbol_address>;
   connection->add_callback ("address_oracle", fun);
 
-  fun = cc1_plugin::callback<int,
-			     cp_call_enter_scope>;
+  fun = cc1_plugin::invoker<int>::invoke<cp_call_enter_scope>;
   connection->add_callback ("enter_scope", fun);
 
-  fun = cc1_plugin::callback<int,
-			     cp_call_leave_scope>;
+  fun = cc1_plugin::invoker<int>::invoke<cp_call_leave_scope>;
   connection->add_callback ("leave_scope", fun);
 }
 
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index 64cde651139c..79694b919641 100644
--- a/libcc1/libcp1plugin.cc
+++ b/libcc1/libcp1plugin.cc
@@ -3509,46 +3509,46 @@ plugin_init (struct plugin_name_args *plugin_info,
 #define GCC_METHOD0(R, N)			\
   {						\
     cc1_plugin::callback_ftype *fun		\
-      = cc1_plugin::callback<R, plugin_ ## N>;	\
+      = cc1_plugin::invoker<R>::invoke<plugin_ ## N>;	\
     current_context->add_callback (# N, fun);	\
   }
 #define GCC_METHOD1(R, N, A)				\
   {							\
     cc1_plugin::callback_ftype *fun			\
-      = cc1_plugin::callback<R, A, plugin_ ## N>;	\
+      = cc1_plugin::invoker<R, A>::invoke<plugin_ ## N>;	\
     current_context->add_callback (# N, fun);		\
   }
 #define GCC_METHOD2(R, N, A, B)				\
   {							\
     cc1_plugin::callback_ftype *fun			\
-      = cc1_plugin::callback<R, A, B, plugin_ ## N>;	\
+      = cc1_plugin::invoker<R, A, B>::invoke<plugin_ ## N>;	\
     current_context->add_callback (# N, fun);		\
   }
 #define GCC_METHOD3(R, N, A, B, C)			\
   {							\
     cc1_plugin::callback_ftype *fun			\
-      = cc1_plugin::callback<R, A, B, C, plugin_ ## N>;	\
+      = cc1_plugin::invoker<R, A, B, C>::invoke<plugin_ ## N>;	\
     current_context->add_callback (# N, fun);		\
   }
 #define GCC_METHOD4(R, N, A, B, C, D)		\
   {						\
     cc1_plugin::callback_ftype *fun		\
-      = cc1_plugin::callback<R, A, B, C, D,	\
-			     plugin_ ## N>;	\
+      = cc1_plugin::invoker<R, A, B, C,		\
+			    D>::invoke<plugin_ ## N>;	\
     current_context->add_callback (# N, fun);	\
   }
 #define GCC_METHOD5(R, N, A, B, C, D, E)	\
   {						\
     cc1_plugin::callback_ftype *fun		\
-      = cc1_plugin::callback<R, A, B, C, D, E,	\
-			     plugin_ ## N>;	\
+      = cc1_plugin::invoker<R, A, B, C,		\
+			    D, E>::invoke<plugin_ ## N>;	\
     current_context->add_callback (# N, fun);	\
   }
 #define GCC_METHOD7(R, N, A, B, C, D, E, F, G)		\
   {							\
     cc1_plugin::callback_ftype *fun			\
-      = cc1_plugin::callback<R, A, B, C, D, E, F, G,	\
-			     plugin_ ## N>;		\
+      = cc1_plugin::invoker<R, A, B, C,			\
+			    D, E, F, G>::invoke<plugin_ ## N>;		\
     current_context->add_callback (# N, fun);		\
   }
 
diff --git a/libcc1/rpc.hh b/libcc1/rpc.hh
index 09cd7bdda616..8e43fa146dcc 100644
--- a/libcc1/rpc.hh
+++ b/libcc1/rpc.hh
@@ -43,7 +43,7 @@ namespace cc1_plugin
     argument_wrapper (const argument_wrapper &) = delete;
     argument_wrapper &operator= (const argument_wrapper &) = delete;
 
-    operator T () const { return m_object; }
+    T get () const { return m_object; }
 
     status unmarshall (connection *conn)
     {
@@ -68,7 +68,7 @@ namespace cc1_plugin
 
     typedef typename std::remove_const<T>::type type;
 
-    operator const type * () const
+    const type *get () const
     {
       return m_object.get ();
     }
@@ -88,17 +88,14 @@ namespace cc1_plugin
   };
 
   // There are two kinds of template functions here: "call" and
-  // "callback".  "call" is implemented with variadic templates, but
-  // "callback" is repeated multiple times to handle different numbers
-  // of arguments.  (This could be improved with C++17 and
-  // std::apply.)
+  // "invoker".
 
   // The "call" template is used for making a remote procedure call.
   // It starts a query ('Q') packet, marshalls its arguments, waits
   // for a result, and finally reads and returns the result via an
   // "out" parameter.
 
-  // The "callback" template is used when receiving a remote procedure
+  // The "invoker" template is used when receiving a remote procedure
   // call.  This template function is suitable for use with the
   // "callbacks" and "connection" classes.  It decodes incoming
   // arguments, passes them to the wrapped function, and finally
@@ -123,175 +120,71 @@ namespace cc1_plugin
     return OK;
   }
 
-  template<typename R, R (*func) (connection *)>
-  status
-  callback (connection *conn)
+  // The base case -- just return OK.
+  template<int I, typename... T>
+  typename std::enable_if<I == sizeof... (T), status>::type
+  unmarshall (connection *, std::tuple<T...> &)
   {
-    R result;
-
-    if (!unmarshall_check (conn, 0))
-      return FAIL;
-    result = func (conn);
-    if (!conn->send ('R'))
-      return FAIL;
-    return marshall (conn, result);
-  }
-
-  template<typename R, typename A, R (*func) (connection *, A)>
-  status
-  callback (connection *conn)
-  {
-    argument_wrapper<A> arg;
-    R result;
-
-    if (!unmarshall_check (conn, 1))
-      return FAIL;
-    if (!arg.unmarshall (conn))
-      return FAIL;
-    result = func (conn, arg);
-    if (!conn->send ('R'))
-      return FAIL;
-    return marshall (conn, result);
+    return OK;
   }
 
-  template<typename R, typename A1, typename A2, R (*func) (connection *,
-							    A1, A2)>
-  status
-  callback (connection *conn)
+  // Unmarshall this argument, then unmarshall all subsequent args.
+  template<int I, typename... T>
+  typename std::enable_if<I < sizeof... (T), status>::type
+  unmarshall (connection *conn, std::tuple<T...> &value)
   {
-    argument_wrapper<A1> arg1;
-    argument_wrapper<A2> arg2;
-    R result;
-
-    if (!unmarshall_check (conn, 2))
-      return FAIL;
-    if (!arg1.unmarshall (conn))
-      return FAIL;
-    if (!arg2.unmarshall (conn))
+    if (!std::get<I> (value).unmarshall (conn))
       return FAIL;
-    result = func (conn, arg1, arg2);
-    if (!conn->send ('R'))
-      return FAIL;
-    return marshall (conn, result);
+    return unmarshall<I + 1, T...> (conn, value);
   }
 
-  template<typename R, typename A1, typename A2, typename A3,
-	   R (*func) (connection *, A1, A2, A3)>
-  status
-  callback (connection *conn)
+  // Wrap a static function that is suitable for use as a callback.
+  // This is a template function inside a template class to work
+  // around limitations with multiple variadic packs.
+  template<typename R, typename... Arg>
+  class invoker
   {
-    argument_wrapper<A1> arg1;
-    argument_wrapper<A2> arg2;
-    argument_wrapper<A3> arg3;
-    R result;
+    // Base case -- we can call the function.
+    template<int I, R func (connection *, Arg...), typename... T>
+    static typename std::enable_if<I == sizeof... (Arg), R>::type
+    call (connection *conn, const std::tuple<argument_wrapper<Arg>...> &,
+	  T... args)
+    {
+      return func (conn, args...);
+    }
 
-    if (!unmarshall_check (conn, 3))
-      return FAIL;
-    if (!arg1.unmarshall (conn))
-      return FAIL;
-    if (!arg2.unmarshall (conn))
-      return FAIL;
-    if (!arg3.unmarshall (conn))
-      return FAIL;
-    result = func (conn, arg1, arg2, arg3);
-    if (!conn->send ('R'))
-      return FAIL;
-    return marshall (conn, result);
-  }
+    // Unpack one argument and continue the recursion.
+    template<int I, R func (connection *, Arg...), typename... T>
+    static typename std::enable_if<I < sizeof... (Arg), R>::type
+    call (connection *conn, const std::tuple<argument_wrapper<Arg>...> &value,
+	  T... args)
+    {
+      return call<I + 1, func> (conn, value, args...,
+				std::get<I> (value).get ());
+    }
 
-  template<typename R, typename A1, typename A2, typename A3, typename A4,
-	   R (*func) (connection *, A1, A2, A3, A4)>
-  status
-  callback (connection *conn)
-  {
-    argument_wrapper<A1> arg1;
-    argument_wrapper<A2> arg2;
-    argument_wrapper<A3> arg3;
-    argument_wrapper<A4> arg4;
-    R result;
+  public:
 
-    if (!unmarshall_check (conn, 4))
-      return FAIL;
-    if (!arg1.unmarshall (conn))
-      return FAIL;
-    if (!arg2.unmarshall (conn))
-      return FAIL;
-    if (!arg3.unmarshall (conn))
-      return FAIL;
-    if (!arg4.unmarshall (conn))
-      return FAIL;
-    result = func (conn, arg1, arg2, arg3, arg4);
-    if (!conn->send ('R'))
-      return FAIL;
-    return marshall (conn, result);
-  }
+    // A callback function that reads arguments from the connection,
+    // calls the wrapped function, and then sends the result back on
+    // the connection.
+    template<R func (connection *, Arg...)>
+    static status
+    invoke (connection *conn)
+    {
+      if (!unmarshall_check (conn, sizeof... (Arg)))
+	return FAIL;
+      std::tuple<argument_wrapper<Arg>...> wrapped;
+      if (!unmarshall<0> (conn, wrapped))
+	return FAIL;
 
-  template<typename R, typename A1, typename A2, typename A3, typename A4,
-	   typename A5, R (*func) (connection *, A1, A2, A3, A4, A5)>
-  status
-  callback (connection *conn)
-  {
-    argument_wrapper<A1> arg1;
-    argument_wrapper<A2> arg2;
-    argument_wrapper<A3> arg3;
-    argument_wrapper<A4> arg4;
-    argument_wrapper<A5> arg5;
-    R result;
-
-    if (!unmarshall_check (conn, 5))
-      return FAIL;
-    if (!arg1.unmarshall (conn))
-      return FAIL;
-    if (!arg2.unmarshall (conn))
-      return FAIL;
-    if (!arg3.unmarshall (conn))
-      return FAIL;
-    if (!arg4.unmarshall (conn))
-      return FAIL;
-    if (!arg5.unmarshall (conn))
-      return FAIL;
-    result = func (conn, arg1, arg2, arg3, arg4, arg5);
-    if (!conn->send ('R'))
-      return FAIL;
-    return marshall (conn, result);
-  }
+      R result = call<0, func> (conn, wrapped);
 
-  template<typename R, typename A1, typename A2, typename A3, typename A4,
-	   typename A5, typename A6, typename A7,
-	   R (*func) (connection *, A1, A2, A3, A4, A5, A6, A7)>
-  status
-  callback (connection *conn)
-  {
-    argument_wrapper<A1> arg1;
-    argument_wrapper<A2> arg2;
-    argument_wrapper<A3> arg3;
-    argument_wrapper<A4> arg4;
-    argument_wrapper<A5> arg5;
-    argument_wrapper<A6> arg6;
-    argument_wrapper<A7> arg7;
-    R result;
-
-    if (!unmarshall_check (conn, 7))
-      return FAIL;
-    if (!arg1.unmarshall (conn))
-      return FAIL;
-    if (!arg2.unmarshall (conn))
-      return FAIL;
-    if (!arg3.unmarshall (conn))
-      return FAIL;
-    if (!arg4.unmarshall (conn))
-      return FAIL;
-    if (!arg5.unmarshall (conn))
-      return FAIL;
-    if (!arg6.unmarshall (conn))
-      return FAIL;
-    if (!arg7.unmarshall (conn))
-      return FAIL;
-    result = func (conn, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
-    if (!conn->send ('R'))
-      return FAIL;
-    return marshall (conn, result);
-  }
+      if (!conn->send ('R'))
+	return FAIL;
+      return marshall (conn, result);
+    }
+  };
 };
 
 #endif // CC1_PLUGIN_RPC_HH
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 20/21] libcc1: avoid extra string copies
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (18 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 19/21] libcc1: use variadic templates for callbacks Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-28 16:07   ` Jeff Law
  2021-04-28  1:01 ` [PATCH v2 21/21] libcc1: avoid a call to c_str Tom Tromey
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

PR c/94669 points out that a couple of spots in libcc1 take a
std::string where a reference would do.  This changes these spots to
take a const char *, to reduce the number of copies.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	PR c/94669:
	* compiler.hh (compiler_driver_filename): Take const char *.
	(compiler_triplet_regexp): Likewise.
---
 libcc1/ChangeLog   | 6 ++++++
 libcc1/compiler.hh | 4 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/libcc1/compiler.hh b/libcc1/compiler.hh
index 638f7c09f634..d10d409f9d35 100644
--- a/libcc1/compiler.hh
+++ b/libcc1/compiler.hh
@@ -58,7 +58,7 @@ namespace cc1_plugin
 
     char *find (const char *base, std::string &compiler) const override;
 
-    compiler_triplet_regexp (bool v, std::string triplet_regexp)
+    compiler_triplet_regexp (bool v, const char *triplet_regexp)
       : compiler (v), triplet_regexp_ (triplet_regexp)
     {
     }
@@ -72,7 +72,7 @@ namespace cc1_plugin
   public:
     char *find (const char *base, std::string &compiler) const override;
 
-    compiler_driver_filename (bool v, std::string driver_filename)
+    compiler_driver_filename (bool v, const char *driver_filename)
       : compiler (v), driver_filename_ (driver_filename)
     {
     }
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 21/21] libcc1: avoid a call to c_str
  2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
                   ` (19 preceding siblings ...)
  2021-04-28  1:01 ` [PATCH v2 20/21] libcc1: avoid extra string copies Tom Tromey
@ 2021-04-28  1:01 ` Tom Tromey
  2021-04-28 16:08   ` Jeff Law
  20 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28  1:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom Tromey

This is a trivial change to libcc1 to avoid an explicit call to c_str.
Passing by const reference is slightly less wordy.

libcc1/ChangeLog
2021-04-27  Tom Tromey  <tom@tromey.com>

	* compiler.cc (make_regexp): Take const std::string.
	(cc1_plugin::compiler_triplet_regexp::find): Update.
---
 libcc1/ChangeLog   | 5 +++++
 libcc1/compiler.cc | 4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/libcc1/compiler.cc b/libcc1/compiler.cc
index fede84968625..a12843c538ae 100644
--- a/libcc1/compiler.cc
+++ b/libcc1/compiler.cc
@@ -28,7 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 
 // Construct an appropriate regexp to match the compiler name.
 static std::string
-make_regexp (const char *triplet_regexp, const char *compiler)
+make_regexp (const std::string &triplet_regexp, const char *compiler)
 {
   std::stringstream buf;
 
@@ -71,7 +71,7 @@ char *
 cc1_plugin::compiler_triplet_regexp::find (const char *base,
 					   std::string &compiler) const
 {
-  std::string rx = make_regexp (triplet_regexp_.c_str (), base);
+  std::string rx = make_regexp (triplet_regexp_, base);
   if (verbose)
     fprintf (stderr, _("searching for compiler matching regex %s\n"),
 	     rx.c_str());
-- 
2.26.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 02/21] libcc1: use "override"
  2021-04-28  1:01 ` [PATCH v2 02/21] libcc1: use "override" Tom Tromey
@ 2021-04-28 15:53   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-28 15:53 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> This changes libcc1 to use "override" where appropriate.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* libcp1.cc (class compiler_triplet_regexp)
> 	(class compiler_driver_filename, class libcp1_connection): Use
> 	"override".
> 	* libcc1.cc (class compiler_triplet_regexp)
> 	(class compiler_driver_filename, class libcc1_connection): Use
> 	"override".

OK

jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 03/21] libcc1: inline some simple methods
  2021-04-28  1:01 ` [PATCH v2 03/21] libcc1: inline some simple methods Tom Tromey
@ 2021-04-28 15:54   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-28 15:54 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> This changes libcc1 to inline a trivial method and to use the default
> constructor.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* connection.hh (~connection): Use default.
> 	(print): Inline.
> 	* connection.cc (cc1_plugin::connection::~connection)
> 	(cc1_plugin::connection::print): Remove definitions.

OK

Jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 04/21] libcc1: delete copy constructor and assignment operators
  2021-04-28  1:01 ` [PATCH v2 04/21] libcc1: delete copy constructor and assignment operators Tom Tromey
@ 2021-04-28 15:55   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-28 15:55 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> Change libcc1 to use "= delete" for the copy constructor and
> assignment operator, rather than the old approach of private methods
> that are nowhere defined.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* rpc.hh (argument_wrapper): Use delete for copy constructor.
> 	* connection.hh (class connection): Use delete for copy
> 	constructor.
> 	* callbacks.hh (class callbacks): Use delete for copy constructor.

OK

jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 07/21] libcc1: use std::vector when building function types
  2021-04-28  1:01 ` [PATCH v2 07/21] libcc1: use std::vector when building function types Tom Tromey
@ 2021-04-28 16:01   ` Jeff Law
  2021-04-28 19:56     ` Tom Tromey
  0 siblings, 1 reply; 46+ messages in thread
From: Jeff Law @ 2021-04-28 16:01 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> This changes libcc1 to use std::vector in the code that builds
> function types.  This avoids some explicit memory management.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* libcp1plugin.cc (plugin_build_function_type): Use std::vector.
> 	* libcc1plugin.cc (plugin_build_function_type): Use std::vector.

Does this really work?   In general we can't stuff GC'd objects into 
something like std::vector.  Though I guess in this instance the 
lifetime is limited and we don't have to worry about the GC system?


Jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 12/21] libcc1: use foreach
  2021-04-28  1:01 ` [PATCH v2 12/21] libcc1: use foreach Tom Tromey
@ 2021-04-28 16:04   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-28 16:04 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> This changes libcc1 to ues foreach in a couple of spots.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* libcp1plugin.cc (plugin_context::mark): Use foreach.
> 	* libcc1plugin.cc (plugin_context::mark): Use foreach.

OK

jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 13/21] libcc1: use static_assert
  2021-04-28  1:01 ` [PATCH v2 13/21] libcc1: use static_assert Tom Tromey
@ 2021-04-28 16:06   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-28 16:06 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> This changes one spot in libcc1 to use static_assert rather than the
> old-style array declaration.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* libcp1plugin.cc: Use static assert.

OK

jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 16/21] libcc1: use GCC_FE_VERSION_1 in C++ plugin
  2021-04-28  1:01 ` [PATCH v2 16/21] libcc1: use GCC_FE_VERSION_1 in C++ plugin Tom Tromey
@ 2021-04-28 16:06   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-28 16:06 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> The C++ plugin defaults to version 0 of the base compiler API.
> However, this is a mistake -- version 1 was introduced before the C++
> API was even implemented.  This switches the default to version 1.
> Note that the compiler-side plugin will accept this version, so it
> should remain compatible.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* libcp1.cc (vtable): Use GCC_FE_VERSION_1.

OK

Jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 18/21] libcc1: fix a memory leak
  2021-04-28  1:01 ` [PATCH v2 18/21] libcc1: fix a memory leak Tom Tromey
@ 2021-04-28 16:07   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-28 16:07 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> libcc1 has a memory leak when calling fork_exec -- it allocates a new
> vector of arguments, but then does not free it anywhere.  This patch
> changes this code to use std::vector instead.
>
> Note that the previous code tried to avoid bad_alloc.  I don't believe
> this is very important.  For one thing, plenty of other allocations do
> not bother with this.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* gdbctx.hh (do_compile): Use std::vector.

OK

jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 20/21] libcc1: avoid extra string copies
  2021-04-28  1:01 ` [PATCH v2 20/21] libcc1: avoid extra string copies Tom Tromey
@ 2021-04-28 16:07   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-28 16:07 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> PR c/94669 points out that a couple of spots in libcc1 take a
> std::string where a reference would do.  This changes these spots to
> take a const char *, to reduce the number of copies.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	PR c/94669:
> 	* compiler.hh (compiler_driver_filename): Take const char *.
> 	(compiler_triplet_regexp): Likewise.

OK

jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 21/21] libcc1: avoid a call to c_str
  2021-04-28  1:01 ` [PATCH v2 21/21] libcc1: avoid a call to c_str Tom Tromey
@ 2021-04-28 16:08   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-28 16:08 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> This is a trivial change to libcc1 to avoid an explicit call to c_str.
> Passing by const reference is slightly less wordy.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* compiler.cc (make_regexp): Take const std::string.
> 	(cc1_plugin::compiler_triplet_regexp::find): Update.

OK

jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 01/21] libcc1: use templates to unmarshall enums
  2021-04-28  1:00 ` [PATCH v2 01/21] libcc1: use templates to unmarshall enums Tom Tromey
@ 2021-04-28 18:27   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-28 18:27 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:00 PM, Tom Tromey wrote:
> Now that C++11 can be used in GCC, libcc1 can be changed to use
> templates and type traits to handle unmarshalling all kinds of enums.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* marshall.hh (cc1_plugin::unmarshall): Use type traits.
> 	* marshall-cp.hh (cc1_plugin::unmarshall): Remove overloads.
> 	* marshall-c.hh: Remove.
> 	* libcc1plugin.cc: Update includes.
> 	* libcc1.cc: Update includes.

OK

jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 05/21] libcc1: use variadic templates for "call"
  2021-04-28  1:01 ` [PATCH v2 05/21] libcc1: use variadic templates for "call" Tom Tromey
@ 2021-04-28 18:28   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-28 18:28 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> This changes libcc1 to use variadic templates for the "call"
> functions.  The primary benefit is that this simplifies the code.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* rpc.hh (call): Use variadic template.  Remove overloads.
> 	* marshall.hh (marshall): Add base overload.  Use variadic
> 	template.

OK

jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 06/21] libcc1: use variadic templates for "rpc"
  2021-04-28  1:01 ` [PATCH v2 06/21] libcc1: use variadic templates for "rpc" Tom Tromey
@ 2021-04-28 18:28   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-28 18:28 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> This changes libcc1 to use variadic templates for the "rpc" functions.
> This simplifies the code and removes some possibility for mistakes.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* libcp1.cc (rpc): Use variadic template.  Remove overloads.
> 	* libcc1.cc (rpc): Use variadic template.  Remove overloads.

OK

jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 07/21] libcc1: use std::vector when building function types
  2021-04-28 16:01   ` Jeff Law
@ 2021-04-28 19:56     ` Tom Tromey
  2021-04-28 20:07       ` Jeff Law
  0 siblings, 1 reply; 46+ messages in thread
From: Tom Tromey @ 2021-04-28 19:56 UTC (permalink / raw)
  To: Jeff Law; +Cc: Tom Tromey, gcc-patches

>>>>> "Jeff" == Jeff Law <jeffreyalaw@gmail.com> writes:

Jeff> On 4/27/2021 7:01 PM, Tom Tromey wrote:
>> This changes libcc1 to use std::vector in the code that builds
>> function types.  This avoids some explicit memory management.
>> 
>> libcc1/ChangeLog
>> 2021-04-27  Tom Tromey  <tom@tromey.com>
>> 
>> * libcp1plugin.cc (plugin_build_function_type): Use std::vector.
>> * libcc1plugin.cc (plugin_build_function_type): Use std::vector.

Jeff> Does this really work?   In general we can't stuff GC'd objects into
Jeff> something like std::vector.  Though I guess in this instance the 
Jeff> lifetime is limited and we don't have to worry about the GC system?

It's the latter.

The patch doesn't really change whether or not the elements of the array
are visible to the GC.  It just changes how the vector is managed --
from manual use of new/delete to automatic via vector.

The plugins do need to interface with the GC, but this is done by
registering GC'able objects in a global hash table that is manually
marked; see the 'preserve' and 'mark' methods on the plugin context
objects.

thanks,
Tom

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 07/21] libcc1: use std::vector when building function types
  2021-04-28 19:56     ` Tom Tromey
@ 2021-04-28 20:07       ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-28 20:07 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gcc-patches


On 4/28/2021 1:56 PM, Tom Tromey wrote:
>>>>>> "Jeff" == Jeff Law <jeffreyalaw@gmail.com> writes:
> Jeff> On 4/27/2021 7:01 PM, Tom Tromey wrote:
>>> This changes libcc1 to use std::vector in the code that builds
>>> function types.  This avoids some explicit memory management.
>>>
>>> libcc1/ChangeLog
>>> 2021-04-27  Tom Tromey  <tom@tromey.com>
>>>
>>> * libcp1plugin.cc (plugin_build_function_type): Use std::vector.
>>> * libcc1plugin.cc (plugin_build_function_type): Use std::vector.
> Jeff> Does this really work?   In general we can't stuff GC'd objects into
> Jeff> something like std::vector.  Though I guess in this instance the
> Jeff> lifetime is limited and we don't have to worry about the GC system?
>
> It's the latter.
>
> The patch doesn't really change whether or not the elements of the array
> are visible to the GC.  It just changes how the vector is managed --
> from manual use of new/delete to automatic via vector.
>
> The plugins do need to interface with the GC, but this is done by
> registering GC'able objects in a global hash table that is manually
> marked; see the 'preserve' and 'mark' methods on the plugin context
> objects.

OK.  Then let's go with the patch as-is.

jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 08/21] libcc1: add deleter objects
  2021-04-28  1:01 ` [PATCH v2 08/21] libcc1: add deleter objects Tom Tromey
@ 2021-04-28 21:06   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-28 21:06 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> This adds deleter objects for various kinds of protocol pointers to
> libcc1.  Existing specializations of argument_wrapper are then
> replaced with a single specialization that handles all pointer types
> via the appropriate deleter.  The result here is a bit nicer because
> the argument_wrapper boilerplate code is completely shared, leaving
> just the memory-management detail to the particular specializations.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* rpc.hh (struct deleter): New template class and
> 	specializations.
> 	(argument_wrapper): Remove specializations.  Add specialization
> 	for any pointer type.

OK


Jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 09/21] libcc1: add more uses of 'deleter'
  2021-04-28  1:01 ` [PATCH v2 09/21] libcc1: add more uses of 'deleter' Tom Tromey
@ 2021-04-29 12:43   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-29 12:43 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> This changes libcc1 to use the 'deleter' template in a few more
> places.  The template and basic specializations are moved to a new
> header, then some unmarshall functions are changed to use this code.
> This change avoids the need to repeat cleanup code in the
> unmarshallers.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* rpc.hh (deleter): Move template and some specializations to
> 	deleter.hh.
> 	(argument_wrapper<const T *>): Use cc1_plugin::unique_ptr.
> 	* marshall.cc (cc1_plugin::unmarshall): Use
> 	cc1_plugin::unique_ptr.
> 	* marshall-cp.hh (deleter): New specializations.
> 	(unmarshall): Use cc1_plugin::unique_ptr.
> 	* deleter.hh: New file.

OK

jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 10/21] libcc1: use unique_ptr more
  2021-04-28  1:01 ` [PATCH v2 10/21] libcc1: use unique_ptr more Tom Tromey
@ 2021-04-29 12:44   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-29 12:44 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> This changes libcc1 to use unique_ptr in a few more places, removing
> some manual memory management.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* libcp1.cc (struct libcp1) <connection, compilerp>: Use
> 	unique_ptr.
> 	(~libcp1): Remove.
> 	(libcp1_compile, libcp1_set_triplet_regexp)
> 	(libcp1_set_driver_filename): Update.
> 	* libcc1.cc (struct libcc1) <connection, compilerp>: Use
> 	unique_ptr.
> 	(~libcc1): Remove.
> 	(libcc1_set_triplet_regexp, libcc1_set_driver_filename)
> 	(libcc1_compile): Update.

OK

Jeff

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 11/21] libcc1: unify compiler handling
  2021-04-28  1:01 ` [PATCH v2 11/21] libcc1: unify compiler handling Tom Tromey
@ 2021-04-29 12:47   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-29 12:47 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> Both libcc1 plugins have nearly identical copies of code to find the
> underlying compiler.  This seemed wasteful to me, so this patch
> unifies the copies.
>
> Two minor API changes were needed.
>
> First, the old code used a back-link from the compiler object to the
> plugin object to check the 'verbose' setting.  This patch adds a
> 'verbose' setting directly to the compiler object instead.
>
> Second, the 'find' method implicitly knew which compiler base name
> ("gcc" or "g++") to use.  This patch makes this a parameter that is
> passed in by the plugin.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* libcc1.cc (compiler, compiler_triplet_regexp)
> 	(compiler_driver_filename): Remove.
> 	(libcp1::libcp1): Update.
> 	(make_regexp, libcp1::compiler::find)
> 	(libcp1::compiler_triplet_regexp::find)
> 	(libcp1::compiler_driver_filename::find): Remove.
> 	(libcp1_set_verbose, libcp1_set_arguments)
> 	(libcp1_set_triplet_regexp, libcp1_set_driver_filename): Update.
> 	* libcc1.cc (compiler, compiler_triplet_regexp)
> 	(compiler_driver_filename): Remove.
> 	(libcc1::libcc1): Update.
> 	(make_regexp, libcc1::compiler::find)
> 	(libcc1::compiler_triplet_regexp::find)
> 	(libcc1::compiler_driver_filename::find): Remove.
> 	(libcc1_set_verbose, libcc1_set_arguments)
> 	(libcc1_set_triplet_regexp, libcc1_set_driver_filename): Update.
> 	* compiler.cc: New file.
> 	* compiler.hh: New file.
> 	* Makefile.in: Rebuild.
> 	* Makefile.am (libcc1_la_SOURCES): Add compiler.hh, compiler.cc.

OK

Jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 14/21] libcc1: share basic context code
  2021-04-28  1:01 ` [PATCH v2 14/21] libcc1: share basic context code Tom Tromey
@ 2021-04-29 12:50   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-29 12:50 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> Both plugins in libcc1 share a fair amount of boilerplate.  They both
> share error-emission code, context management code, and tree GC code.
> This patch unifies these two bodies of code, avoiding needless
> duplication.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* libcc1plugin.cc: Move code to context.cc.
> 	* libcp1plugin.cc: Move code to context.cc.
> 	* context.hh: New file.
> 	* context.cc: New file.
> 	* Makefile.in: Rebuild.
> 	* Makefile.am (AM_CPPFLAGS): Add more gcc flags.
> 	(CPPFLAGS_FOR_C, CPPFLAGS_FOR_CXX): Update.
> 	(libcc1plugin_la_SOURCES): Add context.hh, context.cc.
> 	(libcp1plugin_la_SOURCES): Likewise.

OK

jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 15/21] libcc1: share GDB plugin code
  2021-04-28  1:01 ` [PATCH v2 15/21] libcc1: share GDB plugin code Tom Tromey
@ 2021-04-30 14:50   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-30 14:50 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> 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/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* 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.

OK

jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 17/21] libcc1: share the GCC interface code
  2021-04-28  1:01 ` [PATCH v2 17/21] libcc1: share the GCC interface code Tom Tromey
@ 2021-04-30 15:07   ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2021-04-30 15:07 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> 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  <tom@tromey.com>
>
> 	* 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.
> 	<add_callbacks>: New virtual method.
> 	<plugin_name, fe_version, compiler_name, vtable>: 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.

OK

Jeff

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 19/21] libcc1: use variadic templates for callbacks
  2021-04-28  1:01 ` [PATCH v2 19/21] libcc1: use variadic templates for callbacks Tom Tromey
@ 2021-04-30 15:08   ` Jeff Law
  2021-05-04 22:05     ` Tom Tromey
  0 siblings, 1 reply; 46+ messages in thread
From: Jeff Law @ 2021-04-30 15:08 UTC (permalink / raw)
  To: Tom Tromey, gcc-patches


On 4/27/2021 7:01 PM, Tom Tromey wrote:
> This patch completes the transition of libcc1 from the use of separate
> template functions for different arities to the use of variadic
> functions.  This is how I had wanted it to work from the very
> beginning, and is possible now with C++11.
>
> I had thought that variadic callbacks required C++17, but it turns out
> that the approach taken here is basically equivalent to std::apply --
> just a bit wordier.
>
> libcc1/ChangeLog
> 2021-04-27  Tom Tromey  <tom@tromey.com>
>
> 	* rpc.hh (argument_wrapper) <get>: Replace cast operator.
> 	(argument_wrapper<T *>) <get>: Likewise.
> 	(unmarshall): Add std::tuple overloads.
> 	(callback): Remove.
> 	(class invoker): New.
> 	* libcp1plugin.cc (plugin_init): Update.
> 	* libcp1.cc (libcp1::add_callbacks): Update.
> 	* libcc1plugin.cc (plugin_init): Update.
> 	* libcc1.cc (libcc1::add_callbacks): Update.
> 	* connection.cc (cc1_plugin::connection::do_wait): Update.

OK

I think that's the whole set.  If not, let me know.


jeff


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 19/21] libcc1: use variadic templates for callbacks
  2021-04-30 15:08   ` Jeff Law
@ 2021-05-04 22:05     ` Tom Tromey
  0 siblings, 0 replies; 46+ messages in thread
From: Tom Tromey @ 2021-05-04 22:05 UTC (permalink / raw)
  To: Jeff Law; +Cc: Tom Tromey, gcc-patches

Jeff> OK

Jeff> I think that's the whole set.  If not, let me know.

It is.  Thank you for the reviews.
I am checking it in now.

Tom

^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2021-05-04 22:05 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-28  1:00 [PATCH v2 00/21] C++11-based improvements for libcc1 Tom Tromey
2021-04-28  1:00 ` [PATCH v2 01/21] libcc1: use templates to unmarshall enums Tom Tromey
2021-04-28 18:27   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 02/21] libcc1: use "override" Tom Tromey
2021-04-28 15:53   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 03/21] libcc1: inline some simple methods Tom Tromey
2021-04-28 15:54   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 04/21] libcc1: delete copy constructor and assignment operators Tom Tromey
2021-04-28 15:55   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 05/21] libcc1: use variadic templates for "call" Tom Tromey
2021-04-28 18:28   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 06/21] libcc1: use variadic templates for "rpc" Tom Tromey
2021-04-28 18:28   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 07/21] libcc1: use std::vector when building function types Tom Tromey
2021-04-28 16:01   ` Jeff Law
2021-04-28 19:56     ` Tom Tromey
2021-04-28 20:07       ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 08/21] libcc1: add deleter objects Tom Tromey
2021-04-28 21:06   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 09/21] libcc1: add more uses of 'deleter' Tom Tromey
2021-04-29 12:43   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 10/21] libcc1: use unique_ptr more Tom Tromey
2021-04-29 12:44   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 11/21] libcc1: unify compiler handling Tom Tromey
2021-04-29 12:47   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 12/21] libcc1: use foreach Tom Tromey
2021-04-28 16:04   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 13/21] libcc1: use static_assert Tom Tromey
2021-04-28 16:06   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 14/21] libcc1: share basic context code Tom Tromey
2021-04-29 12:50   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 15/21] libcc1: share GDB plugin code Tom Tromey
2021-04-30 14:50   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 16/21] libcc1: use GCC_FE_VERSION_1 in C++ plugin Tom Tromey
2021-04-28 16:06   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 17/21] libcc1: share the GCC interface code Tom Tromey
2021-04-30 15:07   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 18/21] libcc1: fix a memory leak Tom Tromey
2021-04-28 16:07   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 19/21] libcc1: use variadic templates for callbacks Tom Tromey
2021-04-30 15:08   ` Jeff Law
2021-05-04 22:05     ` Tom Tromey
2021-04-28  1:01 ` [PATCH v2 20/21] libcc1: avoid extra string copies Tom Tromey
2021-04-28 16:07   ` Jeff Law
2021-04-28  1:01 ` [PATCH v2 21/21] libcc1: avoid a call to c_str Tom Tromey
2021-04-28 16:08   ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).