From c8ba13ad37c98262b94f99cc4f84ac0066c48cc2 Mon Sep 17 00:00:00 2001 From: Keith Seitz Date: Wed, 18 Oct 2017 11:05:45 -0700 Subject: [PATCH] Canonicalize conversion operators Consider a conversion operator such as: operator foo const* const* (); There are two small parser problems, highlighted by this test: (gdb) p operator foo const* const* There is no field named operatorfoo const* const * GDB is looking up the symbol "operatorfoo const* const*" -- it is missing a space between the keyword "operator" and the type name "foo const* const*". Additionally, this input of the user-defined type needs to be canonicalized so that different "spellings" of the type are recognized: (gdb) p operator const foo* const * There is no field named operator const foo* const * gdb/ChangeLog: * c-exp.y (oper): Canonicalize conversion operators of user-defined types. Add whitespace to front of type name. gdb/testsuite/ChangeLog: * gdb.cp/cpexprs.cc (base) : New method. (main): Call it. * gdb.cp/cpexprs.exp: Add new conversion operator to test matrix. Add additional user-defined conversion operator tests. --- gdb/ChangeLog | 6 ++++++ gdb/c-exp.y | 10 ++++++++-- gdb/testsuite/ChangeLog | 8 ++++++++ gdb/testsuite/gdb.cp/cpexprs.cc | 2 ++ gdb/testsuite/gdb.cp/cpexprs.exp | 16 ++++++++++++++++ 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b588641990..bbb0aab419 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2017-11-18 Keith Seitz + + * c-exp.y (oper): Canonicalize conversion operators of user-defined + types. + Add whitespace to front of type name. + 2017-10-18 Keith Seitz * dwarf2read.c (dwarf2_add_typedef): Issue a complaint on unhandled diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 7c050b4ce7..18c74d8a17 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -1554,7 +1554,7 @@ oper: OPERATOR NEW | OPERATOR '>' { $$ = operator_stoken (">"); } | OPERATOR ASSIGN_MODIFY - { const char *op = "unknown"; + { const char *op = " unknown"; switch ($2) { case BINOP_RSH: @@ -1630,7 +1630,13 @@ oper: OPERATOR NEW c_print_type ($2, NULL, &buf, -1, 0, &type_print_raw_options); - $$ = operator_stoken (buf.c_str ()); + + /* This also needs canonicalization. */ + std::string canon + = cp_canonicalize_string (buf.c_str ()); + if (canon.empty ()) + canon = std::move (buf.string ()); + $$ = operator_stoken ((" " + canon).c_str ()); } ; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index ddfce31253..de136451e6 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2017-11-18 Keith Seitz + + * gdb.cp/cpexprs.cc (base) : New + method. + (main): Call it. + * gdb.cp/cpexprs.exp: Add new conversion operator to test matrix. + Add additional user-defined conversion operator tests. + 2017-10-17 Pedro Alves * boards/native-stdio-gdbserver.exp: Load "local-board". diff --git a/gdb/testsuite/gdb.cp/cpexprs.cc b/gdb/testsuite/gdb.cp/cpexprs.cc index f70fd51603..a2364ebe91 100644 --- a/gdb/testsuite/gdb.cp/cpexprs.cc +++ b/gdb/testsuite/gdb.cp/cpexprs.cc @@ -270,6 +270,7 @@ public: operator int () const { return 21; } // base::operator int operator fluff* () const { return new fluff (); } // base::operator fluff* operator fluff** () const { return &g_fluff; } // base::operator fluff** + operator fluff const* const* () const { return &g_fluff; } // base::operator fluff const* const* }; class base1 : public virtual base @@ -448,6 +449,7 @@ test_function (int argc, char* argv[]) // test_function char* str = a; fluff* flp = a; fluff** flpp = a; + fluff const* const* flcpcp = a; CV_f(CV::i); diff --git a/gdb/testsuite/gdb.cp/cpexprs.exp b/gdb/testsuite/gdb.cp/cpexprs.exp index d0f41b2d8e..463e89c12c 100644 --- a/gdb/testsuite/gdb.cp/cpexprs.exp +++ b/gdb/testsuite/gdb.cp/cpexprs.exp @@ -407,6 +407,10 @@ add {base::operator int} \ {int (const base * const)} \ - \ - +add {base::operator fluff const* const*} \ + {const fluff * const *(const base * const)} \ + - \ + - # Templates add {tclass::do_something} \ @@ -746,5 +750,17 @@ gdb_test "p CV_f(CV::i)" " = 43" gdb_test "p CV_f('cpexprs.cc'::CV::t)" \ { = {int \(int\)} 0x[0-9a-f]+ } +# Make sure conversion operator names are canonicalized and properly +# "spelled." +gdb_test "p base::operator const fluff * const *" \ + [get "base::operator fluff const* const*" print] \ + "canonicalized conversion operator name 1" +gdb_test "p base::operator const fluff* const*" \ + [get "base::operator fluff const* const*" print] \ + "canonicalized conversion operator name 2" +gdb_test "p base::operator derived*" \ + "There is no field named operator derived\\*" \ + "undefined conversion operator" + gdb_exit return 0