* [PATCH 01/10] libcc1: use templates to unmarshall enums
2021-01-03 18:26 [PATCH 00/10] C++11-based improvements for libcc1 Tom Tromey
@ 2021-01-03 18:26 ` Tom Tromey
2021-01-03 18:26 ` [PATCH 02/10] libcc1: use "override" Tom Tromey
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2021-01-03 18:26 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-01-03 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 c675624ee1c..1838f2e5577 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 241a8158b98..a0fb61f2e46 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 a617654bd5e..00000000000
--- a/libcc1/marshall-c.hh
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Marshalling and unmarshalling of C-specific types.
- 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_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 23756c44b5f..e921ab0d3a9 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 fb4e9a484d7..7fadbeaa5ac 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] 12+ messages in thread
* [PATCH 02/10] libcc1: use "override"
2021-01-03 18:26 [PATCH 00/10] C++11-based improvements for libcc1 Tom Tromey
2021-01-03 18:26 ` [PATCH 01/10] libcc1: use templates to unmarshall enums Tom Tromey
@ 2021-01-03 18:26 ` Tom Tromey
2021-01-03 18:26 ` [PATCH 03/10] libcc1: inline some simple methods Tom Tromey
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2021-01-03 18:26 UTC (permalink / raw)
To: gcc-patches; +Cc: Tom Tromey
This changes libcc1 to use "override" where appropriate.
libcc1/ChangeLog
2021-01-03 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 1838f2e5577..4fb3084c24c 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 e8aceb14604..5fa6a6742f5 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] 12+ messages in thread
* [PATCH 03/10] libcc1: inline some simple methods
2021-01-03 18:26 [PATCH 00/10] C++11-based improvements for libcc1 Tom Tromey
2021-01-03 18:26 ` [PATCH 01/10] libcc1: use templates to unmarshall enums Tom Tromey
2021-01-03 18:26 ` [PATCH 02/10] libcc1: use "override" Tom Tromey
@ 2021-01-03 18:26 ` Tom Tromey
2021-01-03 18:26 ` [PATCH 04/10] libcc1: delete copy constructor and assignment operators Tom Tromey
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2021-01-03 18:26 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-01-03 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 a91dfc8c5e2..01cda378613 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 f7cc5319a24..d8562a26154 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] 12+ messages in thread
* [PATCH 04/10] libcc1: delete copy constructor and assignment operators
2021-01-03 18:26 [PATCH 00/10] C++11-based improvements for libcc1 Tom Tromey
` (2 preceding siblings ...)
2021-01-03 18:26 ` [PATCH 03/10] libcc1: inline some simple methods Tom Tromey
@ 2021-01-03 18:26 ` Tom Tromey
2021-01-03 18:26 ` [PATCH 05/10] libcc1: use variadic templates for "call" Tom Tromey
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2021-01-03 18:26 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-01-03 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 e2d19b888b3..d3b06d9cf25 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 d8562a26154..1dc099902c8 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 f616124fabe..ef2527ae40b 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] 12+ messages in thread
* [PATCH 05/10] libcc1: use variadic templates for "call"
2021-01-03 18:26 [PATCH 00/10] C++11-based improvements for libcc1 Tom Tromey
` (3 preceding siblings ...)
2021-01-03 18:26 ` [PATCH 04/10] libcc1: delete copy constructor and assignment operators Tom Tromey
@ 2021-01-03 18:26 ` Tom Tromey
2021-01-03 18:26 ` [PATCH 06/10] libcc1: use variadic templates for "rpc" Tom Tromey
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2021-01-03 18:26 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-01-03 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 7fadbeaa5ac..d9d5d6cbc74 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 ef2527ae40b..322521274e6 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] 12+ messages in thread
* [PATCH 06/10] libcc1: use variadic templates for "rpc"
2021-01-03 18:26 [PATCH 00/10] C++11-based improvements for libcc1 Tom Tromey
` (4 preceding siblings ...)
2021-01-03 18:26 ` [PATCH 05/10] libcc1: use variadic templates for "call" Tom Tromey
@ 2021-01-03 18:26 ` Tom Tromey
2021-01-03 18:26 ` [PATCH 07/10] libcc1: use std::vector when building function types Tom Tromey
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2021-01-03 18:26 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-01-03 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 4fb3084c24c..82b1a6435b4 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 5fa6a6742f5..4fced736204 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] 12+ messages in thread
* [PATCH 07/10] libcc1: use std::vector when building function types
2021-01-03 18:26 [PATCH 00/10] C++11-based improvements for libcc1 Tom Tromey
` (5 preceding siblings ...)
2021-01-03 18:26 ` [PATCH 06/10] libcc1: use variadic templates for "rpc" Tom Tromey
@ 2021-01-03 18:26 ` Tom Tromey
2021-01-03 18:26 ` [PATCH 08/10] libcc1: add deleter objects Tom Tromey
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2021-01-03 18:26 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-01-03 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 a0fb61f2e46..aa07e6dbaef 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 648368353cb..d2700e24152 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] 12+ messages in thread
* [PATCH 08/10] libcc1: add deleter objects
2021-01-03 18:26 [PATCH 00/10] C++11-based improvements for libcc1 Tom Tromey
` (6 preceding siblings ...)
2021-01-03 18:26 ` [PATCH 07/10] libcc1: use std::vector when building function types Tom Tromey
@ 2021-01-03 18:26 ` Tom Tromey
2021-01-03 18:26 ` [PATCH 09/10] libcc1: add more uses of 'deleter' Tom Tromey
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2021-01-03 18:26 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-01-03 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 322521274e6..00f108d6dc9 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] 12+ messages in thread
* [PATCH 09/10] libcc1: add more uses of 'deleter'
2021-01-03 18:26 [PATCH 00/10] C++11-based improvements for libcc1 Tom Tromey
` (7 preceding siblings ...)
2021-01-03 18:26 ` [PATCH 08/10] libcc1: add deleter objects Tom Tromey
@ 2021-01-03 18:26 ` Tom Tromey
2021-01-03 18:26 ` [PATCH 10/10] libcc1: use unique_ptr more Tom Tromey
2021-01-03 23:43 ` [PATCH 00/10] C++11-based improvements for libcc1 Tom Tromey
10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2021-01-03 18:26 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-01-03 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 00000000000..70553eef8f8
--- /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 e921ab0d3a9..f3c1dbd43ea 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 368418a8215..5d2d3428a53 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 00f108d6dc9..f829e77682d 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] 12+ messages in thread
* [PATCH 10/10] libcc1: use unique_ptr more
2021-01-03 18:26 [PATCH 00/10] C++11-based improvements for libcc1 Tom Tromey
` (8 preceding siblings ...)
2021-01-03 18:26 ` [PATCH 09/10] libcc1: add more uses of 'deleter' Tom Tromey
@ 2021-01-03 18:26 ` Tom Tromey
2021-01-03 23:43 ` [PATCH 00/10] C++11-based improvements for libcc1 Tom Tromey
10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2021-01-03 18:26 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-01-03 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 82b1a6435b4..f79dac23137 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 4fced736204..b66ea524d34 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] 12+ messages in thread
* Re: [PATCH 00/10] C++11-based improvements for libcc1
2021-01-03 18:26 [PATCH 00/10] C++11-based improvements for libcc1 Tom Tromey
` (9 preceding siblings ...)
2021-01-03 18:26 ` [PATCH 10/10] libcc1: use unique_ptr more Tom Tromey
@ 2021-01-03 23:43 ` Tom Tromey
10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2021-01-03 23:43 UTC (permalink / raw)
To: Tom Tromey; +Cc: gcc-patches
>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:
Tom> This short series uses C++11 features to simplify libcc1. This brings
Tom> the code closer to how I pictured it when I first wrote it. (It would
Tom> be further improved by std::apply, but this isn't available until
Tom> C++17.)
I figured out today that it's possible to do this in C++11 -- just not
quite as convenient. So, once this series goes in, I have another
series lined up to simplify more things, including the "callback"
template functions.
Tom
^ permalink raw reply [flat|nested] 12+ messages in thread