From 3eac77a50024b49ee89436fa6f18c30ed64c3eeb Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 27 Oct 2023 10:58:00 -0600 Subject: [PATCH] Simplify C++ type-printing The C++ type-printing code had its own variant of the accessibility enum. This patch removes this and changes the code to use the new one from gdbtypes.h. This patch also changes the C++ code to recognize the default accessibility of a class. This makes ptype a bit more C++-like, and lets us remove a chunk of questionable code. Acked-By: Simon Marchi Reviewed-by: Keith Seitz --- gdb/c-typeprint.c | 136 +++++------------------ gdb/testsuite/gdb.base/ptype-offsets.exp | 6 - 2 files changed, 30 insertions(+), 112 deletions(-) diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c index 4a0c6950b0c..3402c783cce 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -33,16 +33,6 @@ #include "cp-abi.h" #include "cp-support.h" -/* A list of access specifiers used for printing. */ - -enum access_specifier -{ - s_none, - s_public, - s_private, - s_protected -}; - static void c_type_print_varspec_suffix (struct type *, struct ui_file *, int, int, int, enum language, @@ -866,85 +856,32 @@ print_spaces_filtered_with_print_options /* Output an access specifier to STREAM, if needed. LAST_ACCESS is the last access specifier output (typically returned by this function). */ -static enum access_specifier +static accessibility output_access_specifier (struct ui_file *stream, - enum access_specifier last_access, - int level, bool is_protected, bool is_private, + accessibility last_access, + int level, accessibility new_access, const struct type_print_options *flags) { - if (is_protected) + if (last_access == new_access) + return new_access; + + if (new_access == accessibility::PROTECTED) { - if (last_access != s_protected) - { - last_access = s_protected; - print_spaces_filtered_with_print_options (level + 2, stream, flags); - gdb_printf (stream, "protected:\n"); - } + print_spaces_filtered_with_print_options (level + 2, stream, flags); + gdb_printf (stream, "protected:\n"); } - else if (is_private) + else if (new_access == accessibility::PRIVATE) { - if (last_access != s_private) - { - last_access = s_private; - print_spaces_filtered_with_print_options (level + 2, stream, flags); - gdb_printf (stream, "private:\n"); - } + print_spaces_filtered_with_print_options (level + 2, stream, flags); + gdb_printf (stream, "private:\n"); } else { - if (last_access != s_public) - { - last_access = s_public; - print_spaces_filtered_with_print_options (level + 2, stream, flags); - gdb_printf (stream, "public:\n"); - } + print_spaces_filtered_with_print_options (level + 2, stream, flags); + gdb_printf (stream, "public:\n"); } - return last_access; -} - -/* Return true if an access label (i.e., "public:", "private:", - "protected:") needs to be printed for TYPE. */ - -static bool -need_access_label_p (struct type *type) -{ - if (type->is_declared_class ()) - { - for (int i = TYPE_N_BASECLASSES (type); i < type->num_fields (); i++) - if (!type->field (i).is_private ()) - return true; - for (int j = 0; j < TYPE_NFN_FIELDS (type); j++) - for (int i = 0; i < TYPE_FN_FIELDLIST_LENGTH (type, j); i++) - if (!TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type, - j), i)) - return true; - for (int i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); ++i) - if (!TYPE_TYPEDEF_FIELD_PRIVATE (type, i)) - return true; - } - else - { - for (int i = TYPE_N_BASECLASSES (type); i < type->num_fields (); i++) - if (!type->field (i).is_public ()) - return true; - for (int j = 0; j < TYPE_NFN_FIELDS (type); j++) - { - for (int i = 0; i < TYPE_FN_FIELDLIST_LENGTH (type, j); i++) - if (TYPE_FN_FIELD_PROTECTED (TYPE_FN_FIELDLIST1 (type, - j), i) - || TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type, - j), - i)) - return true; - } - for (int i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); ++i) - if (TYPE_TYPEDEF_FIELD_PROTECTED (type, i) - || TYPE_TYPEDEF_FIELD_PRIVATE (type, i)) - return true; - } - - return false; + return new_access; } /* Helper function that temporarily disables FLAGS->PRINT_OFFSETS, @@ -1067,17 +1004,9 @@ c_type_print_base_struct_union (struct type *type, struct ui_file *stream, metadata_style.style ().ptr (), nullptr); } - /* Start off with no specific section type, so we can print - one for the first field we find, and use that section type - thereafter until we find another type. */ - - enum access_specifier section_type = s_none; - - /* For a class, if all members are private, there's no need - for a "private:" label; similarly, for a struct or union - masquerading as a class, if all members are public, there's - no need for a "public:" label. */ - bool need_access_label = need_access_label_p (type); + accessibility section_type = (type->is_declared_class () + ? accessibility::PRIVATE + : accessibility::PUBLIC); /* If there is a base class for this type, do not print the field that it occupies. */ @@ -1098,13 +1027,10 @@ c_type_print_base_struct_union (struct type *type, struct ui_file *stream, || type->field (i).is_artificial ()) continue; - if (need_access_label) - { - section_type = output_access_specifier - (stream, section_type, level, - type->field (i).is_protected (), - type->field (i).is_private (), flags); - } + section_type + = output_access_specifier (stream, section_type, level, + type->field (i).accessibility (), + flags); bool is_static = type->field (i).is_static (); @@ -1176,7 +1102,7 @@ c_type_print_base_struct_union (struct type *type, struct ui_file *stream, if (!TYPE_FN_FIELD_ARTIFICIAL (f, j)) real_len++; } - if (real_len > 0 && section_type != s_none) + if (real_len > 0) gdb_printf (stream, "\n"); /* C++: print out the methods. */ @@ -1207,8 +1133,8 @@ c_type_print_base_struct_union (struct type *type, struct ui_file *stream, QUIT; section_type = output_access_specifier (stream, section_type, level, - TYPE_FN_FIELD_PROTECTED (f, j), - TYPE_FN_FIELD_PRIVATE (f, j), flags); + TYPE_FN_FIELD (f, j).accessibility, + flags); print_spaces_filtered_with_print_options (level + 4, stream, flags); @@ -1334,13 +1260,11 @@ c_type_print_base_struct_union (struct type *type, struct ui_file *stream, gdb_assert (target->code () == TYPE_CODE_TYPEDEF); target = target->target_type (); - if (need_access_label) - { - section_type = output_access_specifier - (stream, section_type, level, - TYPE_TYPEDEF_FIELD_PROTECTED (type, i), - TYPE_TYPEDEF_FIELD_PRIVATE (type, i), flags); - } + section_type = (output_access_specifier + (stream, section_type, level, + TYPE_TYPEDEF_FIELD (type, i).accessibility, + flags)); + print_spaces_filtered_with_print_options (level + 4, stream, flags); gdb_printf (stream, "typedef "); diff --git a/gdb/testsuite/gdb.base/ptype-offsets.exp b/gdb/testsuite/gdb.base/ptype-offsets.exp index 2cfc70f1686..f36bd2fdedf 100644 --- a/gdb/testsuite/gdb.base/ptype-offsets.exp +++ b/gdb/testsuite/gdb.base/ptype-offsets.exp @@ -36,7 +36,6 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile \ gdb_test "ptype /o struct abc" \ [string_to_regexp [multi_line \ "/* offset | size */ type = struct abc \{" \ -" public:" \ "/* 8 | 8 */ void *field1;" \ "/* 16: 0 | 4 */ unsigned int field2 : 1;" \ "/* XXX 7-bit hole */" \ @@ -61,7 +60,6 @@ gdb_test "ptype /o struct abc" \ gdb_test "ptype /ox struct abc" \ [string_to_regexp [multi_line \ "/* offset | size */ type = struct abc {" \ -" public:" \ "/* 0x0008 | 0x0008 */ void *field1;" \ "/* 0x0010: 0x0 | 0x0004 */ unsigned int field2 : 1;" \ "/* XXX 7-bit hole */" \ @@ -86,7 +84,6 @@ gdb_test "ptype /ox struct abc" \ gdb_test "ptype /oTM struct abc" \ [string_to_regexp [multi_line \ "/* offset | size */ type = struct abc \{" \ -" public:" \ "/* 8 | 8 */ void *field1;" \ "/* 16: 0 | 4 */ unsigned int field2 : 1;" \ "/* XXX 7-bit hole */" \ @@ -116,7 +113,6 @@ gdb_test "ptype /oTM struct abc" \ gdb_test "ptype /TMo struct abc" \ [string_to_regexp [multi_line \ "/* offset | size */ type = struct abc \{" \ -" public:" \ "/* 8 | 8 */ void *field1;" \ "/* 16: 0 | 4 */ unsigned int field2 : 1;" \ "/* XXX 7-bit hole */" \ @@ -421,7 +417,6 @@ with_test_prefix "with_hex_default" { gdb_test "ptype /o struct abc" \ [string_to_regexp [multi_line \ "/* offset | size */ type = struct abc \{" \ - " public:" \ "/* 0x0008 | 0x0008 */ void *field1;" \ "/* 0x0010: 0x0 | 0x0004 */ unsigned int field2 : 1;" \ "/* XXX 7-bit hole */" \ @@ -445,7 +440,6 @@ with_test_prefix "with_hex_default" { gdb_test "ptype /od struct abc" \ [string_to_regexp [multi_line \ "/* offset | size */ type = struct abc \{" \ - " public:" \ "/* 8 | 8 */ void *field1;" \ "/* 16: 0 | 4 */ unsigned int field2 : 1;" \ "/* XXX 7-bit hole */" \