Re: [PATCH] Use DW_TAG_module for Ada

2024-05-17 Thread Tom Tromey
>>>>> "Tom" == Tom Tromey  writes:

Tom> DWARF is not especially clear on the distinction between
Tom> DW_TAG_namespace and DW_TAG_module, but I think that DW_TAG_module is
Tom> more appropriate for Ada.  This patch changes the compiler to do this.
Tom> Note that the Ada compiler does not yet create NAMESPACE_DECLs.

Ping.

Tom


[PATCH] Use DW_TAG_module for Ada

2024-05-03 Thread Tom Tromey
DWARF is not especially clear on the distinction between
DW_TAG_namespace and DW_TAG_module, but I think that DW_TAG_module is
more appropriate for Ada.  This patch changes the compiler to do this.
Note that the Ada compiler does not yet create NAMESPACE_DECLs.

gcc

* dwarf2out.cc (gen_namespace_die): Use DW_TAG_module for Ada.
---
 gcc/dwarf2out.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 1b0e8b5a5b2..1e46c27cdf7 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -26992,7 +26992,7 @@ gen_namespace_die (tree decl, dw_die_ref context_die)
 {
   /* Output a real namespace or module.  */
   context_die = setup_namespace_context (decl, comp_unit_die ());
-  namespace_die = new_die (is_fortran () || is_dlang ()
+  namespace_die = new_die (is_fortran () || is_dlang () || is_ada ()
   ? DW_TAG_module : DW_TAG_namespace,
   context_die, decl);
   /* For Fortran modules defined in different CU don't add src coords.  */
-- 
2.44.0



Re: [RFC][PATCH v1 1/4] Documentation change

2024-04-19 Thread Tom Tromey
> Qing Zhao  writes:

> +The size of the union is as if the flexiable array member were omitted
> +except that it may have more trailing padding than the omission would imply.
> +
> +If all the members of a union are flexiable array member, the size of 

There's a couple of spots that say "flexiable" which should say "flexible".

thanks,
Tom


Re: [RFC 0/2] black, isort, and flake8 configuration

2024-04-04 Thread Tom Tromey
>>>>> "Tom" == Tom Tromey  writes:

Tom> This short series adds configuration files for black ("opinionated"
Tom> code formatter), isort (import sorter) and flake8 (Python lint) to
Tom> libstdc++.

Tom> I marked it as RFC since sometimes people don't like black's output.
Tom> In gdb we use it -- at first I found some of its decisions a little
Tom> odd, but overall it's nice not to have to review for or worry about
Tom> the minitia of code formatting.

FWIW in gdb we recently updated our .pre-commit-config.yaml to
automatically run all three of these tools.  What this means is that
it's now very easy for developers to ensure that the Python code in the
tree remains clean -- is correctly formatted, passes flake8 checking, etc.

The tool is opt-in but also extremely easy to use.

Anyway, if you're at all interested, I could refresh this series to
enable flake8 cleanliness and then add a .pre-commit-config.yaml as well.

thanks,
Tom


[PATCH] libiberty: Invoke D demangler when --format=auto

2024-03-30 Thread Tom Tromey
Investigating GDB PR d/31580 showed that the libiberty demangler
doesn't automatically demangle D mangled names.  However, I think it
should -- like C++ and Rust (new-style), D mangled names are readily
distinguished by the leading "_D", and so the likelihood of confusion
is low.  The other non-"auto" cases in this code are Ada (where the
encoded form could more easily be confused by ordinary programs) and
Java (which is long gone, but which also shared the C++ mangling and
thus was just an output style preference).

This patch also fixed another GDB bug, though of course that part
won't apply to the GCC repository.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31580
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30276

libiberty
* cplus-dem.c (cplus_demangle): Try the D demangler with
"auto" format.
* testsuite/d-demangle-expected: Add --format=auto test.
---
 gdb/testsuite/gdb.dlang/dlang-start-2.exp | 4 +---
 libiberty/cplus-dem.c | 2 +-
 libiberty/testsuite/d-demangle-expected   | 5 +
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/gdb/testsuite/gdb.dlang/dlang-start-2.exp 
b/gdb/testsuite/gdb.dlang/dlang-start-2.exp
index 4b3163ec97d..284f841b54a 100644
--- a/gdb/testsuite/gdb.dlang/dlang-start-2.exp
+++ b/gdb/testsuite/gdb.dlang/dlang-start-2.exp
@@ -79,10 +79,8 @@ if {[gdb_start_cmd] < 0} {
 return -1
 }
 
-# We should probably have "D main" instead of "_Dmain" here, filed PR30276
-# '[gdb/symtab] function name is _Dmain instead of "D main"' about that.
 gdb_test "" \
-"in _Dmain \\(\\)" \
+"in D main \\(\\)" \
 "start"
 
 gdb_test "show language" {"auto; currently d".}
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index 8b92946981f..ee9e84f5d6b 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -186,7 +186,7 @@ cplus_demangle (const char *mangled, int options)
   if (GNAT_DEMANGLING)
 return ada_demangle (mangled, options);
 
-  if (DLANG_DEMANGLING)
+  if (DLANG_DEMANGLING || AUTO_DEMANGLING)
 {
   ret = dlang_demangle (mangled, options);
   if (ret)
diff --git a/libiberty/testsuite/d-demangle-expected 
b/libiberty/testsuite/d-demangle-expected
index 47b059c4298..cfbdf2a52cb 100644
--- a/libiberty/testsuite/d-demangle-expected
+++ b/libiberty/testsuite/d-demangle-expected
@@ -1470,3 +1470,8 @@ demangle.anonymous
 --format=dlang
 _D8demangle9anonymous03fooZ
 demangle.anonymous.foo
+#
+# Test that 'auto' works.
+--format=auto
+_D8demangle9anonymous03fooZ
+demangle.anonymous.foo
-- 
2.43.0



Re: [PATCH v8 0/5] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2024-03-29 Thread Tom Tromey
> So, let’s delay the possible support to gdb in a later patch. 

> Does this sound reasonable to you?

It's not really up to me, but sure.  I was just curious if it perhaps
already worked, but not enough to apply the patches and find out.

Tom


Re: [PATCH v8 0/5] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2024-03-29 Thread Tom Tromey
Kees> Does DWARF have such an annotation? Regardless, I think this could be a
Kees> future patch to not hold up landing the initial feature.

Sure, the compiler can emit the array length (and structure size) as a
DWARF expression using the length.

Tom


Re: [PATCH v8 0/5] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2024-03-29 Thread Tom Tromey
> Qing Zhao  writes:

> This is the 8th version of the patch.

> compare with the 7th version, the difference are:

[...]

Hi.  I was curious to know if the information supplied by this attribute
shows up in the DWARF.  It would be good if it did, because that would
let gdb correctly print these arrays without user intervention.

Tom


[PATCH] Prettify output of debug_dwarf_die

2024-03-28 Thread Tom Tromey
When debugging gcc, I tried calling debug_dwarf_die and I saw this
output:

  DW_AT_location: location descriptor:
(0x7fffe9c2e870) DW_OP_dup 0, 0
(0x7fffe9c2e8c0) DW_OP_bra location descriptor (0x7fffe9c2e640)
, 0
(0x7fffe9c2e820) DW_OP_lit4 4, 0
(0x7fffe9c2e910) DW_OP_skip location descriptor (0x7fffe9c2e9b0)
, 0
(0x7fffe9c2e640) DW_OP_dup 0, 0

I think those ", 0" should not appear on their own lines.  The issue
seems to be that print_dw_val should not generally emit a newline,
except when recursing.

gcc/ChangeLog

* dwarf2out.cc (print_dw_val) : Don't
print newline when not recursing.
---
 gcc/dwarf2out.cc | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 8f18bc4fe64..1b0e8b5a5b2 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -6651,7 +6651,7 @@ print_dw_val (dw_val_node *val, bool recurse, FILE 
*outfile)
 case dw_val_class_loc:
   fprintf (outfile, "location descriptor");
   if (val->v.val_loc == NULL)
-   fprintf (outfile, " -> \n");
+   fprintf (outfile, " -> ");
   else if (recurse)
{
  fprintf (outfile, ":\n");
@@ -6662,9 +6662,9 @@ print_dw_val (dw_val_node *val, bool recurse, FILE 
*outfile)
   else
{
  if (flag_dump_noaddr || flag_dump_unnumbered)
-   fprintf (outfile, " #\n");
+   fprintf (outfile, " #");
  else
-   fprintf (outfile, " (%p)\n", (void *) val->v.val_loc);
+   fprintf (outfile, " (%p)", (void *) val->v.val_loc);
}
   break;
 case dw_val_class_loc_list:
-- 
2.43.0



Re: [PATCH] Revert "Pass GUILE down to subdirectories"

2024-03-22 Thread Tom Tromey
> "Andrew" == Andrew Burgess  writes:

Andrew> Thanks, that would be great, and would certainly fix the build problems
Andrew> I see.

I'm going to check it in to binutils-gdb in a minute.

For those reading on gcc-patches, please consider this a ping of the
patch.

thanks,
Tom


Re: [PATCH] Revert "Pass GUILE down to subdirectories"

2024-03-08 Thread Tom Tromey
> "Andrew" == Andrew Burgess  writes:

Andrew> After once again forgetting to add GUILE=guile2.2 to my GDB build I was
Andrew> thinking about this issue again.

Andrew> Given that GDB has a --with-guile=... configure option, and that our
Andrew> configure scripts try to identify a matching version of guild and a
Andrew> shared library to link GDB against, I wondered why we don't just force
Andrew> the use of a matching version of guile.

Andrew> I guess I'm suggesting that for building GDB's guile components we
Andrew> should respect either the --with-guile=... configure option, or what the
Andrew> configure script auto-detected, and should not be picking up any build
Andrew> time GUILE=... flag -- setting GUILE=... isn't going to change the
Andrew> version of guild used, nor is it going to change the shared library that
Andrew> GDB links against, so just changing the guile version seems like a
Andrew> recipe for incompatibility problems.

Andrew> Below is a patch that forces GDB to compile our guile scripts using a
Andrew> suitable version of guile.  This could be applied irrespective of
Andrew> whether you revert b7e5a29602143b53267efcd9c8d5ecc78cd5a62f or not.

Andrew> What do you think?

I have no issue with this.  If it helps you, you should do it.

FWIW I was waiting for a response from you before reverting this change.
https://sourceware.org/pipermail/gdb-patches/2024-February/206507.html


Overall I think that we really should revert my change.

cgen isn't run commonly enough to warrant the change breaking literally
anything else.  And, part of this is on cgen for not coming with any
kind of script for running it ... actually looking under the hood has
really soured me on cgen entirely.

The guild #! prologue also seems like an obvious bug to me.  However
it's perhaps too late to fix this in any useful way.

Tom


Re: [PATCH 1/3] Change 'v1' float and int code to fall back to v0

2024-02-29 Thread Tom Tromey
> "Jeff" == Jeff Law  writes:

>> I don't know how to fix this.

Jeff> Me neither, but I can suggest a hacky workaround.

FTR, I asked Jakub on irc and he fixed it, so thankfully I didn't have
to resort to the hack :-)

thanks,
Tom


Re: [PATCH 1/3] Change 'v1' float and int code to fall back to v0

2024-02-28 Thread Tom Tromey
> "Andrew" == Andrew Pinski  writes:

Andrew> I don't know how to update the script server side after it is
Andrew> committed in git. the checker script is located in git though:

Thanks, I didn't realize it was there.

Could you check in your patch?
IMO it seems obvious.

Tom


Re: [PATCH 1/3] Change 'v1' float and int code to fall back to v0

2024-02-28 Thread Tom Tromey
> "Jeff" == Jeff Law  writes:

Jeff> Given this is all libcc1 related and thus primarily of interest to
Jeff> gdb, if you're happy with it, then it's OK for the trunk.

Thank you.

I could not push this because:

remote: *** ChangeLog format failed:
remote: *** ERR: invalid PR component in subject: "Fix PR libcc1/113977"

I guess this script isn't in sync with the components in bugzilla.

I don't know how to fix this.

Tom


[PATCH 3/3] Fix PR libcc1/113977

2024-02-26 Thread Tom Tromey
PR libcc1/113977 points out a case where a simple expression is
rejected with a compiler error message.  The bug here is that gdb does
not inform the plugin of the correct alignment -- in fact, there is no
way to do that.

This patch adds a new method to allow the alignment to be set, and
bumps the C front end protocol version.

It also includes some updates to various comments in 'include', done
here to simplify the merge to binutils-gdb.

include/ChangeLog
2024-02-26  Tom Tromey  

* gcc-cp-interface.h (gcc_cp_fe_context_function): Update
comment.
* gcc-c-interface.h (enum gcc_c_api_version) :
New constant.
(gcc_c_fe_context_function): Update comment.
* gcc-c-fe.def (finish_record_with_alignment): New method.
Update documentation.

libcc1/ChangeLog
2024-02-26  Tom Tromey  

PR libcc1/113977
* libcc1plugin.cc (plugin_finish_record_or_union): New function.
(plugin_finish_record_or_union): Rewrite.
(plugin_init): Use GCC_C_FE_VERSION_2.
* libcc1.cc (c_vtable): Use GCC_C_FE_VERSION_2.
(gcc_c_fe_context): Check for GCC_C_FE_VERSION_2.
---
 include/ChangeLog  | 10 ++
 include/gcc-c-fe.def   | 13 -
 include/gcc-c-interface.h  | 11 +--
 include/gcc-cp-interface.h |  6 +-
 libcc1/ChangeLog   |  9 +
 libcc1/libcc1.cc   |  5 +++--
 libcc1/libcc1plugin.cc | 26 ++
 7 files changed, 66 insertions(+), 14 deletions(-)

diff --git a/include/ChangeLog b/include/ChangeLog
index 8bfaec6faa1..4c8b5b28039 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,13 @@
+2024-02-26  Tom Tromey  
+
+   * gcc-cp-interface.h (gcc_cp_fe_context_function): Update
+   comment.
+   * gcc-c-interface.h (enum gcc_c_api_version) :
+   New constant.
+   (gcc_c_fe_context_function): Update comment.
+   * gcc-c-fe.def (finish_record_with_alignment): New method.
+   Update documentation.
+
 2024-01-13  Jakub Jelinek  
 
* demangle.h (enum demangle_component_type): Add
diff --git a/include/gcc-c-fe.def b/include/gcc-c-fe.def
index 36a765484a7..cb7cf197525 100644
--- a/include/gcc-c-fe.def
+++ b/include/gcc-c-fe.def
@@ -89,7 +89,10 @@ GCC_METHOD5 (int /* bool */, build_add_field,
 
 /* After all the fields have been added to a struct or union, the
struct or union type must be "finished".  This does some final
-   cleanups in GCC.  */
+   cleanups in GCC.
+
+   Note that when using GCC_C_FE_VERSION_2, it is preferable to call
+   finish_record_with_alignment instead.  */
 
 GCC_METHOD2 (int /* bool */, finish_record_or_union,
 gcc_type, /* Argument RECORD_OR_UNION_TYPE. */
@@ -220,3 +223,11 @@ GCC_METHOD2 (gcc_type, float_type,
 unsigned long,/* Argument SIZE_IN_BYTES.  */
 const char *) /* Argument BUILTIN_NAME.  */
 
+/* New in GCC_FE_VERSION_2.  Like finish_record_or_union but the caller also
+   supplies the alignment.  If the alignment is 0, this acts identically to
+   finish_record_or_union.  */
+
+GCC_METHOD3 (int /* bool */, finish_record_with_alignment,
+gcc_type, /* Argument RECORD_OR_UNION_TYPE. */
+unsigned long,/* Argument SIZE_IN_BYTES.  */
+unsigned long)/* Argument ALIGNMENT.  */
diff --git a/include/gcc-c-interface.h b/include/gcc-c-interface.h
index feece1e38a2..700d7483a4a 100644
--- a/include/gcc-c-interface.h
+++ b/include/gcc-c-interface.h
@@ -45,7 +45,10 @@ enum gcc_c_api_version
 
   /* Added char_type.  Added new version of int_type and float_type,
  deprecated int_type_v0 and float_type_v0.  */
-  GCC_C_FE_VERSION_1 = 1
+  GCC_C_FE_VERSION_1 = 1,
+
+  /* Added finish_record_with_alignment method.  */
+  GCC_C_FE_VERSION_2 = 2,
 };
 
 /* Qualifiers.  */
@@ -198,7 +201,11 @@ struct gcc_c_context
 /* The type of the initialization function.  The caller passes in the
desired base version and desired C-specific version.  If the
request can be satisfied, a compatible gcc_context object will be
-   returned.  Otherwise, the function returns NULL.  */
+   returned.  In particular, this may return a context object with a higher
+   actual version number than was requested, provided the higher version is
+   fully compatible.  (As of GCC_C_FE_VERSION_2, this is always true.)
+
+   Otherwise, the function returns NULL.  */
 
 typedef struct gcc_c_context *gcc_c_fe_context_function
 (enum gcc_base_api_version,
diff --git a/include/gcc-cp-interface.h b/include/gcc-cp-interface.h
index 2f950729b9b..15b911cb216 100644
--- a/include/gcc-cp-interface.h
+++ b/include/gcc-cp-interface.h
@@ -483,7 +483,11 @@ struct gcc_cp_context
 /* The type of the initialization function.  The caller passes in the
desired base version and desired C-specific version.  If the
request can be satisfied, a 

[PATCH 2/3] Fix version negotiation in libcc1 plugins

2024-02-26 Thread Tom Tromey
This fixes version negotiation in the libcc1 plugins.  It's done in a
simple way: the version number from the context object is now passed
to base_gdb_plugin.

The idea behind this is that when the client (gdb) requests version N,
the plugin should respond with the newest version that it knows of
that is backward compatible to N.  That is, the connection can be
upgraded.  Note that the protocol does not change much, and no
backward incompatibilities have ever been needed.

The C plugin is also changed to advertise GCC_C_FE_VERSION_1.

The version negotiation approach should of course be documented, but I
did that in a subsequent patch, in order to only have one patch
touching the 'include' directory and thus needing a merge to
binutils-gdb.

2024-02-26  Tom Tromey  

* libcp1.cc (libcp1::libcp1): Use FE version number from context.
* libcc1.cc (libcc1::libcc1): Use FE version number from context.
(c_vtable): Use GCC_C_FE_VERSION_1.
---
 libcc1/ChangeLog | 6 ++
 libcc1/libcc1.cc | 4 ++--
 libcc1/libcp1.cc | 2 +-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/libcc1/ChangeLog b/libcc1/ChangeLog
index b0b31ee6586..b4072574ba8 100644
--- a/libcc1/ChangeLog
+++ b/libcc1/ChangeLog
@@ -1,3 +1,9 @@
+2024-02-26  Tom Tromey  
+
+   * libcp1.cc (libcp1::libcp1): Use FE version number from context.
+   * libcc1.cc (libcc1::libcc1): Use FE version number from context.
+   (c_vtable): Use GCC_C_FE_VERSION_1.
+
 2024-02-26  Tom Tromey  
 
* libcc1plugin.cc (safe_lookup_builtin_type): Handle ERROR_MARK.
diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index 8d4ddc5ddfe..992181e8fdc 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -54,7 +54,7 @@ struct libcc1 : public 
cc1_plugin::base_gdb_plugin
 libcc1::libcc1 (const gcc_c_fe_vtable *cv)
   : cc1_plugin::base_gdb_plugin ("libcc1plugin",
C_COMPILER_NAME,
-   GCC_C_FE_VERSION_1)
+   cv->c_version)
 {
   c_ops = cv;
 }
@@ -108,7 +108,7 @@ set_callbacks (struct gcc_c_context *s,
 
 static const struct gcc_c_fe_vtable c_vtable =
 {
-  GCC_C_FE_VERSION_0,
+  GCC_C_FE_VERSION_1,
   set_callbacks,
 
 #define GCC_METHOD0(R, N) \
diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc
index ec3eec2c606..cc2915d30af 100644
--- a/libcc1/libcp1.cc
+++ b/libcc1/libcp1.cc
@@ -55,7 +55,7 @@ struct libcp1 : public 
cc1_plugin::base_gdb_plugin
 libcp1::libcp1 (const gcc_cp_fe_vtable *cv)
   : cc1_plugin::base_gdb_plugin ("libcp1plugin",
 CP_COMPILER_NAME,
-GCC_CP_FE_VERSION_0)
+cv->cp_version)
 {
   cp_ops = cv;
 }

-- 
2.43.0



[PATCH 1/3] Change 'v1' float and int code to fall back to v0

2024-02-26 Thread Tom Tromey
While working on another patch, I discovered that the libcc1 plugin
code never did version negotiation correctly.  So, the patches to
introduce v1 never did anything -- the new code, as far as I know, has
never been run.

Making version negotiation work shows that the existing code causes
crashes.  For example, safe_lookup_builtin_type might return
error_mark_node in some cases, which the callers aren't prepared to
accept.

Looking into it some more, I couldn't find any justification for this
v1 code for the C compiler plugin.  Since it's not run at all, it's
also clear that removing it doesn't cause any regressions in gdb.

However, rather than remove it, this patch changes it to handle
ERROR_MARK better, and then to fall back to the v0 code if the new
code fails to find the type it's looking for.

2024-02-26  Tom Tromey  

* libcc1plugin.cc (safe_lookup_builtin_type): Handle ERROR_MARK.
(plugin_int_type): Fall back to plugin_int_type_v0.
(plugin_float_type): Fall back to plugin_float_type_v0.
---
 libcc1/ChangeLog   |  6 ++
 libcc1/libcc1plugin.cc | 19 ++-
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/libcc1/ChangeLog b/libcc1/ChangeLog
index f81fe389e71..b0b31ee6586 100644
--- a/libcc1/ChangeLog
+++ b/libcc1/ChangeLog
@@ -1,3 +1,9 @@
+2024-02-26  Tom Tromey  
+
+   * libcc1plugin.cc (safe_lookup_builtin_type): Handle ERROR_MARK.
+   (plugin_int_type): Fall back to plugin_int_type_v0.
+   (plugin_float_type): Fall back to plugin_float_type_v0.
+
 2024-02-09  Marek Polacek  
 
PR c++/98388
diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc
index 00d3963029d..f1082d8e9d3 100644
--- a/libcc1/libcc1plugin.cc
+++ b/libcc1/libcc1plugin.cc
@@ -555,7 +555,7 @@ safe_lookup_builtin_type (const char *builtin_name)
 
   gcc_assert (TREE_CODE (result) == TYPE_DECL);
   result = TREE_TYPE (result);
-  return result;
+  return TREE_CODE (result) == ERROR_MARK ? nullptr : result;
 }
 
 static gcc_type
@@ -592,13 +592,14 @@ plugin_int_type (cc1_plugin::connection *self,
 int is_unsigned, unsigned long size_in_bytes,
 const char *builtin_name)
 {
-  if (!builtin_name)
-return plugin_int_type_v0 (self, is_unsigned, size_in_bytes);
-
-  tree result = safe_lookup_builtin_type (builtin_name);
-  gcc_assert (!result || TREE_CODE (result) == INTEGER_TYPE);
-
-  return plugin_int_check (self, is_unsigned, size_in_bytes, result);
+  if (builtin_name != nullptr)
+{
+  tree result = safe_lookup_builtin_type (builtin_name);
+  gcc_assert (!result || TREE_CODE (result) == INTEGER_TYPE);
+  if (result != nullptr)
+   return plugin_int_check (self, is_unsigned, size_in_bytes, result);
+}
+  return plugin_int_type_v0 (self, is_unsigned, size_in_bytes);
 }
 
 gcc_type
@@ -631,7 +632,7 @@ plugin_float_type (cc1_plugin::connection *self,
   tree result = safe_lookup_builtin_type (builtin_name);
 
   if (!result)
-return convert_out (error_mark_node);
+return plugin_float_type_v0 (self, size_in_bytes);
 
   gcc_assert (SCALAR_FLOAT_TYPE_P (result));
   gcc_assert (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (result));

-- 
2.43.0



[PATCH 0/3] Fix libcc1 failure

2024-02-26 Thread Tom Tromey
This started as a patch to fix the libcc1 failure pointed out in
PR libcc1/113977.  However, investigating that pointed out some other
issues, which are also fixed in this series.

I tested this on x86-64 Fedora 38 against two versions of gdb: one
patched to fix the gdb side of the bug, and one that was not.  In both
cases gdb's "gdb.compile" tests were run.

---
Tom Tromey (3):
  Change 'v1' float and int code to fall back to v0
  Fix version negotiation in libcc1 plugins
  Fix PR libcc1/113977

 include/ChangeLog  | 10 ++
 include/gcc-c-fe.def   | 13 -
 include/gcc-c-interface.h  | 11 +--
 include/gcc-cp-interface.h |  6 +-
 libcc1/ChangeLog   | 21 +
 libcc1/libcc1.cc   |  7 ---
 libcc1/libcc1plugin.cc | 45 -
 libcc1/libcp1.cc   |  2 +-
 8 files changed, 90 insertions(+), 25 deletions(-)
---
base-commit: 1e2a3b278d7770db6b5ca869756b1375fc3a77d6
change-id: 20240226-gdb-compile-align-f31c69137d6a

Best regards,
-- 
Tom Tromey 



Re: [PATCH] Revert "Pass GUILE down to subdirectories"

2024-02-10 Thread Tom Tromey
>>>>> "Andrew" == Andrew Burgess  writes:

Andrew> Tom Tromey  writes:
>> This reverts commit b7e5a29602143b53267efcd9c8d5ecc78cd5a62f.
>> 
>> This patch caused problems for some users when building gdb, because
>> it would cause 'guild' to be invoked with the wrong versin of guile.
>> On the whole it seems simpler to just back this out.
>> 
>> * Makefile.in: Rebuild.
>> * Makefile.tpl (BASE_EXPORTS): Remove GUILE.
>> (GUILE): Remove.
>> * Makefile.def (flags_to_pass): Remove GUILE.

Andrew> Is it going to be possible to merge this with GCC in stage 4?  Would be
Andrew> super useful if we could as this is still causing problems.

We can always check it in to gdb now and then to gcc at some later date.
If that sounds ok to you, I'll go ahead & do it.

thanks,
Tom


[PATCH] Revert "Pass GUILE down to subdirectories"

2024-01-22 Thread Tom Tromey
This reverts commit b7e5a29602143b53267efcd9c8d5ecc78cd5a62f.

This patch caused problems for some users when building gdb, because
it would cause 'guild' to be invoked with the wrong versin of guile.
On the whole it seems simpler to just back this out.

* Makefile.in: Rebuild.
* Makefile.tpl (BASE_EXPORTS): Remove GUILE.
(GUILE): Remove.
* Makefile.def (flags_to_pass): Remove GUILE.
---
 Makefile.def | 1 -
 Makefile.in  | 8 ++--
 Makefile.tpl | 7 ++-
 3 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/Makefile.def b/Makefile.def
index 19954e7d731..c8c80af3657 100644
--- a/Makefile.def
+++ b/Makefile.def
@@ -312,7 +312,6 @@ flags_to_pass = { flag= GNATBIND ; };
 flags_to_pass = { flag= GNATMAKE ; };
 flags_to_pass = { flag= GDC ; };
 flags_to_pass = { flag= GDCFLAGS ; };
-flags_to_pass = { flag= GUILE ; };
 
 // Target tools
 flags_to_pass = { flag= AR_FOR_TARGET ; };
diff --git a/Makefile.in b/Makefile.in
index edb0c8a9a42..245dd610b53 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -3,7 +3,7 @@
 #
 # Makefile for directory with subdirs to build.
 #   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-#   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 
2011, 2023
+#   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 
2011
 #   Free Software Foundation
 #
 # This file is free software; you can redistribute it and/or modify
@@ -143,8 +143,7 @@ BASE_EXPORTS = \
M4="$(M4)"; export M4; \
SED="$(SED)"; export SED; \
AWK="$(AWK)"; export AWK; \
-   MAKEINFO="$(MAKEINFO)"; export MAKEINFO; \
-   GUILE="$(GUILE)"; export GUILE;
+   MAKEINFO="$(MAKEINFO)"; export MAKEINFO;
 
 # This is the list of variables to export in the environment when
 # configuring subdirectories for the build system.
@@ -452,8 +451,6 @@ GM2FLAGS = $(CFLAGS)
 
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 
-GUILE = guile
-
 # Pass additional PGO and LTO compiler options to the PGO build.
 BUILD_CFLAGS = $(PGO_BUILD_CFLAGS) $(PGO_BUILD_LTO_CFLAGS)
 override CFLAGS += $(BUILD_CFLAGS)
@@ -886,7 +883,6 @@ BASE_FLAGS_TO_PASS = \
"GNATMAKE=$(GNATMAKE)" \
"GDC=$(GDC)" \
"GDCFLAGS=$(GDCFLAGS)" \
-   "GUILE=$(GUILE)" \
"AR_FOR_TARGET=$(AR_FOR_TARGET)" \
"AS_FOR_TARGET=$(AS_FOR_TARGET)" \
"CC_FOR_TARGET=$(CC_FOR_TARGET)" \
diff --git a/Makefile.tpl b/Makefile.tpl
index adbcbdd1d57..6e22adecd2f 100644
--- a/Makefile.tpl
+++ b/Makefile.tpl
@@ -6,7 +6,7 @@ in
 #
 # Makefile for directory with subdirs to build.
 #   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-#   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 
2011, 2023
+#   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 
2011
 #   Free Software Foundation
 #
 # This file is free software; you can redistribute it and/or modify
@@ -146,8 +146,7 @@ BASE_EXPORTS = \
M4="$(M4)"; export M4; \
SED="$(SED)"; export SED; \
AWK="$(AWK)"; export AWK; \
-   MAKEINFO="$(MAKEINFO)"; export MAKEINFO; \
-   GUILE="$(GUILE)"; export GUILE;
+   MAKEINFO="$(MAKEINFO)"; export MAKEINFO;
 
 # This is the list of variables to export in the environment when
 # configuring subdirectories for the build system.
@@ -455,8 +454,6 @@ GM2FLAGS = $(CFLAGS)
 
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 
-GUILE = guile
-
 # Pass additional PGO and LTO compiler options to the PGO build.
 BUILD_CFLAGS = $(PGO_BUILD_CFLAGS) $(PGO_BUILD_LTO_CFLAGS)
 override CFLAGS += $(BUILD_CFLAGS)
-- 
2.43.0



Re: [PATCH] Pass GUILE down to subdirectories

2024-01-22 Thread Tom Tromey
Eric> I mean, I've been trying to figure out how to re-run cgen myself, to
Eric> regenerate some cgen-erated files in libopcodes to fix some compiler
Eric> warnings in them, but it's pretty hard to do so; I'd really appreciate
Eric> it if the whole process of regenerating files with cgen could be made
Eric> easy and well-documented and understandable...

Yeah.  Unfortunately cgen seems fairly unmaintained and guile still
seems a bit clunky to use somehow (or maybe it's packaged strangely, I
don't know).

After some patches of mine to let cgen use the guile compiler, it
requires guile 3.0 (at least for me, guile 2 dies while trying to run
it).  So what I do is:

* cd binutils-gdb
* ln -s /path/to/cgen
* configure a new directory with --enable-cgen-maint
* make GUILE=guile3.0

Tom


Re: [PATCH] Pass GUILE down to subdirectories

2024-01-18 Thread Tom Tromey
Andrew> This change is causing some problems for me.

Yeah, Tom de Vries as well.

Andrew> One of my build machines has 2 versions of guile installed.  One is
Andrew> guile 2.0.14 and the other is guile 2.2.21.

Andrew> When GDB configures itself the configure script figures out that it
Andrew> should use 2.2.21 to compile the guile libraries that GDB uses.

Andrew> However, when we actually build the guile libraries we do use guild2.2,
Andrew> but due to this 'GUILE = guile' line, guild2.2 uses guile 2.0.14 in
Andrew> order to perform the compile (I guess, I don't know the details of how
Andrew> guile compilation works).

Andrew> Unfortunately guile 2.0.14 compiles in a way which is not compatible
Andrew> with how GDB then tries to load the guile library.

I consider this a bug in guile -- it installs 'guild' with this:

#!/usr/bin/sh
# -*- scheme -*-
exec ${GUILE:-/usr/bin/guile2.2} $GUILE_FLAGS -e '(@@ (guild) main)' -s 
"$0" "$@"
!#

Allowing a system script to pick $GUILE here seems weird, especially for
a versioned install of "guild", where as you can see it already knows
the correct guile to use.

However -- I think it's better to just work around this.
I plan to back out this change.  Anyone needing to re-run cgen (which
itself ought to come with smarts here, but since it is un-maintained...)
can just specify this by hand.  I.e., the status quo ante.

I'll try to send a patch tomorrow.

Tom


[PATCH] Pass GUILE down to subdirectories

2023-12-30 Thread Tom Tromey
When I enable cgen rebuilding in the binutils-gdb tree, the default is
to run cgen using 'guile'.  However, on my host, guile is guile 2.2,
which doesn't work for me -- I have to use guile3.0.

This patch arranges to pass "GUILE" down to subdirectories, so I can
use 'make GUILE=guile3.0'.

ChangeLog
2023-12-30  Tom Tromey  

* Makefile.in: Rebuild.
* Makefile.tpl (BASE_EXPORTS): Add GUILE.
(GUILE): New variable.
* Makefile.def (flags_to_pass): Add GUILE.
---
 ChangeLog| 7 +++
 Makefile.def | 1 +
 Makefile.in  | 8 ++--
 Makefile.tpl | 7 +--
 4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/Makefile.def b/Makefile.def
index 662e50fdc18..792919e561c 100644
--- a/Makefile.def
+++ b/Makefile.def
@@ -310,6 +310,7 @@ flags_to_pass = { flag= GNATBIND ; };
 flags_to_pass = { flag= GNATMAKE ; };
 flags_to_pass = { flag= GDC ; };
 flags_to_pass = { flag= GDCFLAGS ; };
+flags_to_pass = { flag= GUILE ; };
 
 // Target tools
 flags_to_pass = { flag= AR_FOR_TARGET ; };
diff --git a/Makefile.in b/Makefile.in
index 48320bb549e..9a58d5a4f20 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -3,7 +3,7 @@
 #
 # Makefile for directory with subdirs to build.
 #   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-#   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 
2011
+#   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 
2011, 2023
 #   Free Software Foundation
 #
 # This file is free software; you can redistribute it and/or modify
@@ -143,7 +143,8 @@ BASE_EXPORTS = \
M4="$(M4)"; export M4; \
SED="$(SED)"; export SED; \
AWK="$(AWK)"; export AWK; \
-   MAKEINFO="$(MAKEINFO)"; export MAKEINFO;
+   MAKEINFO="$(MAKEINFO)"; export MAKEINFO; \
+   GUILE="$(GUILE)"; export GUILE;
 
 # This is the list of variables to export in the environment when
 # configuring subdirectories for the build system.
@@ -450,6 +451,8 @@ GM2FLAGS = $(CFLAGS)
 
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 
+GUILE = guile
+
 # Pass additional PGO and LTO compiler options to the PGO build.
 BUILD_CFLAGS = $(PGO_BUILD_CFLAGS) $(PGO_BUILD_LTO_CFLAGS)
 override CFLAGS += $(BUILD_CFLAGS)
@@ -878,6 +881,7 @@ BASE_FLAGS_TO_PASS = \
"GNATMAKE=$(GNATMAKE)" \
"GDC=$(GDC)" \
"GDCFLAGS=$(GDCFLAGS)" \
+   "GUILE=$(GUILE)" \
"AR_FOR_TARGET=$(AR_FOR_TARGET)" \
"AS_FOR_TARGET=$(AS_FOR_TARGET)" \
"CC_FOR_TARGET=$(CC_FOR_TARGET)" \
diff --git a/Makefile.tpl b/Makefile.tpl
index 36fa20950d4..17e585df541 100644
--- a/Makefile.tpl
+++ b/Makefile.tpl
@@ -6,7 +6,7 @@ in
 #
 # Makefile for directory with subdirs to build.
 #   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-#   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 
2011
+#   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 
2011, 2023
 #   Free Software Foundation
 #
 # This file is free software; you can redistribute it and/or modify
@@ -146,7 +146,8 @@ BASE_EXPORTS = \
M4="$(M4)"; export M4; \
SED="$(SED)"; export SED; \
AWK="$(AWK)"; export AWK; \
-   MAKEINFO="$(MAKEINFO)"; export MAKEINFO;
+   MAKEINFO="$(MAKEINFO)"; export MAKEINFO; \
+   GUILE="$(GUILE)"; export GUILE;
 
 # This is the list of variables to export in the environment when
 # configuring subdirectories for the build system.
@@ -453,6 +454,8 @@ GM2FLAGS = $(CFLAGS)
 
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 
+GUILE = guile
+
 # Pass additional PGO and LTO compiler options to the PGO build.
 BUILD_CFLAGS = $(PGO_BUILD_CFLAGS) $(PGO_BUILD_LTO_CFLAGS)
 override CFLAGS += $(BUILD_CFLAGS)
-- 
2.43.0



Re: [PATCH] Add some new DW_IDX_* constants

2023-12-10 Thread Tom Tromey
> "Jakub" == Jakub Jelinek  writes:

Jakub> LGTM for GCC (but it needs a ChangeLog entry).

Oops, yeah -- I am out of the habit of writing those.
I'll add one before I push this.

Tom


[PATCH] Add some new DW_IDX_* constants

2023-12-09 Thread Tom Tromey
I've reimplemented the .debug_names code in GDB -- it was quite far
from being correct, and the new implementation is much closer to what
is specified by DWARF.

However, the new writer in GDB needs to emit some symbol properties,
so that the reader can be fully functional.  This patch adds a few new
DW_IDX_* constants, and tries to document the existing extensions as
well.  (My patch series add more documentation of these to the GDB
manual as well.)
---
 include/dwarf2.def | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/dwarf2.def b/include/dwarf2.def
index 7ab3ee611fd4..75b75d901884 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -802,8 +802,17 @@ DW_IDX (DW_IDX_parent, 4)
 DW_IDX (DW_IDX_type_hash, 5)
 DW_IDX_DUP (DW_IDX_lo_user, 0x2000)
 DW_IDX (DW_IDX_hi_user, 0x3fff)
+/* Internal linkage.  A flag.  */
 DW_IDX (DW_IDX_GNU_internal, 0x2000)
+/* External linkage.  A flag.  Note that gdb no longer generates this;
+   the default is to assume external linkage.  */
 DW_IDX (DW_IDX_GNU_external, 0x2001)
+/* This entry is the program's entry point.  A flag.  */
+DW_IDX (DW_IDX_GNU_main, 0x2002)
+/* Language for this entry.  A DW_LANG_* value.  */
+DW_IDX (DW_IDX_GNU_language, 0x2003)
+/* This entry is a linkage name.  A flag.  */
+DW_IDX (DW_IDX_GNU_linkage_name, 0x2004)
 DW_END_IDX
 
 /* DWARF5 Unit type header encodings  */
-- 
2.43.0



Re: [PATCH] gettext: disable install, docs targets, libasprintf, threads

2023-12-04 Thread Tom Tromey
> "Arsen" == Arsen Arsenović  writes:

Arsen> Thanks.  I'll wait for the Binutils and GDB maintainers to weigh in
Arsen> before pushing (plus, I can't push there).

Seems fine to me.  Thank you.

Tom


[PATCH] Fix crash in libcc1

2023-11-14 Thread Tom Tromey
The gdb tests of the libcc1 plugin have been failing lately.  I
tracked this down to a crash trying to access an enum's underlying
type.  This patch fixes the crash by setting this type.

libcc1/ChangeLog

* libcc1plugin.cc (plugin_build_enum_type): Set
ENUM_UNDERLYING_TYPE.
---
 libcc1/libcc1plugin.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc
index 283eaf206850..34dcd89b1b33 100644
--- a/libcc1/libcc1plugin.cc
+++ b/libcc1/libcc1plugin.cc
@@ -454,6 +454,7 @@ plugin_build_enum_type (cc1_plugin::connection *self,
 
   TYPE_PRECISION (result) = TYPE_PRECISION (underlying_int_type);
   TYPE_UNSIGNED (result) = TYPE_UNSIGNED (underlying_int_type);
+  ENUM_UNDERLYING_TYPE (result) = underlying_int_type;
 
   plugin_context *ctx = static_cast (self);
   return convert_out (ctx->preserve (result));
-- 
2.41.0



[RFC 1/2] libstdc++: Use 'black' and 'isort' in pretty printers

2023-10-04 Thread Tom Tromey
This changes libstdc++ to use the 'black' Python formatter.  This
formatter is somewhat standard and fairly comprehensive.  FWIW we use
this in gdb, mainly because it means we don't have to review Python
code for formatting style.

This patch also runs 'isort', which handles sorting the imports.

A new pyproject.tom file is added, so after this you can:

cd .../libstdc++/python
black .
isort .

... and have any changes reformatted.

libstdc++-v3/ChangeLog:
* pyproject.toml: New file.
* python/libstdcxx/v6/printers.py: Reformat.
* python/libstdcxx/v6/xmethods.py: Reformat.
* python/libstdcxx/v6/__init__.py: Reformat.
---
 libstdc++-v3/python/libstdcxx/v6/__init__.py |   5 +
 libstdc++-v3/python/libstdcxx/v6/printers.py | 834 ---
 libstdc++-v3/python/libstdcxx/v6/xmethods.py | 138 +--
 libstdc++-v3/python/pyproject.toml   |   6 +
 4 files changed, 648 insertions(+), 335 deletions(-)
 create mode 100644 libstdc++-v3/python/pyproject.toml

diff --git a/libstdc++-v3/python/libstdcxx/v6/__init__.py 
b/libstdc++-v3/python/libstdcxx/v6/__init__.py
index 8b2cbc60a1b..cb0abf38e6b 100644
--- a/libstdc++-v3/python/libstdcxx/v6/__init__.py
+++ b/libstdc++-v3/python/libstdcxx/v6/__init__.py
@@ -13,19 +13,24 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see .
 
+
 # Load the xmethods if GDB supports them.
 def gdb_has_xmethods():
 try:
 import gdb.xmethod
+
 return True
 except ImportError:
 return False
 
+
 def register_libstdcxx_printers(obj):
 # Load the pretty-printers.
 from .printers import register_libstdcxx_printers
+
 register_libstdcxx_printers(obj)
 
 if gdb_has_xmethods():
 from .xmethods import register_libstdcxx_xmethods
+
 register_libstdcxx_xmethods(obj)
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 7e16a49aeb0..e26b8b36013 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -15,12 +15,13 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see .
 
-import gdb
+import datetime
+import errno
 import itertools
 import re
 import sys
-import errno
-import datetime
+
+import gdb
 
 # Python 2 + Python 3 compatibility code
 
@@ -78,6 +79,7 @@ else:
 
 def dst(self, dt):
 return datetime.timedelta(0)
+
 _utc_timezone = UTC()
 
 # Try to use the new-style pretty-printing if available.
@@ -91,6 +93,7 @@ except ImportError:
 _use_type_printing = False
 try:
 import gdb.types
+
 if hasattr(gdb.types, 'TypePrinter'):
 _use_type_printing = True
 except ImportError:
@@ -148,6 +151,7 @@ def lookup_templ_spec(templ, *args):
 pass
 raise e
 
+
 # Use this to find container node types instead of find_type,
 # see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91997 for details.
 def lookup_node_type(nodename, containertype):
@@ -177,8 +181,9 @@ def lookup_node_type(nodename, containertype):
 except gdb.error:
 # For debug mode containers the node is in std::__cxx1998.
 if is_member_of_namespace(nodename, 'std'):
-if is_member_of_namespace(containertype, 'std::__cxx1998',
-  'std::__debug', '__gnu_debug'):
+if is_member_of_namespace(
+containertype, 'std::__cxx1998', 'std::__debug', '__gnu_debug'
+):
 nodename = nodename.replace('::', '::__cxx1998::', 1)
 try:
 return lookup_templ_spec(nodename, valtype)
@@ -296,7 +301,9 @@ class SharedPointerPrinter(printer_base):
 state = 'expired, weak count %d' % weakcount
 else:
 state = 'use count %d, weak count %d' % (
-usecount, weakcount - 1)
+usecount,
+weakcount - 1,
+)
 return '%s<%s> (%s)' % (self._typename, targ, state)
 
 
@@ -305,13 +312,15 @@ def _tuple_impl_get(val):
 bases = val.type.fields()
 if not bases[-1].is_base_class:
 raise ValueError(
-"Unsupported implementation for std::tuple: %s" % str(val.type))
+"Unsupported implementation for std::tuple: %s" % str(val.type)
+)
 # Get the _Head_base base class:
 head_base = val.cast(bases[-1].type)
 fields = head_base.type.fields()
 if len(fields) == 0:
 raise ValueError(
-"Unsupported implementation for std::tuple: %s" % str(val.type))
+"Unsupported implementation for std::tuple: %s" % str(val.type)
+)
 if fields[0].name == '_M_head_impl':
 # The tuple element is the _Head_base::_M_head_impl data member.
 return 

[RFC 2/2] libstdc++: Add flake8 configuration

2023-10-04 Thread Tom Tromey
flake8 is a Python linter.  This patch adds a .flake8 configuration
file (flake8 does not use pyproject.toml for some reason) and fixes a
few trivial flake8 warnings.

After this patch, the only remaining flake8 warnings are about unused
imports (there are two - but they are not completely trivial to
remove) and the use of bare "except:".

It is possible to change the flake8 configuration to suppress these
warnings, but I haven't done so here.

libstdc++-v3/ChangeLog:

* python/.flake8: New file.
* python/libstdcxx/v6/__init__.py: Remove blank line.
* python/libstdcxx/v6/printers.py: Reformat two comments.
---
 libstdc++-v3/python/.flake8  | 3 +++
 libstdc++-v3/python/libstdcxx/__init__.py| 1 -
 libstdc++-v3/python/libstdcxx/v6/printers.py | 8 
 3 files changed, 7 insertions(+), 5 deletions(-)
 create mode 100644 libstdc++-v3/python/.flake8

diff --git a/libstdc++-v3/python/.flake8 b/libstdc++-v3/python/.flake8
new file mode 100644
index 000..7ffe4d6e0f7
--- /dev/null
+++ b/libstdc++-v3/python/.flake8
@@ -0,0 +1,3 @@
+[flake8]
+max-line-length = 79
+extend-ignore = E203
diff --git a/libstdc++-v3/python/libstdcxx/__init__.py 
b/libstdc++-v3/python/libstdcxx/__init__.py
index 8b137891791..e69de29bb2d 100644
--- a/libstdc++-v3/python/libstdcxx/__init__.py
+++ b/libstdc++-v3/python/libstdcxx/__init__.py
@@ -1 +0,0 @@
-
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index e26b8b36013..202fa450a91 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -2672,8 +2672,8 @@ class FilteringTypePrinter(object):
 name (str): The typedef-name that will be used instead.
 targ1 (str, optional): The first template argument. Defaults to None.
 
-Checks if a specialization of the class template 'template' is the same 
type
-as the typedef 'name', and prints it as 'name' instead.
+Checks if a specialization of the class template 'template' is the same
+type as the typedef 'name', and prints it as 'name' instead.
 
 e.g. if an instantiation of std::basic_istream is the same type as
 std::istream then print it as std::istream.
@@ -3167,8 +3167,8 @@ def build_libstdcxx_dictionary():
 libstdcxx_printer.add_version(
 'std::chrono::', 'tzdb', StdChronoTzdbPrinter
 )
-# libstdcxx_printer.add_version('std::chrono::(anonymous namespace)', 
'Rule',
-#  StdChronoTimeZoneRulePrinter)
+# libstdcxx_printer.add_version('std::chrono::(anonymous namespace)',
+#   'Rule', StdChronoTimeZoneRulePrinter)
 
 # Extensions.
 libstdcxx_printer.add_version('__gnu_cxx::', 'slist', StdSlistPrinter)
-- 
2.40.1



[RFC 0/2] black, isort, and flake8 configuration

2023-10-04 Thread Tom Tromey
This short series adds configuration files for black ("opinionated"
code formatter), isort (import sorter) and flake8 (Python lint) to
libstdc++.

I marked it as RFC since sometimes people don't like black's output.
In gdb we use it -- at first I found some of its decisions a little
odd, but overall it's nice not to have to review for or worry about
the minitia of code formatting.

Tom




[PATCH] libstdc++: Correctly call _string_types function

2023-10-04 Thread Tom Tromey
flake8 points out that the new call to _string_types from
StdExpAnyPrinter.__init__ is not correct -- it needs to be qualified.

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/printers.py
(StdExpAnyPrinter.__init__): Qualify call to
_string_types.
---
 libstdc++-v3/python/libstdcxx/v6/printers.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 23efbd171ec..9a51f26d8e0 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1386,7 +1386,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
 # FIXME need to expand 'std::string' so that gdb.lookup_type works
 if 'std::string' in mgrname:
 mgrtypes = []
-for s in _string_types():
+for s in StdExpAnyPrinter._string_types():
 try:
 x = re.sub(r"std::string(?!\w)", s, m.group(1))
 # The following lookup might raise gdb.error if the
-- 
2.40.1



[PATCH 2/2] libstdc++: _versioned_namespace is always non-None

2023-10-03 Thread Tom Tromey
Some code in the pretty-printers seems to assume that the
_versioned_namespace global might be None (or the empty string).
However, doesn't occur, as the variable is never reassigned.

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/printers.py: Assume that
_versioned_namespace is non-None.
* python/libstdcxx/v6/xmethods.py (is_specialization_of):
Assume that _versioned_namespace is non-None.
---
 libstdc++-v3/python/libstdcxx/v6/printers.py | 15 ++-
 libstdc++-v3/python/libstdcxx/v6/xmethods.py |  3 +--
 2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 23efbd171ec..e370551cbe1 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -139,7 +139,7 @@ def lookup_templ_spec(templ, *args):
 except gdb.error as e:
 # Type not found, try again in versioned namespace.
 global _versioned_namespace
-if _versioned_namespace and _versioned_namespace not in templ:
+if _versioned_namespace not in templ:
 t = t.replace('::', '::' + _versioned_namespace, 1)
 try:
 return gdb.lookup_type(t)
@@ -211,16 +211,13 @@ def is_specialization_of(x, template_name):
 global _versioned_namespace
 if isinstance(x, gdb.Type):
 x = x.tag
-if _versioned_namespace:
-template_name = '(%s)?%s' % (_versioned_namespace, template_name)
+template_name = '(%s)?%s' % (_versioned_namespace, template_name)
 return re.match('^std::%s<.*>$' % template_name, x) is not None
 
 
 def strip_versioned_namespace(typename):
 global _versioned_namespace
-if _versioned_namespace:
-return typename.replace(_versioned_namespace, '')
-return typename
+return typename.replace(_versioned_namespace, '')
 
 
 def strip_inline_namespaces(type_str):
@@ -2355,7 +2352,7 @@ class Printer(object):
 # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
 def add_version(self, base, name, function):
 self.add(base + name, function)
-if _versioned_namespace and '__cxx11' not in base:
+if '__cxx11' not in base:
 vbase = re.sub('^(std|__gnu_cxx)::', r'\g<0>%s' %
_versioned_namespace, base)
 self.add(vbase + name, function)
@@ -2527,7 +2524,7 @@ def add_one_template_type_printer(obj, name, defargs):
 printer = TemplateTypePrinter('std::__debug::' + name, defargs)
 gdb.types.register_type_printer(obj, printer)
 
-if _versioned_namespace and '__cxx11' not in name:
+if '__cxx11' not in name:
 # Add second type printer for same type in versioned namespace:
 ns = 'std::' + _versioned_namespace
 # PR 86112 Cannot use dict comprehension here:
@@ -2628,7 +2625,7 @@ class FilteringTypePrinter(object):
 def add_one_type_printer(obj, template, name, targ1=None):
 printer = FilteringTypePrinter('std::' + template, 'std::' + name, targ1)
 gdb.types.register_type_printer(obj, printer)
-if _versioned_namespace and '__cxx11' not in template:
+if '__cxx11' not in template:
 ns = 'std::' + _versioned_namespace
 printer = FilteringTypePrinter(ns + template, ns + name, targ1)
 gdb.types.register_type_printer(obj, printer)
diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py 
b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
index 8ccf57c4d6b..42e60eb57b1 100644
--- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
+++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
@@ -39,8 +39,7 @@ def is_specialization_of(x, template_name):
 """
 if isinstance(x, gdb.Type):
 x = x.tag
-if _versioned_namespace:
-template_name = '(%s)?%s' % (_versioned_namespace, template_name)
+template_name = '(%s)?%s' % (_versioned_namespace, template_name)
 return re.match(r'^std::(__\d::)?%s<.*>$' % template_name, x) is not None
 
 class LibStdCxxXMethod(gdb.xmethod.XMethod):
-- 
2.40.1



[PATCH 1/2] libstdc++: Define _versioned_namespace in xmethods.py

2023-10-03 Thread Tom Tromey
flake8 pointed out that is_specialization_of in xmethods.py looks at a
global that wasn't added to the file.  This patch correct the
oversight.

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/xmethods.py (_versioned_namespace):
Define.
---
 libstdc++-v3/python/libstdcxx/v6/xmethods.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py 
b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
index 844c8a2105a..8ccf57c4d6b 100644
--- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
+++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
@@ -28,6 +28,8 @@ def get_bool_type():
 def get_std_size_type():
 return gdb.lookup_type('std::size_t')
 
+_versioned_namespace = '__8::'
+
 def is_specialization_of(x, template_name):
 """
 Test whether a type is a specialization of the named class template.
-- 
2.40.1



[PATCH 0/2] A couple minor _versioned_namespace patches

2023-10-03 Thread Tom Tromey
While I was working on the flake8/black patches, flake8 pointed out a
bug in xmethods.py.  This is fixed in patch 1.  Then I found the
checks of _versioned_namespace to be a bit odd, so I wrote patch 2.

Tested on x86-64 Fedora 36.

Tom




Re: [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class

2023-09-28 Thread Tom Tromey
Jonathan> I've pushed the changes I wanted to make, so you'll have to rebase
Jonathan> your patches now, sorry.

No problem.  I rebased & re-tested them.
I can send a v2 if you want to double-check (only this large patch
required any changes), or just go ahead.  Let me know.
I may not be able to push until Monday.

Tom


Re: [PATCH 6/7] libstdc++: Fix regex escapes in pretty-printers

2023-09-28 Thread Tom Tromey
Jonathan> I already have a patch to use r'...' for these, so we only
Jonathan> need the single backslash.

Yeah, probably nicer.

Jonathan> So please don't commit this one, I think it will be
Jonathan> unnecessary in a couple of hours.

No problem, I'll drop it when I rebase on top of your changes.

Tom


[PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class

2023-09-28 Thread Tom Tromey
GDB 14 will add a new ValuePrinter tag class that will be used to
signal that pretty-printers will agree to the "extension protocol" --
essentially that they will follow some simple namespace rules, so that
GDB can add new methods over time.

A couple new methods have already been added to GDB, to support DAP.
While I haven't implemented these for any libstdc++ printers yet, this
patch makes the basic conversion: printers derive from
gdb.ValuePrinter if it is available, and all "non-standard" (that is,
not specified by GDB) members of the various value-printing classes
are renamed to have a leading underscore.
---
 libstdc++-v3/python/libstdcxx/v6/printers.py | 1201 +-
 1 file changed, 605 insertions(+), 596 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index d60c8003a63..bbc4375541f 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -97,6 +97,12 @@ try:
 except ImportError:
 pass
 
+# Use the base class if available.
+if hasattr(gdb, 'ValuePrinter'):
+printer_base = gdb.ValuePrinter
+else:
+printer_base = object
+
 # Starting with the type ORIG, search for the member type NAME.  This
 # handles searching upward through superclasses.  This is needed to
 # work around http://sourceware.org/bugzilla/show_bug.cgi?id=13615.
@@ -241,43 +247,43 @@ class SmartPtrIterator(Iterator):
 "An iterator for smart pointer types with a single 'child' value"
 
 def __init__(self, val):
-self.val = val
+self._val = val
 
 def __iter__(self):
 return self
 
 def __next__(self):
-if self.val is None:
+if self._val is None:
 raise StopIteration
-self.val, val = None, self.val
+self._val, val = None, self._val
 return ('get()', val)
 
 
-class SharedPointerPrinter:
+class SharedPointerPrinter(printer_base):
 "Print a shared_ptr, weak_ptr, atomic, or atomic"
 
 def __init__(self, typename, val):
-self.typename = strip_versioned_namespace(typename)
-self.val = val
-self.pointer = val['_M_ptr']
+self._typename = strip_versioned_namespace(typename)
+self._val = val
+self._pointer = val['_M_ptr']
 
 def children(self):
-return SmartPtrIterator(self.pointer)
+return SmartPtrIterator(self._pointer)
 
 # Return the _Sp_counted_base<>* that holds the refcounts.
 def _get_refcounts(self):
-if self.typename == 'std::atomic':
+if self._typename == 'std::atomic':
 # A tagged pointer is stored as uintptr_t.
-ptr_val = self.val['_M_refcount']['_M_val']['_M_i']
+ptr_val = self._val['_M_refcount']['_M_val']['_M_i']
 ptr_val = ptr_val - (ptr_val % 2)  # clear lock bit
-ptr_type = find_type(self.val['_M_refcount'].type, 'pointer')
+ptr_type = find_type(self._val['_M_refcount'].type, 'pointer')
 return ptr_val.cast(ptr_type)
-return self.val['_M_refcount']['_M_pi']
+return self._val['_M_refcount']['_M_pi']
 
 def to_string(self):
 state = 'empty'
 refcounts = self._get_refcounts()
-targ = self.val.type.template_argument(0)
+targ = self._val.type.template_argument(0)
 targ = strip_versioned_namespace(str(targ))
 
 if refcounts != 0:
@@ -288,7 +294,7 @@ class SharedPointerPrinter:
 else:
 state = 'use count %d, weak count %d' % (
 usecount, weakcount - 1)
-return '%s<%s> (%s)' % (self.typename, targ, state)
+return '%s<%s> (%s)' % (self._typename, targ, state)
 
 
 def _tuple_impl_get(val):
@@ -347,17 +353,17 @@ def unique_ptr_get(val):
 return tuple_get(0, tuple_member)
 
 
-class UniquePointerPrinter:
+class UniquePointerPrinter(printer_base):
 "Print a unique_ptr"
 
 def __init__(self, typename, val):
-self.val = val
+self._val = val
 
 def children(self):
-return SmartPtrIterator(unique_ptr_get(self.val))
+return SmartPtrIterator(unique_ptr_get(self._val))
 
 def to_string(self):
-return ('std::unique_ptr<%s>' % 
(str(self.val.type.template_argument(0
+return ('std::unique_ptr<%s>' % 
(str(self._val.type.template_argument(0
 
 
 def get_value_from_aligned_membuf(buf, valtype):
@@ -381,55 +387,56 @@ def get_value_from_list_node(node):
 raise ValueError("Unsupported implementation for %s" % str(node.type))
 
 
-class StdListPrinter:
+class StdListPrinter(printer_base):
 "Print a std::list"
 
 class _iterator(Iterator):
 def __init__(self, nodetype, head):
-self.nodetype = nodetype
-self.base = head['_M_next']
-self.head = head.address
-self.count = 0
+self._nodetype = nodetype
+self._base = head['_M_next']
+

[PATCH 7/7] libstdc++: Use Python "not in" operator

2023-09-28 Thread Tom Tromey
flake8 warns about code like

not something in "whatever"

Ordinarily in Python this should be written as:

something not in "whatever"

This patch makes this change.

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/printers.py (Printer.add_version)
(add_one_template_type_printer)
(FilteringTypePrinter.add_one_type_printer): Use Python
"not in" operator.
---
 libstdc++-v3/python/libstdcxx/v6/printers.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index d125236b777..380426cd41e 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -2321,7 +2321,7 @@ class Printer(object):
 # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
 def add_version(self, base, name, function):
 self.add(base + name, function)
-if _versioned_namespace and not '__cxx11' in base:
+if _versioned_namespace and '__cxx11' not in base:
 vbase = re.sub('^(std|__gnu_cxx)::', r'\g<0>%s' %
_versioned_namespace, base)
 self.add(vbase + name, function)
@@ -2494,7 +2494,7 @@ def add_one_template_type_printer(obj, name, defargs):
 printer = TemplateTypePrinter('std::__debug::'+name, defargs)
 gdb.types.register_type_printer(obj, printer)
 
-if _versioned_namespace and not '__cxx11' in name:
+if _versioned_namespace and '__cxx11' not in name:
 # Add second type printer for same type in versioned namespace:
 ns = 'std::' + _versioned_namespace
 # PR 86112 Cannot use dict comprehension here:
@@ -2589,7 +2589,7 @@ class FilteringTypePrinter(object):
 def add_one_type_printer(obj, template, name, targ1=None):
 printer = FilteringTypePrinter('std::' + template, 'std::' + name, targ1)
 gdb.types.register_type_printer(obj, printer)
-if _versioned_namespace and not '__cxx11' in template:
+if _versioned_namespace and '__cxx11' not in template:
 ns = 'std::' + _versioned_namespace
 printer = FilteringTypePrinter(ns + template, ns + name, targ1)
 gdb.types.register_type_printer(obj, printer)
-- 
2.40.1



[PATCH 4/7] libstdc++: Remove unused locals from printers.py

2023-09-28 Thread Tom Tromey
flake8 pointed out some unused local variables in the libstdc++
pretty-printers.  This removes them.

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/printers.py
(StdExpOptionalPrinter.__init__, lookup_node_type):
Remove unused variables.
---
 libstdc++-v3/python/libstdcxx/v6/printers.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 8d44244afb0..6bf4fe891fd 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -169,7 +169,7 @@ def lookup_node_type(nodename, containertype):
 valtype = valtype.strip_typedefs()
 try:
 return lookup_templ_spec(nodename, valtype)
-except gdb.error as e:
+except gdb.error:
 # For debug mode containers the node is in std::__cxx1998.
 if is_member_of_namespace(nodename, 'std'):
 if is_member_of_namespace(containertype, 'std::__cxx1998',
@@ -1423,7 +1423,6 @@ class StdExpOptionalPrinter(SingleObjContainerPrinter):
 "Print a std::optional or std::experimental::optional"
 
 def __init__(self, typename, val):
-valtype = self._recognize(val.type.template_argument(0))
 typename = strip_versioned_namespace(typename)
 self._typename = re.sub(
 '^std::(experimental::|)(fundamentals_v\d::|)(.*)', r'std::\1\3', 
typename, 1)
-- 
2.40.1



[PATCH 6/7] libstdc++: Fix regex escapes in pretty-printers

2023-09-28 Thread Tom Tromey
flake8 pointed out that some regexes in the pretty-printers are
missing a backslash.  This patch fixes these.

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/printers.py
(StdExpAnyPrinter.__init__, StdExpOptionalPrinter.__init__):
Add missing backslash.
* python/libstdcxx/v6/xmethods.py
(ArrayMethodsMatcher.match, DequeMethodsMatcher.match)
(ForwardListMethodsMatcher.match, ListMethodsMatcher.match)
(VectorMethodsMatcher.match)
(AssociativeContainerMethodsMatcher.match)
(UniquePtrGetWorker.__call__, UniquePtrMethodsMatcher.match)
(SharedPtrSubscriptWorker.__call__)
(SharedPtrMethodsMatcher.match): Add missing backslash.
---
 libstdc++-v3/python/libstdcxx/v6/printers.py |  6 +++---
 libstdc++-v3/python/libstdcxx/v6/xmethods.py | 22 ++--
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 94ac9232da7..d125236b777 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1344,7 +1344,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
 def __init__(self, typename, val):
 self._typename = strip_versioned_namespace(typename)
 self._typename = re.sub(
-'^std::experimental::fundamentals_v\d::', 'std::experimental::', 
self._typename, 1)
+'^std::experimental::fundamentals_v\\d::', 'std::experimental::', 
self._typename, 1)
 self._val = val
 self._contained_type = None
 contained_value = None
@@ -1377,7 +1377,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
 mgrtypes = []
 for s in strings:
 try:
-x = re.sub("std::string(?!\w)", s, m.group(1))
+x = re.sub("std::string(?!\\w)", s, m.group(1))
 # The following lookup might raise gdb.error if the
 # manager function was never instantiated for 's' in 
the
 # program, because there will be no such type.
@@ -1425,7 +1425,7 @@ class StdExpOptionalPrinter(SingleObjContainerPrinter):
 def __init__(self, typename, val):
 typename = strip_versioned_namespace(typename)
 self._typename = re.sub(
-'^std::(experimental::|)(fundamentals_v\d::|)(.*)', r'std::\1\3', 
typename, 1)
+'^std::(experimental::|)(fundamentals_v\\d::|)(.*)', r'std::\1\3', 
typename, 1)
 payload = val['_M_payload']
 if self._typename.startswith('std::experimental'):
 engaged = val['_M_engaged']
diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py 
b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
index 025b1b86ed0..eafecbb148e 100644
--- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
+++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
@@ -159,7 +159,7 @@ class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher):
 self.methods = [self._method_dict[m] for m in self._method_dict]
 
 def match(self, class_type, method_name):
-if not re.match('^std::(__\d+::)?array<.*>$', class_type.tag):
+if not re.match('^std::(__\\d+::)?array<.*>$', class_type.tag):
 return None
 method = self._method_dict.get(method_name)
 if method is None or not method.enabled:
@@ -284,7 +284,7 @@ class DequeMethodsMatcher(gdb.xmethod.XMethodMatcher):
 self.methods = [self._method_dict[m] for m in self._method_dict]
 
 def match(self, class_type, method_name):
-if not re.match('^std::(__\d+::)?deque<.*>$', class_type.tag):
+if not re.match('^std::(__\\d+::)?deque<.*>$', class_type.tag):
 return None
 method = self._method_dict.get(method_name)
 if method is None or not method.enabled:
@@ -332,7 +332,7 @@ class ForwardListMethodsMatcher(gdb.xmethod.XMethodMatcher):
 self.methods = [self._method_dict[m] for m in self._method_dict]
 
 def match(self, class_type, method_name):
-if not re.match('^std::(__\d+::)?forward_list<.*>$', class_type.tag):
+if not re.match('^std::(__\\d+::)?forward_list<.*>$', class_type.tag):
 return None
 method = self._method_dict.get(method_name)
 if method is None or not method.enabled:
@@ -419,7 +419,7 @@ class ListMethodsMatcher(gdb.xmethod.XMethodMatcher):
 self.methods = [self._method_dict[m] for m in self._method_dict]
 
 def match(self, class_type, method_name):
-if not re.match('^std::(__\d+::)?(__cxx11::)?list<.*>$', 
class_type.tag):
+if not re.match('^std::(__\\d+::)?(__cxx11::)?list<.*>$', 
class_type.tag):
 return None
 method = self._method_dict.get(method_name)
 if method is None or not method.enabled:
@@ -542,7 +542,7 @@ class VectorMethodsMatcher(gdb.xmethod.XMethodMatcher):
 self.methods = 

[PATCH 5/7] libstdc++: Remove std_ratio_t_tuple

2023-09-28 Thread Tom Tromey
This removes the std_ratio_t_tuple function from the Python
pretty-printer code.  It is not used.  Apparently the relevant parts
were moved to StdChronoDurationPrinter._ratio at some point in the
past.

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/printers.py (std_ratio_t_tuple):
Remove.
---
 libstdc++-v3/python/libstdcxx/v6/printers.py | 8 
 1 file changed, 8 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 6bf4fe891fd..94ac9232da7 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1985,14 +1985,6 @@ class StdFormatArgsPrinter(printer_base):
 return "%s with %d arguments" % (typ, size)
 
 
-def std_ratio_t_tuple(ratio_type):
-# TODO use reduced period i.e. duration::period
-period = self._val.type.template_argument(1)
-num = period.template_argument(0)
-den = period.template_argument(1)
-return (num, den)
-
-
 class StdChronoDurationPrinter(printer_base):
 "Print a std::chrono::duration"
 
-- 
2.40.1



[PATCH 3/7] libstdc++: Remove unused Python imports

2023-09-28 Thread Tom Tromey
flake8 pointed out some unused imports.

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/printers.py: Don't import 'os'.
* python/libstdcxx/v6/__init__.py: Don't import 'gdb'.
---
 libstdc++-v3/python/libstdcxx/v6/__init__.py | 2 --
 libstdc++-v3/python/libstdcxx/v6/printers.py | 1 -
 2 files changed, 3 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/__init__.py 
b/libstdc++-v3/python/libstdcxx/v6/__init__.py
index df654acd0c2..8b2cbc60a1b 100644
--- a/libstdc++-v3/python/libstdcxx/v6/__init__.py
+++ b/libstdc++-v3/python/libstdcxx/v6/__init__.py
@@ -13,8 +13,6 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see .
 
-import gdb
-
 # Load the xmethods if GDB supports them.
 def gdb_has_xmethods():
 try:
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index bbc4375541f..8d44244afb0 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -19,7 +19,6 @@ import gdb
 import itertools
 import re
 import sys
-import os
 import errno
 import datetime
 
-- 
2.40.1



[PATCH 0/7] libstdc++: Use gdb.ValuePrinter in pretty-printers

2023-09-28 Thread Tom Tromey
GDB 14 will include a gdb.ValuePrinter tag class that can be used by
pretty-printers to signal they will accept any extensions that GDB
happens to make over time.

This series started as an attempt to change the libstdc++ printers to
support this.  This just involves renaming a bunch of attributes.
There aren't many interesting GDB API additions yet (and I didn't
implement the new ones in libstdc++ yet anyway), but seeing as these
are the flagship pretty-printers, it seemed worthwhile to do.

I added patch 1 when debugging the changes; then proceeded to fix a
bunch of small issues that were pointed out by flake8.

Tested on x86-64 Fedora 36.  Let me know what you think.

Tom




[PATCH 1/7] libstdc++: Show full Python stack on error

2023-09-28 Thread Tom Tromey
This changes the libstdc++ test suite to arrange for gdb to show the
full Python stack if any sort of Python exception occurs.  This makes
debugging the printers a little simpler.

libstdc++-v3/ChangeLog:

* testsuite/lib/gdb-test.exp (gdb-test): Enable Python
stack traces from gdb.
---
 libstdc++-v3/testsuite/lib/gdb-test.exp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libstdc++-v3/testsuite/lib/gdb-test.exp 
b/libstdc++-v3/testsuite/lib/gdb-test.exp
index d8e572ef7b3..af7d970d388 100644
--- a/libstdc++-v3/testsuite/lib/gdb-test.exp
+++ b/libstdc++-v3/testsuite/lib/gdb-test.exp
@@ -141,6 +141,8 @@ proc gdb-test { marker {selector {}} {load_xmethods 0} } {
 puts $fd "set auto-load no"
 # Now that we've disabled auto-load, it's safe to set the target file
 puts $fd "file ./$output_file"
+# See the full backtrace of any failures.
+puts $fd "set python print-stack full"
 # Load & register *our* copy of the pretty-printers
 puts $fd "source $printer_code"
 puts $fd "python register_libstdcxx_printers(None)"
-- 
2.40.1



Re: [committed] libstdc++: Add GDB printers for types

2023-09-28 Thread Tom Tromey
Jonathan> The changes made by black seem reasonable, though I prefer it
Jonathan> with -S to disable string-normalization. It also needs an
Jonathan> option to use 79 as the maximum line length.

I've got some patches I'm about to send.

I made a pyproject.toml to auto-configure black (and isort), and this
works fine, but it also makes a bunch of edits.  So I'd rather send that
separately, after the current batch of patches is handled.

flake8 still isn't really happy, I guess because there are strings that
cause lines over 79, and black doesn't split those.  But meh, maybe
suppressing some flake8 errors is the way to go.

Tom


Re: [committed] libstdc++: Add GDB printers for types

2023-09-27 Thread Tom Tromey
>> I have fixes for most of the issues that are worth fixing (I didn't
>> bother with line lengths -- FWIW in gdb we just run 'black' and don't
>> worry about these details),

Jonathan> I used autopep8 and committed the result as
Jonathan> e08559271b2d797f658579ac8610dbf5e58bcfd8 so the line lengths
Jonathan> should be OK now.

Yeah, my patches are on top of that, but flake8 still complains, and I
still see lines > 79 characters.  However maybe flake8 isn't the checker
you want to use, or maybe you have something set up for a different line
length?

Jonathan> So the fix is to just change the string to '{} {}' which I've pushed
Jonathan> as 1fab05a885a308c19cf42b72fd36805ddf27fdc8 now (also attached).

Thank you.

Tom


Re: [committed] libstdc++: Add GDB printers for types

2023-09-27 Thread Tom Tromey
> Jonathan Wakely via Gcc-patches  writes:

Replying to a quite old email...

I ran a Python linter on the libstdc++ pretty-printers.

I have fixes for most of the issues that are worth fixing (I didn't
bother with line lengths -- FWIW in gdb we just run 'black' and don't
worry about these details), but the patch I'm replying to had a problem
that I didn't know how to fix:

> +class StdChronoTimeZoneRulePrinter:
[...]
> +if kind == 0: # DayOfMonth
> +start = '{} {}{}'.format(month, ordinal_day)

flake8 points out that this call to format has three placeholders but
only two arguments.

Tom


Re: RFC: Top level configure: Require a minimum version 6.8 texinfo

2023-08-30 Thread Tom Tromey
> "Eric" == Eric Gallager via Gdb-patches  
> writes:

Eric> Just as a point of reference, but the default makeinfo shipped with
Eric> macOS (/usr/bin/makeinfo) is stuck at version 4.8 due to the whole
Eric> GPL3 transition. The other makeinfos that I have installed are:
[...]

I think brew has a newer one.

However, I also sent a patch to back out what we think is the problem
patch.  Could you try that?  It's on the binutils list.

Tom


Re: RFC: Top level configure: Require a minimum version 6.8 texinfo

2023-08-29 Thread Tom Tromey
> "Nick" == Nick Clifton via Gdb-patches  
> writes:

Nick>   The reason for the change is that the bfd documentation now needs at
Nick>   least version 6.8 in order to build[1][2].

Sorry about this.  It was fallout from my patch.

However, GDB has used this same one-argument @node syntax for a long
time without any complaint.  Like, python.texi has used this since at
least 2014.

So, if makeinfo 6.8 is really needed by BFD, then I think it must be for
some other reason.

Tom


Re: [PATCH] Relax type-printer regexp in libstdc++ test suite

2023-06-29 Thread Tom Tromey via Gcc-patches
> Jonathan Wakely  writes:

> Looks good. OK for trunk, and OK to backport after some soak time on trunk. 
> Thanks.

AdaCore doesn't need a backport of this, and I don't think it's
extremely important; so unless you want me to do it, I don't plan to.

I did check it in on trunk earlier today.

thanks,
Tom


[PATCH] Relax type-printer regexp in libstdc++ test suite

2023-06-28 Thread Tom Tromey via Gcc-patches
The libstdc++ test suite checks whether gdb type printers are
available like so:

set do_whatis_tests [gdb_batch_check "python print(gdb.type_printers)" \
   "\\\[\\\]"]

This regexp assumes that the list of printers is empty.  However,
sometimes it's convenient to ship a gdb that comes with some default
printers, causing this to erroneously report that gdb is "too old".

I believe the intent of this check is to ensure that gdb.type_printers
exists -- not to check its starting value.  This patch changes the
check to accept any Python list as output.

Note that the patch doesn't look for the trailing "]".  I tried this
but in my case the output was too long for expect.  It seemed fine to
just check the start, as the point really is to reject the case where
the command prints an error message.

* testsuite/lib/gdb-test.exp (gdb-test): Relax type-printer
regexp.
---
 libstdc++-v3/testsuite/lib/gdb-test.exp | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/lib/gdb-test.exp 
b/libstdc++-v3/testsuite/lib/gdb-test.exp
index 3728a060aa4..d8e572ef7b3 100644
--- a/libstdc++-v3/testsuite/lib/gdb-test.exp
+++ b/libstdc++-v3/testsuite/lib/gdb-test.exp
@@ -107,8 +107,12 @@ proc gdb-test { marker {selector {}} {load_xmethods 0} } {
}
 }
 
+# A very old version of gdb will not have the type_printers
+# global.  Some organizations may ship a gdb that has some default
+# type printers, so accept any list output as indication that the
+# global exists.
 set do_whatis_tests [gdb_batch_check "python print(gdb.type_printers)" \
-  "\\\[\\\]"]
+  "\\\[.+"]
 if {!$do_whatis_tests} {
send_log "skipping 'whatis' tests - gdb too old"
 }
-- 
2.40.1



Re: [PATCH] [rs6000] adjust return_pc debug attrs

2023-03-24 Thread Tom Tromey via Gcc-patches
> "Segher" == Segher Boessenkool  writes:

>> FWIW I sent a gdb patch to work around this bug.  However, in my
>> examples, I only ever saw a nop following the call instruction -- so I
>> had gdb check for this.

Segher> GCC inserts just a nop in most cases, but the linker or dynamic linker
Segher> can replace it.

Thanks.  I've updated my gdb patch to drop the nop check.

Tom


Re: [PATCH] [rs6000] adjust return_pc debug attrs

2023-03-17 Thread Tom Tromey via Gcc-patches
> "Segher" == Segher Boessenkool  writes:

Segher> Yes.  On most architectures you can get multiple machine instructions of
Segher> course (for long calls for example), but on rs6000 (with some ABIs, in
Segher> some circumstances) we generate a nop insn after calls, so that the
Segher> linker has a spot to insert fixup code after calls (typically to restore
Segher> the r2 contents, but it could be anything).

FWIW I sent a gdb patch to work around this bug.  However, in my
examples, I only ever saw a nop following the call instruction -- so I
had gdb check for this.

Patch is here:

https://sourceware.org/pipermail/gdb-patches/2023-March/197951.html

... but I suppose I should change it to drop the nop check?

It would of course be better not to have to have gdb work around this
problem.

Tom


Re: [PATCHv2] Use toplevel configure for GMP and MPFR for gdb

2022-12-21 Thread Tom Tromey
>> I think it's fine to move forward with this now.
>> Thank you again for doing this.

Andrew> Just to double check this is an approval?

Yes, sorry for being unclear.

Tom


Re: [PATCHv2] Use toplevel configure for GMP and MPFR for gdb

2022-12-20 Thread Tom Tromey
> "Andrew" == apinski--- via Gdb-patches  
> writes:

Andrew> From: Andrew Pinski 
Andrew> This patch uses the toplevel configure parts for GMP/MPFR for
Andrew> gdb. The only thing is that gdb now requires MPFR for building.
Andrew> Before it was a recommended but not required library.
Andrew> Also this allows building of GMP and MPFR with the toplevel
Andrew> directory just like how it is done for GCC.
Andrew> We now error out in the toplevel configure of the version
Andrew> of GMP and MPFR that is wrong.

Andrew> OK after GDB 13 branches? Build gdb 3 ways:
Andrew> with GMP and MPFR in the toplevel (static library used at that point 
for both)
Andrew> With only MPFR in the toplevel (GMP distro library used and MPFR built 
from source)
Andrew> With neither GMP and MPFR in the toplevel (distro libraries used)

I think it's fine to move forward with this now.
Thank you again for doing this.

Tom


Re: [RFA] src-release.sh: Fix gdb source tarball build failure due to libsframe

2022-11-28 Thread Tom Tromey
> "Joel" == Joel Brobecker via Gdb-patches  
> writes:

Joel> ChangeLog:

Joel> * src-release.sh (GDB_SUPPORT_DIRS): Add libsframe.

Joel> Ok to apply to master?

Looks good to me.
I think we recently agreed that gdb and binutils maintainers can approve
patches like this... ?

thanks,
Tom


Re: [PATCHv2] Use toplevel configure for GMP and MPFR for gdb

2022-11-16 Thread Tom Tromey
> "Jeff" == Jeff Law via Gcc-patches  writes:

>> This patch uses the toplevel configure parts for GMP/MPFR for
>> gdb.

Jeff> If the GDB folks confirm they want this behavior, then the toplevel
Jeff> bits are fine.

I think we do, but my inclination is to wait until after GDB 13 branches.
CCing Joel to see what he thinks, as he handles the releases.

Tom


Re: [PATCH] Use toplevel configure for GMP and MPFR for gdb

2022-11-10 Thread Tom Tromey
> "Andrew" == apinski--- via Gcc-patches  writes:

Andrew> From: Andrew Pinski 
Andrew> This patch uses the toplevel configure parts for GMP/MPFR for
Andrew> gdb. The only thing is that gdb now requires MPFR for building.
Andrew> Before it was a recommended but not required library.
Andrew> Also this allows building of GMP and MPFR with the toplevel
Andrew> directory just like how it is done for GCC.
Andrew> We now error out in the toplevel configure of the version
Andrew> of GMP and MPFR that is wrong.

Thank you for doing this.  It's been on my to-do list to investigate
this for quite a while, but I never got to it... :(

One larger question I have is whether we should land this now, or wait
until after GDB 13 branches.  That is coming soon and maybe it's not
good to add a new dependency just before the release.

My inclination would be to defer it, I suppose out of conservatism, but
I'd appreciate hearing from others.

I think gdb/README and gdb/doc/gdb.texinfo need some minor changes,
because the GMP-related configure options are being renamed.

The commit message should mention "PR build/28500" somewhere so that the
commit is logged to bugzilla.  Also in gdb we've been using a "Bug:"
trailer in the commit message that has the full URL of the bug.
IIUC this does fix that PR.

Tom


Re: [PATCH v2 3/3] p1689r5: initial support

2022-11-01 Thread Tom Tromey
> "Ben" == Ben Boeckel via Gcc-patches  writes:

Ben> - `-fdeps-file=` specifies the path to the file to write the format to.

I don't know how this output is intended to be used, but one mistake
made with the other dependency-tracking options was that the output file
isn't created atomically.  As a consequence, Makefiles normally have to
work around this to be robust.  If that's a possible issue here then it
would be best to handle it in this patch.

Tom


Re: [PATCH Rust front-end v3 01/46] Use DW_ATE_UTF for the Rust 'char' type

2022-10-31 Thread Tom Tromey via Gcc-patches
> "Mark" == Mark Wielaard  writes:

Mark> DW_LANG_Rust_old was used by old rustc compilers <= 2016 before DWARF5
Mark> assigned an official number. It might be recognized by some
Mark> debuggers.

FWIW I wouldn't worry about it any more.
We could probably just remove the '_old' constant.

Tom


[PATCH] Remove --with-gmp-dir and --with-mpfr-dir

2022-03-18 Thread Tom Tromey via Gcc-patches
The top-level configure options --with-gmp-dir and --with-mpfr-dir
were obsoleted and marked as "REMOVED" back in 2006.  I think that's
long enough ago for everyone to have updated their scripts, so this
patch removes them entirely.  While doing this, I also found one other
leftover that wasn't removed by the earlier patch.  This is also
removed here.

ChangeLog
2022-03-18  Tom Tromey  

* configure.ac: Remove --with-mpfr-dir and --with-gmp-dir.
* configure: Rebuild.
---
 ChangeLog|  5 +
 configure| 22 +-
 configure.ac | 14 ++
 3 files changed, 8 insertions(+), 33 deletions(-)

diff --git a/configure b/configure
index f7e0fa46c9c..69d8fc046c3 100755
--- a/configure
+++ b/configure
@@ -811,11 +811,9 @@ enable_pgo_build
 with_mpc
 with_mpc_include
 with_mpc_lib
-with_mpfr_dir
 with_mpfr
 with_mpfr_include
 with_mpfr_lib
-with_gmp_dir
 with_gmp
 with_gmp_include
 with_gmp_lib
@@ -1588,14 +1586,12 @@ Optional Packages:
   --with-mpc-lib=PATH/lib
   --with-mpc-include=PATH specify directory for installed MPC include files
   --with-mpc-lib=PATH specify directory for the installed MPC library
-  --with-mpfr-dir=PATHthis option has been REMOVED
   --with-mpfr=PATHspecify prefix directory for installed MPFR package.
   Equivalent to --with-mpfr-include=PATH/include plus
   --with-mpfr-lib=PATH/lib
   --with-mpfr-include=PATH
   specify directory for installed MPFR include files
   --with-mpfr-lib=PATHspecify directory for the installed MPFR library
-  --with-gmp-dir=PATH this option has been REMOVED
   --with-gmp=PATH specify prefix directory for the installed GMP
   package. Equivalent to
   --with-gmp-include=PATH/include plus
@@ -3768,7 +3764,7 @@ case "${target}" in
   *-*-dragonfly*)
 ;;
   *-*-freebsd*)
-if test "x$with_gmp" = x && test "x$with_gmp_dir" = x \
+if test "x$with_gmp" = x \
&& ! test -d ${srcdir}/gmp \
&& test -f /usr/local/include/gmp.h; then
   with_gmp=/usr/local
@@ -7999,14 +7995,6 @@ fi
 # Specify a location for mpfr
 # check for this first so it ends up on the link line before gmp.
 
-# Check whether --with-mpfr-dir was given.
-if test "${with_mpfr_dir+set}" = set; then :
-  withval=$with_mpfr_dir; as_fn_error $? "The --with-mpfr-dir=PATH option has 
been removed.
-Use --with-mpfr=PATH or --with-mpfr-include=PATH plus --with-mpfr-lib=PATH" 
"$LINENO" 5
-fi
-
-
-
 # Check whether --with-mpfr was given.
 if test "${with_mpfr+set}" = set; then :
   withval=$with_mpfr;
@@ -8052,14 +8040,6 @@ fi
 
 # Specify a location for gmp
 
-# Check whether --with-gmp-dir was given.
-if test "${with_gmp_dir+set}" = set; then :
-  withval=$with_gmp_dir; as_fn_error $? "The --with-gmp-dir=PATH option has 
been removed.
-Use --with-gmp=PATH or --with-gmp-include=PATH plus --with-gmp-lib=PATH" 
"$LINENO" 5
-fi
-
-
-
 # Check whether --with-gmp was given.
 if test "${with_gmp+set}" = set; then :
   withval=$with_gmp;
diff --git a/configure.ac b/configure.ac
index 434b1a267a4..d0f6d215b99 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
 #   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
-#   2014, 2015, 2016, 2019 Free Software Foundation, Inc.
+#   2014, 2015, 2016, 2019, 2022 Free Software Foundation, Inc.
 #
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -1021,7 +1021,7 @@ case "${target}" in
   *-*-dragonfly*)
 ;;
   *-*-freebsd*)
-if test "x$with_gmp" = x && test "x$with_gmp_dir" = x \
+if test "x$with_gmp" = x \
&& ! test -d ${srcdir}/gmp \
&& test -f /usr/local/include/gmp.h; then
   with_gmp=/usr/local
@@ -1568,11 +1568,6 @@ fi
 
 # Specify a location for mpfr
 # check for this first so it ends up on the link line before gmp.
-AC_ARG_WITH(mpfr-dir,
-[AS_HELP_STRING([--with-mpfr-dir=PATH], [this option has been REMOVED])],
-[AC_MSG_ERROR([The --with-mpfr-dir=PATH option has been removed.
-Use --with-mpfr=PATH or --with-mpfr-include=PATH plus --with-mpfr-lib=PATH])])
-
 AC_ARG_WITH(mpfr,
 [AS_HELP_STRING([--with-mpfr=PATH],
[specify prefix directory for installed MPFR package.
@@ -1612,11 +1607,6 @@ Building GCC with MPFR in the source tree is only 
handled for MPFR 3.1.0+.])
 fi
 
 # Specify a location for gmp
-AC_ARG_WITH(gmp-dir,
-[AS_HELP_STRING([--with-gmp-dir=PATH], [this option has been REMOVED])],
-[AC_MSG_ERROR([The --with-gmp-dir=PATH option has been removed.
-Use --with-gmp=PATH or --with-gmp-include=PATH plus --with-gmp-lib=PATH])])
-
 AC_ARG_WITH(gmp,
 [AS_HELP_STRING([--with-gmp=PATH],
[specify prefix directory for the installed GMP package.
-- 
2.34.1



[PATCH 3/3] go: use htab_eq_string in godump

2021-05-05 Thread Tom Tromey
This changes godump to use the new htab_eq_string function.

gcc

* godump.c (string_hash_eq): Remove.
(go_finish): Use htab_eq_string.
---
 gcc/godump.c | 14 +++---
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/gcc/godump.c b/gcc/godump.c
index 7864d9d63e5d..cf9989490356 100644
--- a/gcc/godump.c
+++ b/gcc/godump.c
@@ -109,14 +109,6 @@ macro_hash_del (void *v)
   XDELETE (mhv);
 }
 
-/* For the string hash tables.  */
-
-static int
-string_hash_eq (const void *y1, const void *y2)
-{
-  return strcmp ((const char *) y1, (const char *) y2) == 0;
-}
-
 /* A macro definition.  */
 
 static void
@@ -1374,11 +1366,11 @@ go_finish (const char *filename)
   real_debug_hooks->finish (filename);
 
   container.type_hash = htab_create (100, htab_hash_string,
- string_hash_eq, NULL);
+htab_eq_string, NULL);
   container.invalid_hash = htab_create (10, htab_hash_string,
-   string_hash_eq, NULL);
+   htab_eq_string, NULL);
   container.keyword_hash = htab_create (50, htab_hash_string,
-string_hash_eq, NULL);
+   htab_eq_string, NULL);
   obstack_init (_obstack);
 
   keyword_hash_init ();
-- 
2.26.3



[PATCH 2/3] gcc: use htab_eq_string

2021-05-05 Thread Tom Tromey
This changes one spot in GCC to use the new htab_eq_string function.

gcc

* gengtype-state.c (read_state): Use htab_eq_string.
(string_eq): Remove.
---
 gcc/gengtype-state.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/gcc/gengtype-state.c b/gcc/gengtype-state.c
index 891f2e18a610..a8fde959f4eb 100644
--- a/gcc/gengtype-state.c
+++ b/gcc/gengtype-state.c
@@ -2556,15 +2556,6 @@ equals_type_number (const void *ty1, const void *ty2)
   return type1->state_number == type2->state_number;
 }
 
-static int
-string_eq (const void *a, const void *b)
-{
-  const char *a0 = (const char *)a;
-  const char *b0 = (const char *)b;
-
-  return (strcmp (a0, b0) == 0);
-}
-
 
 /* The function reading the state, called by main from gengtype.c.  */
 void
@@ -2588,7 +2579,7 @@ read_state (const char *path)
   state_seen_types =
 htab_create (2017, hash_type_number, equals_type_number, NULL);
   state_ident_tab =
-htab_create (4027, htab_hash_string, string_eq, NULL);
+htab_create (4027, htab_hash_string, htab_eq_string, NULL);
   read_state_version (version_string);
   read_state_srcdir ();
   read_state_languages ();
-- 
2.26.3



[PATCH 0/3] Add htab_eq_string to libiberty

2021-05-05 Thread Tom Tromey
The libiberty hash table defines a hash function for strings, but not
an equality function.  This means that various files have had to
implement their own comparison function over the years.

This series resolves this for gcc.  Once this is in, I plan to import
the change into binutils-gdb and apply a similar fix there.

While examining all the uses of htab_hash_string, I found an oddity
related to this in libcpp.  I've filed PR preprocessor/100435 for
this.

Tom




[PATCH 1/3] libiberty: add htab_eq_string

2021-05-05 Thread Tom Tromey
The libiberty hash table includes a helper function for strings, but
no equality function.  Consequently, this equality function has been
reimplemented a number of times in both the gcc and binutils-gdb
source trees.  This patch adds the function to the libiberty hash
table, as a step toward the goal of removing all the copies.

One change to gcc is included here.  Normally I would have put this in
the next patch, but gensupport.c used the most natural name for its
reimplementation of this function, and this can't coexist with the
extern function in libiberty.

include

* hashtab.h (htab_eq_string): Declare.

libiberty

* hashtab.c (htab_eq_string): New function.

gcc

* gensupport.c (htab_eq_string): Remove.
---
 gcc/gensupport.c| 8 
 include/hashtab.h   | 3 +++
 libiberty/hashtab.c | 7 +++
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/gcc/gensupport.c b/gcc/gensupport.c
index 0f19bd706646..e1ca06dbc1ec 100644
--- a/gcc/gensupport.c
+++ b/gcc/gensupport.c
@@ -2322,14 +2322,6 @@ gen_reader::handle_unknown_directive (file_location loc, 
const char *rtx_name)
 process_rtx (x, loc);
 }
 
-/* Comparison function for the mnemonic hash table.  */
-
-static int
-htab_eq_string (const void *s1, const void *s2)
-{
-  return strcmp ((const char*)s1, (const char*)s2) == 0;
-}
-
 /* Add mnemonic STR with length LEN to the mnemonic hash table
MNEMONIC_HTAB.  A trailing zero end character is appended to STR
and a permanent heap copy of STR is created.  */
diff --git a/include/hashtab.h b/include/hashtab.h
index b3a6265eeb6e..77c5eec79055 100644
--- a/include/hashtab.h
+++ b/include/hashtab.h
@@ -192,6 +192,9 @@ extern htab_eq htab_eq_pointer;
 /* A hash function for null-terminated strings.  */
 extern hashval_t htab_hash_string (const void *);
 
+/* An equality function for null-terminated strings.  */
+extern int htab_eq_string (const void *, const void *);
+
 /* An iterative hash function for arbitrary data.  */
 extern hashval_t iterative_hash (const void *, size_t, hashval_t);
 /* Shorthand for hashing something with an intrinsic size.  */
diff --git a/libiberty/hashtab.c b/libiberty/hashtab.c
index 0c7208effe11..7c424e8f6cc1 100644
--- a/libiberty/hashtab.c
+++ b/libiberty/hashtab.c
@@ -841,6 +841,13 @@ htab_hash_string (const PTR p)
   return r;
 }
 
+/* An equality function for null-terminated strings.  */
+int
+htab_eq_string (const void *a, const void *b)
+{
+  return strcmp ((const char *) a, (const char *) b) == 0;
+}
+
 /* DERIVED FROM:
 
 lookup2.c, by Bob Jenkins, December 1996, Public Domain.
-- 
2.26.3



Re: [PATCH v2 19/21] libcc1: use variadic templates for callbacks

2021-05-04 Thread Tom Tromey
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


Re: RFC: Changing AC_PROG_CC to AC_PROG_CC_C99 in top level configure

2021-05-03 Thread Tom Tromey
> "Simon" == Simon Marchi via Gcc-patches  writes:

Simon> For GDB, it's not supported to run gdb/configure directly, you need to
Simon> use the top-level configure.  Is it supported from some of the other
Simon> projects in the repo?

It can be done sometimes but I think it isn't really a scenario worth
worrying about.  Normally this kind of thing is only doable for sources
that are already independent of the top-level configury -- drop-in stuff
like gmp or libiconv, or roots of the tree like libiberty and gnulib.

Simon> I just tried with ld, it doesn't work since it depends on bfd also being
Simon> built.  I tried with just bfd, it doesn't work (with the default
Simon> configure options at least) because it requires zlib being built.

Yeah, most of the things that are "really" in-tree have dependencies and
can't be built independently of the rest.

Tom


Re: [PATCH v2 07/21] libcc1: use std::vector when building function types

2021-04-28 Thread Tom Tromey
>>>>> "Jeff" == Jeff Law  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  
>> 
>> * 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


[PATCH v2 14/21] libcc1: share basic context code

2021-04-27 Thread 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  

* 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

[PATCH v2 11/21] libcc1: unify compiler handling

2021-04-27 Thread 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  

* 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 ..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

[PATCH v2 19/21] libcc1: use variadic templates for callbacks

2021-04-27 Thread 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  

* rpc.hh (argument_wrapper) : Replace cast operator.
(argument_wrapper) : 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;
+= cc1_plugin::invoker::invoke;
   connection->add_callback ("binding_oracle", fun);
 
-  fun = cc1_plugin::callback;
+  fun = cc1_plugin::invoker::invoke;
   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; \
+  = cc1_plugin::invoker::invoke;  \
 current_context->add_callback (# N, fun);  \
   }
 #define GCC_METHOD1(R, N, A)   \
   {\
 cc1_plugin::callback_ftype *fun\
-  = cc1_plugin::callback;  \
+  = cc1_plugin::invoker::invoke;   \
 current_context->add_callback (# N, fun);  \
   }
 #define GCC_METHOD2(R, N, A, B)\
   {\
 cc1_plugin::callback_ftype *fun\
-  = cc1_plugin::callback;   \
+  = cc1_plugin::invoker::invoke;\
 current_context->add_callback (# N, fun);  \
   }
 #define GCC_METHOD3(R, N, A, B, C) \
   {\
 cc1_plugin::callback_ftype *fun\
-  = cc1_plugin::callback;\
+  = cc1_plugin::invoker::invoke; \
 current_context->add_callback (# N, fun);  \
   }
 #define GCC_METHOD4(R, N, A, B, C, D)  \
   {\
 cc1_plugin::callback_ftype *fun\
-  = cc1_plugin::callback; \
+  = cc1_plugin::invoker::invoke;   \
 current_context->add_callback (# N, fun);  \
   }
 #define GCC_METHOD5(R, N, A, B, C, D, E)   \
   {\
 cc1_plugin::callback_ftype *fun\
-  = cc1_plugin::callback; \
+  = cc1_plugin::invoker::invoke;   \
 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; \
+  = cc1_plugin::invoker::invoke; \
 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_plugi

[PATCH v2 21/21] libcc1: avoid a call to c_str

2021-04-27 Thread 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  

* 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 _regexp, const char *compiler)
 {
   std::stringstream buf;
 
@@ -71,7 +71,7 @@ char *
 cc1_plugin::compiler_triplet_regexp::find (const char *base,
   std::string ) 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



[PATCH v2 13/21] libcc1: use static_assert

2021-04-27 Thread 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  

* 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;
 
 
 
-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



[PATCH v2 15/21] libcc1: share GDB plugin code

2021-04-27 Thread 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  

* 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 ..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
+  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 *b)
+   : connection (fd, aux_fd),
+ back_ptr (b)
+  {
+  }
+
+  void print (const char *buf) override
+  {
+   back_ptr->print (buf);
+  }
+
+  base_gdb_plugin *back_ptr;
+};
+
+std::unique_ptr connection;
+
+void (*print_function) (void *datum, const char *message) = nullptr;
+void *print_datum = nullptr;
+
+std::vector args;
+std::string source_file;
+
+/* Non-zero as an equivalent to gcc driver option "-v".  */
+bool verbose;
+
+std::unique_ptr 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
+  R rpc (CTX *s, Arg... rest)
+  {
+base_gdb_plugin *self = (base_gdb_plugin *) s;
+R result;
+
+if (!cc1_plugin::call (self->connection.get (), NAME, , 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
 {
   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->pri

[PATCH v2 17/21] libcc1: share the GCC interface code

2021-04-27 Thread 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  

* libcp1.cc (libcp1): Change parameters.  Update.
(libcp1_set_verbose, libcp1_set_arguments)
(libcp1_set_triplet_regexp, libcp1_set_driver_filename)
(libcp1_set_source_file, libcp1_set_print_callback, fork_exec)
(libcp1_compile, libcp1_destroy, vtable): Remove.
(libcp1::add_callbacks): New method, extracted from
libcp1_compile.
(gcc_c_fe_context): Update.
* libcc1.cc (libcc1): Change parameters.  Update.
(libcc1_set_verbose, libcc1_set_arguments)
(libcc1_set_triplet_regexp, libcc1_set_driver_filename)
(libcc1_set_source_file, libcc1_set_print_callback, fork_exec)
(libcc1_compile, libcc1_destroy, vtable): Remove.
(libcc1::add_callbacks): New method, extracted from
libcc1_compile.
(gcc_c_fe_context): Update.
* gdbctx.hh (base_gdb_plugin): Change parameters.
(~base_gdb_plugin): New.
: New virtual method.
: New members.
(get_self, do_set_verbose, do_set_arguments)
(do_set_triplet_regexp, do_set_driver_filename)
(do_set_arguments_v0, do_set_source_file, do_set_print_callback)
(fork_exec, do_compile, do_compile_v0, do_destroy): New methods.
---
 libcc1/ChangeLog |  27 +
 libcc1/gdbctx.hh | 253 ++-
 libcc1/libcc1.cc | 242 +++--
 libcc1/libcp1.cc | 246 +++--
 4 files changed, 304 insertions(+), 464 deletions(-)

diff --git a/libcc1/gdbctx.hh b/libcc1/gdbctx.hh
index 1c8d87dff021..4a48381f2b4a 100644
--- a/libcc1/gdbctx.hh
+++ b/libcc1/gdbctx.hh
@@ -23,16 +23,38 @@ along with GCC; see the file COPYING3.  If not see
 namespace cc1_plugin
 {
   // The compiler context that we hand back to our caller.
+  // Due to this, the entire implementation is in this header.
   template
   struct base_gdb_plugin : public T
   {
-explicit base_gdb_plugin (const gcc_base_vtable *v)
+base_gdb_plugin (const char *plugin_name_, const char *base_name,
+int version)
   : verbose (false),
+   plugin_name (plugin_name_),
+   fe_version (version),
+   compiler_name (base_name),
compilerp (new compiler (verbose))
 {
-  this->base.ops = v;
+  vtable =
+   {
+ GCC_FE_VERSION_1,
+ do_set_arguments_v0,
+ do_set_source_file,
+ do_set_print_callback,
+ do_compile_v0,
+ do_destroy,
+ do_set_verbose,
+ do_compile,
+ do_set_arguments,
+ do_set_triplet_regexp,
+ do_set_driver_filename,
+   };
+
+  this->base.ops = 
 }
 
+virtual ~base_gdb_plugin () = default;
+
 // A convenience function to print something.
 void print (const char *str)
 {
@@ -53,6 +75,10 @@ namespace cc1_plugin
   connection.reset (new local_connection (fd, aux_fd, this));
 }
 
+// This is called just before compilation begins.  It should set
+// any needed callbacks on the connection.
+virtual void add_callbacks () = 0;
+
 // A local subclass of connection that holds a back-pointer to the
 // context object that we provide to our caller.
 class local_connection : public cc1_plugin::connection
@@ -84,7 +110,230 @@ namespace cc1_plugin
 /* Non-zero as an equivalent to gcc driver option "-v".  */
 bool verbose;
 
+const char *plugin_name;
+int fe_version;
+
+const char *compiler_name;
 std::unique_ptr compilerp;
+
+  private:
+
+struct gcc_base_vtable vtable;
+
+static inline base_gdb_plugin *
+get_self (gcc_base_context *s)
+{
+  T *sub = (T *) s;
+  return static_cast *> (sub);
+}
+
+static void
+do_set_verbose (struct gcc_base_context *s, int /* bool */ verbose)
+{
+  base_gdb_plugin *self = get_self (s);
+
+  self->set_verbose (verbose != 0);
+}
+
+static char *
+do_set_arguments (struct gcc_base_context *s,
+ int argc, char **argv)
+{
+  base_gdb_plugin *self = get_self (s);
+
+  std::string compiler;
+  char *errmsg = self->compilerp->find (self->compiler_name, compiler);
+  if (errmsg != NULL)
+   return errmsg;
+
+  self->args.push_back (compiler);
+
+  for (int i = 0; i < argc; ++i)
+   self->args.push_back (argv[i]);
+
+  return NULL;
+}
+
+static char *
+do_set_triplet_regexp (struct gcc_base_context *s,
+  const char *triplet_reg

[PATCH v2 16/21] libcc1: use GCC_FE_VERSION_1 in C++ plugin

2021-04-27 Thread 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  

* 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



[PATCH v2 18/21] libcc1: fix a memory leak

2021-04-27 Thread 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  

* 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 argv (self->args.size () + 1);
   for (unsigned int i = 0; i < self->args.size (); ++i)
argv[i] = const_cast (self->args[i].c_str ());
-  argv[self->args.size ()] = NULL;
 
-  return self->fork_exec (argv, fds, stderr_fds);
+  return self->fork_exec (argv.data (), fds, stderr_fds);
 }
 
 static int
-- 
2.26.2



[PATCH v2 20/21] libcc1: avoid extra string copies

2021-04-27 Thread 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  

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 ) 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 ) 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



[PATCH v2 12/21] libcc1: use foreach

2021-04-27 Thread Tom Tromey
This changes libcc1 to ues foreach in a couple of spots.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* 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::iterator it = address_map.begin ();
-   it != address_map.end ();
-   ++it)
+  for (const auto  : address_map)
 {
-  ggc_mark ((*it)->decl);
-  ggc_mark ((*it)->address);
+  ggc_mark (item->decl);
+  ggc_mark (item->address);
 }
 
-  for (hash_table< nofree_ptr_hash >::iterator
-it = preserved.begin (); it != preserved.end (); ++it)
-ggc_mark (&*it);
+  for (const auto  : preserved)
+ggc_mark ();
 }
 
 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::iterator it = address_map.begin ();
-   it != address_map.end ();
-   ++it)
+  for (const auto  : address_map)
 {
-  ggc_mark ((*it)->decl);
-  ggc_mark ((*it)->address);
+  ggc_mark (item->decl);
+  ggc_mark (item->address);
 }
 
-  for (hash_table< nofree_ptr_hash >::iterator
-it = preserved.begin (); it != preserved.end (); ++it)
-ggc_mark (&*it);
+  for (const auto  : preserved)
+ggc_mark ();
 }
 
 static void
-- 
2.26.2



[PATCH v2 09/21] libcc1: add more uses of 'deleter'

2021-04-27 Thread 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  

* rpc.hh (deleter): Move template and some specializations to
deleter.hh.
(argument_wrapper): 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 ..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 
+
+namespace cc1_plugin
+{
+  // Any pointer type requires a deleter object that knows how to
+  // clean up.  These are used in multiple places.
+  template struct deleter;
+
+  template<>
+  struct deleter
+  {
+void operator() (char *s)
+{
+  delete[] s;
+}
+  };
+
+  template<>
+  struct deleter
+  {
+void operator() (gcc_type_array *p)
+{
+  delete[] p->elements;
+  delete p;
+}
+  };
+
+  template using unique_ptr = std::unique_ptr>;
+}
+
+#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
+  {
+void operator() (gcc_vbase_array *p)
+{
+  delete[] p->flags;
+  delete[] p->elements;
+  delete p;
+}
+  };
+
+  template<>
+  struct deleter
+  {
+void operator() (gcc_cp_template_args *p)
+{
+  delete[] p->elements;
+  delete[] p->kinds;
+  delete p;
+}
+  };
+
+  template<>
+  struct deleter
+  {
+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 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 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]

[PATCH v2 10/21] libcc1: use unique_ptr more

2021-04-27 Thread 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  

* libcp1.cc (struct libcp1) : Use
unique_ptr.
(~libcp1): Remove.
(libcp1_compile, libcp1_set_triplet_regexp)
(libcp1_set_driver_filename): Update.
* libcc1.cc (struct libcc1) : 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 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 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;
-}
-
 
 
 // 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, , rest...))
+  if (!cc1_plugin::call (self->connection.get (), NAME, , 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::callbackprint_function (this->print_datum, str);
   }
 
-  libcp1_connection *connection;
+  std::unique_ptr 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 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;
 }

[PATCH v2 08/21] libcc1: add deleter objects

2021-04-27 Thread 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  

* 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 
 
 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
-  class argument_wrapper;
+  // Any pointer type requires a deleter object that knows how to
+  // clean up.  These are used in multiple places.
+  template struct deleter;
 
-  // Specialization for string types.
   template<>
-  class argument_wrapper
+  struct deleter
   {
-  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 = (const argument_wrapper &) = delete;
-
-operator const char * () const
-{
-  return m_object;
-}
-
-status unmarshall (connection *conn)
-{
-  return ::cc1_plugin::unmarshall (conn, _object);
-}
-
-  private:
-
-char *m_object;
   };
 
-  // Specialization for gcc_type_array.
   template<>
-  class argument_wrapper
+  struct deleter
   {
-  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 = (const argument_wrapper &) = delete;
-
-operator const gcc_type_array * () const
-{
-  return m_object;
-}
-
-status unmarshall (connection *conn)
-{
-  return ::cc1_plugin::unmarshall (conn, _object);
-}
-
-  private:
-
-gcc_type_array *m_object;
   };
 
 #ifdef GCC_CP_INTERFACE_H
-  // Specialization for gcc_vbase_array.
   template<>
-  class argument_wrapper
+  struct deleter
   {
-  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 = (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, _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
+  struct deleter
   {
-  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 = (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 unmars

[PATCH v2 07/21] libcc1: use std::vector when building function types

2021-04-27 Thread 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  

* 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 
+
 #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 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 (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 
+
 #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 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 (self);
   return convert_out (ctx->preserve (result));
-- 
2.26.2



[PATCH v2 05/21] libcc1: use variadic templates for "call"

2021-04-27 Thread 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  

* 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
@@ -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
+  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
+  template
   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
-  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
   status
   callback (connection *conn)
@@ -315,27 +298,6 @@ namespace cc1_plugin
 return marshall (conn, result);
   }
 
-  template
-  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
   status
@@ -357,30 +319,6 @@ namespace cc1_plugin
 return marshall (conn, result);
   }
 
-  template
-  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;
-

[PATCH v2 06/21] libcc1: use variadic templates for "rpc"

2021-04-27 Thread 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  

* 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
-R rpc (struct gcc_c_context *s)
+template
+R rpc (struct gcc_c_context *s, Arg... rest)
 {
   libcc1 *self = (libcc1 *) s;
   R result;
 
-  if (!cc1_plugin::call (self->connection, NAME, ))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A arg)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg1, arg2))
-return 0;
-  return result;
-}
-
-template
-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, , arg1, arg2, arg3))
-return 0;
-  return result;
-}
-
-template
-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, , arg1, arg2, arg3,
-arg4))
-return 0;
-  return result;
-}
-
-template
-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, , arg1, arg2, arg3,
-arg4, arg5))
-return 0;
-  return result;
-}
-
-template
-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, , arg1, arg2, arg3,
-arg4, arg5, arg6, arg7))
+  if (!cc1_plugin::call (self->connection, NAME, , 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
-R rpc (struct gcc_cp_context *s)
+template
+R rpc (struct gcc_cp_context *s, Arg... rest)
 {
   libcp1 *self = (libcp1 *) s;
   R result;
 
-  if (!cc1_plugin::call (self->connection, NAME, ))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A arg)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg1, arg2))
-return 0;
-  return result;
-}
-
-template
-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, , arg1, arg2, arg3))
-return 0;
-  return result;
-}
-
-template
-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, , arg1, arg2, arg3,
-arg4))
-return 0;
-  return result;
-}
-
-template
-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, , arg1, arg2, arg3,
-arg4, arg5))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5,
-   

[PATCH v2 04/21] libcc1: delete copy constructor and assignment operators

2021-04-27 Thread 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  

* 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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 ass

[PATCH v2 02/21] libcc1: use "override"

2021-04-27 Thread Tom Tromey
This changes libcc1 to use "override" where appropriate.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* 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 ) const;
+char *find (std::string ) 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 ) const;
+char *find (std::string ) 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 ) const;
+char *find (std::string ) 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 ) const;
+char *find (std::string ) 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



[PATCH v2 03/21] libcc1: inline some simple methods

2021-04-27 Thread Tom Tromey
This changes libcc1 to inline a trivial method and to use the default
constructor.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* 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



[PATCH v2 01/21] libcc1: use templates to unmarshall enums

2021-04-27 Thread 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  

* 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 
 #include 
 #include 
-#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..
--- 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, ))
-  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, ))
-  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, ))
-  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, ))
-  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, ))
-  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, ))
-  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, ))
-  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 g

[PATCH v2 00/21] C++11-based improvements for libcc1

2021-04-27 Thread Tom Tromey
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




Re: [PATCH] Use hardware_concurrency only if _GLIBCXX_HAS_GTHREADS

2021-04-21 Thread Tom Tromey
> "Jakub" == Jakub Jelinek via Gcc-patches  writes:

Jakub> What would be IMHO a good idea would be to use configure test for
Jakub> #include 
Jakub> int t = std::thread::hardware_concurrency ();
Jakub> and in that case use that as a fallback to the previous implementation,
Jakub> that will be strictly an improvement.

FWIW, gdb had to do this.  The check is in gdbsupport/common.m4.
I've appended it for convenience.

Tom

  # Check for std::thread.  This does not work on some platforms, like
  # mingw and DJGPP.
  AC_LANG_PUSH([C++])
  AX_PTHREAD([threads=yes], [threads=no])
  if test "$threads" = "yes"; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$PTHREAD_CFLAGS $save_CXXFLAGS"
AC_CACHE_CHECK([for std::thread],
   gdb_cv_cxx_std_thread,
   [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[#include 
  void callback() { }]],
[[std::thread t(callback);]])],
  gdb_cv_cxx_std_thread=yes,
  gdb_cv_cxx_std_thread=no)])

# This check must be here, while LIBS includes any necessary
# threading library.
AC_CHECK_FUNCS([pthread_sigmask pthread_setname_np])

LIBS="$save_LIBS"
CXXFLAGS="$save_CXXFLAGS"
  fi
  if test "$gdb_cv_cxx_std_thread" = "yes"; then
AC_DEFINE(CXX_STD_THREAD, 1,
  [Define to 1 if std::thread works.])
  fi
  AC_LANG_POP


Re: [PATCH] libgccjit: Handle truncation and extension for casts [PR 95498]

2021-02-20 Thread Tom Tromey
> "Antoni" == Antoni Boucher via Gcc-patches  
> writes:

Antoni> gcc/jit/
Antoni> PR target/95498
Antoni> * jit-playback.c: Add support to handle truncation and extension
Antoni> in the convert function.

Antoni> +  switch (dst_code)
Antoni> +{
Antoni> +case INTEGER_TYPE:
Antoni> +case ENUMERAL_TYPE:
Antoni> +  t_ret = convert_to_integer (dst_type, expr);
Antoni> +  goto maybe_fold;
Antoni> +
Antoni> +default:
Antoni> +  gcc_assert (gcc::jit::active_playback_ctxt);
Antoni> +  gcc::jit::active_playback_ctxt->add_error (NULL, "unhandled 
conversion");
Antoni> +  fprintf (stderr, "input expression:\n");
Antoni> +  debug_tree (expr);
Antoni> +  fprintf (stderr, "requested type:\n");
Antoni> +  debug_tree (dst_type);
Antoni> +  return error_mark_node;
Antoni> +
Antoni> +maybe_fold:
Antoni> +  if (TREE_CODE (t_ret) != C_MAYBE_CONST_EXPR)
Antoni> +   t_ret = fold (t_ret);
Antoni> +  return t_ret;

It seems weird to have a single 'goto' to maybe_fold, especially inside
a switch like this.

If you think the maybe_fold code won't be reused, then it should just be
hoisted up and the 'goto' removed.

On the other hand, if the maybe_fold code might be reused for some other
case, then I suppose I would have the case end with 'break' and then
have this code outside the switch.


In another message, you wrote:

Antoni> For your question, the current code already works with boolean and
Antoni> reals and casts between integers and pointers is currently not
Antoni> supported.

I am curious why this wasn't supported.  It seems like something that
one might want to do.

thanks,
Tom


Re: [PATCH] Fix producer string memory leaks

2021-02-16 Thread Tom Tromey
> "Martin" == Martin Sebor via Gcc-patches  writes:

Martin> FWIW, I have prototyped
Martin> a simple string class over the weekend (based on auto_vec) that I'm
Martin> willing to contribute if std::string turns out to be out of favor.

I wonder whether GDB and GCC can or should collaborate in this area.

GDB has been using C++ for a while now, and we've encountered many of
these same transitional problems.  My sense is that, unlike GCC, GDB has
been a bit more aggressive about adopting C++11 style though.

For this particular area, GDB uses std::string pretty freely -- but not
universally, both due to its history as a C code base, but also because
std::string can be too heavy for some uses.  Not all code needs to carry
around the length, etc.

Pedro adapted the C++17 string_view from libstdc++, and this is used in
some spots in GDB.  See gdbsupport/gdb_string_view.h.

GDB also uses a unique_ptr specialization that wraps xmalloc/xfree.
See gdbsupport/gdb_unique_ptr.h.

So in GDB, instead of writing a new string-ish class, I suppose we'd
simply hook string_view up to unique_xmalloc_ptr or something
along those lines.

Martin> There is std::unique_ptr that we could use rather than rolling our
Martin> own.  That said, I don't think using std::unique_ptr over a string
Martin> class would be appropriate for things like local (string) variables
Martin> or return types of functions returning strings.

In GDB we do this kind of thing all the time.  The main idea is to
indicate ownership transfer via the type system.  This helps eliminate
comments like "the caller must free the result" -- the return of a
unique_ptr explains this directly.

>> But then there's the issue of introducing lifetime bugs because
>> you definitely need to have the pointer escape at points like
>> the printf ...

This is a valid concern in C++, but hasn't been a big practical issue in
GDB.

Tom


Re: [PATCH 00/10] C++11-based improvements for libcc1

2021-01-03 Thread Tom Tromey
>>>>> "Tom" == Tom Tromey  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


[PATCH 10/10] libcc1: use unique_ptr more

2021-01-03 Thread 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  

* libcp1.cc (struct libcp1) : Use
unique_ptr.
(~libcp1): Remove.
(libcp1_compile, libcp1_set_triplet_regexp)
(libcp1_set_driver_filename): Update.
* libcc1.cc (struct libcc1) : 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 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 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;
-}
-
 
 
 // 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, , rest...))
+  if (!cc1_plugin::call (self->connection.get (), NAME, , 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::callbackprint_function (this->print_datum, str);
   }
 
-  libcp1_connection *connection;
+  std::unique_ptr 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 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::~libc

[PATCH 09/10] libcc1: add more uses of 'deleter'

2021-01-03 Thread 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  

* rpc.hh (deleter): Move template and some specializations to
deleter.hh.
(argument_wrapper): 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 000..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 
+
+namespace cc1_plugin
+{
+  // Any pointer type requires a deleter object that knows how to
+  // clean up.  These are used in multiple places.
+  template struct deleter;
+
+  template<>
+  struct deleter
+  {
+void operator() (char *s)
+{
+  delete[] s;
+}
+  };
+
+  template<>
+  struct deleter
+  {
+void operator() (gcc_type_array *p)
+{
+  delete[] p->elements;
+  delete p;
+}
+  };
+
+  template using unique_ptr = std::unique_ptr>;
+}
+
+#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
+  {
+void operator() (gcc_vbase_array *p)
+{
+  delete[] p->flags;
+  delete[] p->elements;
+  delete p;
+}
+  };
+
+  template<>
+  struct deleter
+  {
+void operator() (gcc_cp_template_args *p)
+{
+  delete[] p->elements;
+  delete[] p->kinds;
+  delete p;
+}
+  };
+
+  template<>
+  struct deleter
+  {
+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 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 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]

[PATCH 08/10] libcc1: add deleter objects

2021-01-03 Thread 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  

* 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 
 
 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
-  class argument_wrapper;
+  // Any pointer type requires a deleter object that knows how to
+  // clean up.  These are used in multiple places.
+  template struct deleter;
 
-  // Specialization for string types.
   template<>
-  class argument_wrapper
+  struct deleter
   {
-  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 = (const argument_wrapper &) = delete;
-
-operator const char * () const
-{
-  return m_object;
-}
-
-status unmarshall (connection *conn)
-{
-  return ::cc1_plugin::unmarshall (conn, _object);
-}
-
-  private:
-
-char *m_object;
   };
 
-  // Specialization for gcc_type_array.
   template<>
-  class argument_wrapper
+  struct deleter
   {
-  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 = (const argument_wrapper &) = delete;
-
-operator const gcc_type_array * () const
-{
-  return m_object;
-}
-
-status unmarshall (connection *conn)
-{
-  return ::cc1_plugin::unmarshall (conn, _object);
-}
-
-  private:
-
-gcc_type_array *m_object;
   };
 
 #ifdef GCC_CP_INTERFACE_H
-  // Specialization for gcc_vbase_array.
   template<>
-  class argument_wrapper
+  struct deleter
   {
-  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 = (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, _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
+  struct deleter
   {
-  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 = (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 unmars

[PATCH 04/10] libcc1: delete copy constructor and assignment operators

2021-01-03 Thread 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  

* 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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 ass

[PATCH 06/10] libcc1: use variadic templates for "rpc"

2021-01-03 Thread 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  

* 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
-R rpc (struct gcc_c_context *s)
+template
+R rpc (struct gcc_c_context *s, Arg... rest)
 {
   libcc1 *self = (libcc1 *) s;
   R result;
 
-  if (!cc1_plugin::call (self->connection, NAME, ))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A arg)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg1, arg2))
-return 0;
-  return result;
-}
-
-template
-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, , arg1, arg2, arg3))
-return 0;
-  return result;
-}
-
-template
-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, , arg1, arg2, arg3,
-arg4))
-return 0;
-  return result;
-}
-
-template
-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, , arg1, arg2, arg3,
-arg4, arg5))
-return 0;
-  return result;
-}
-
-template
-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, , arg1, arg2, arg3,
-arg4, arg5, arg6, arg7))
+  if (!cc1_plugin::call (self->connection, NAME, , 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
-R rpc (struct gcc_cp_context *s)
+template
+R rpc (struct gcc_cp_context *s, Arg... rest)
 {
   libcp1 *self = (libcp1 *) s;
   R result;
 
-  if (!cc1_plugin::call (self->connection, NAME, ))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A arg)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg1, arg2))
-return 0;
-  return result;
-}
-
-template
-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, , arg1, arg2, arg3))
-return 0;
-  return result;
-}
-
-template
-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, , arg1, arg2, arg3,
-arg4))
-return 0;
-  return result;
-}
-
-template
-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, , arg1, arg2, arg3,
-arg4, arg5))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5,
-   A6 arg6,

[PATCH 07/10] libcc1: use std::vector when building function types

2021-01-03 Thread 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  

* 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 
+
 #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 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 (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 
+
 #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 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 (self);
   return convert_out (ctx->preserve (result));
-- 
2.26.2



  1   2   3   4   5   6   >