From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1551) id 6FA603838008; Tue, 10 May 2022 13:18:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6FA603838008 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Pedro Alves To: gdb-cvs@sourceware.org Subject: [binutils-gdb] Fix "b f(std::string)" when current language is C X-Act-Checkin: binutils-gdb X-Git-Author: Pedro Alves X-Git-Refname: refs/heads/master X-Git-Oldrev: 1c6fbf42e5bd3045a41ad32c5efbc2ab8ca5e941 X-Git-Newrev: c7d029ea9cc566b8d3c50b08ef12d98394adf1b1 Message-Id: <20220510131824.6FA603838008@sourceware.org> Date: Tue, 10 May 2022 13:18:24 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 May 2022 13:18:24 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Dc7d029ea9cc5= 66b8d3c50b08ef12d98394adf1b1 commit c7d029ea9cc566b8d3c50b08ef12d98394adf1b1 Author: Pedro Alves Date: Fri Apr 29 23:21:18 2022 +0100 Fix "b f(std::string)" when current language is C =20 If you try to set a breakpoint at a function such as "b f(std::string)", and the current language is C, the breakpoint fails to be set, like so: =20 (gdb) set language c break f(std::string) Function "f(std::string)" not defined. Make breakpoint pending on future shared library load? (y or [n]) n (gdb) =20 The problem is that the code in GDB that expands the std::string typedef hits this in c-typeprint.c: =20 /* If we have "typedef struct foo {. . .} bar;" do we want to print it as "struct foo" or as "bar"? Pick the latter for C++, because C++ folk tend to expect things like "class5 *foo" rather than "struct class5 *foo". We rather arbitrarily choose to make language_minimal work in a C-like way. */ if (language =3D=3D language_c || language =3D=3D language_minima= l) { if (type->code () =3D=3D TYPE_CODE_UNION) gdb_printf (stream, "union "); else if (type->code () =3D=3D TYPE_CODE_STRUCT) { if (type->is_declared_class ()) gdb_printf (stream, "class "); else gdb_printf (stream, "struct "); } else if (type->code () =3D=3D TYPE_CODE_ENUM) gdb_printf (stream, "enum "); } =20 I.e., std::string is expanded to "class std::..." instead of just "std::...", and then the "f(class std::..." symbol doesn't exist. =20 Fix this by making cp-support.c:inspect_type print the expanded typedef type using the language of the symbol whose type we're expanding the typedefs for -- in the example in question, the "std::string" typedef symbol, which is a C++ symbol. =20 Use type_print_raw_options as it seems to me that in this scenario we always want raw types, to match the real symbol names. =20 Adjust the gdb.cp/break-f-std-string.exp testcase to try setting a breakpoint at "f(std::string)" in both C and C++. =20 Change-Id: Ib54fab4cf0fd307bfd55bf1dd5056830096a653b Diff: --- gdb/cp-support.c | 10 +++++++++- gdb/testsuite/gdb.cp/break-f-std-string.exp | 13 ++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/gdb/cp-support.c b/gdb/cp-support.c index 71c14635e38..807c944a97c 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -41,6 +41,7 @@ #include #include "event-top.h" #include "run-on-main-thread.h" +#include "typeprint.h" =20 #define d_left(dc) (dc)->u.s_binary.left #define d_right(dc) (dc)->u.s_binary.right @@ -229,7 +230,14 @@ inspect_type (struct demangle_parse_info *info, string_file buf; try { - type_print (type, "", &buf, -1); + /* Avoid using the current language. If the language is + C, and TYPE is a struct/class, the printed type is + prefixed with "struct " or "class ", which we don't + want when we're expanding a C++ typedef. Print using + the type symbol's language to expand a C++ typedef + the C++ way even if the current language is C. */ + const language_defn *lang =3D language_def (sym->language ()); + lang->print_type (type, "", &buf, -1, 0, &type_print_raw_options); } /* If type_print threw an exception, there is little point in continuing, so just bow out gracefully. */ diff --git a/gdb/testsuite/gdb.cp/break-f-std-string.exp b/gdb/testsuite/gd= b.cp/break-f-std-string.exp index 0869912bb29..e222bae8ab3 100644 --- a/gdb/testsuite/gdb.cp/break-f-std-string.exp +++ b/gdb/testsuite/gdb.cp/break-f-std-string.exp @@ -93,10 +93,17 @@ proc test {cxx11_abi} { } } =20 - gdb_test "break f($type)" "$srcfile, line $::decimal\\." + # GDB should be able to expand the std::string typedef in the + # function prototype using C++ logic even if the current language + # is C. + foreach_with_prefix lang {"c" "c++"} { + gdb_test_no_output "set language $lang" =20 - if { $realtype !=3D "" } { - gdb_test "break f($realtype)" "$srcfile, line $::decimal\\." + gdb_test "break f($type)" "$srcfile, line $::decimal\\." + + if { $realtype !=3D "" } { + gdb_test "break f($realtype)" "$srcfile, line $::decimal\\." + } } }