diff options
author | Keith Seitz <keiths@redhat.com> | 2017-10-16 17:19:29 -0700 |
---|---|---|
committer | Keith Seitz <keiths@redhat.com> | 2017-10-16 17:19:29 -0700 |
commit | c191a6875b118fce30e7dc4d9e4bd20eff850270 (patch) | |
tree | 0561f5ba1e0a654aa2cd9f6036090215d2d47175 /gdb/testsuite | |
parent | 087ce8fa0249fa0167a73f25be51e12fb1a2b336 (diff) | |
download | gdb-c191a6875b118fce30e7dc4d9e4bd20eff850270.zip gdb-c191a6875b118fce30e7dc4d9e4bd20eff850270.tar.gz gdb-c191a6875b118fce30e7dc4d9e4bd20eff850270.tar.bz2 |
Record and output access specifiers for nested typedefs
We currently do not record access information for typedefs defined inside
classes. Consider:
struct foo
{
typedef int PUBLIC;
private:
typedef int PRIVATE;
PRIVATE b;
};
(gdb) ptype foo
type = struct foo {
private:
PRIVATE b;
typedef int PRIVATE;
typedef int PUBLIC;
}
This patch fixes this:
(gdb) ptype foo
type = struct foo {
private:
PRIVATE b;
typedef int PRIVATE;
public:
typedef int PUBLIC;
}
gdb/ChangeLog:
* c-typeprint.c (enum access_specifier): Moved here from
c_type_print_base.
(output_access_specifier): New function.
(c_type_print_base): Consider typedefs when assessing
whether access labels are needed.
Use output_access_specifier as needed.
Output access specifier for typedefs, if needed.
* dwarf2read.c (dwarf2_add_typedef): Record DW_AT_accessibility.
* gdbtypes.h (struct typedef_field) <is_protected, is_private>: New
fields.
(TYPE_TYPEDEF_FIELD_PROTECTED, TYPE_TYPEDEF_FIELD_PRIVATE): New
accessor macros.
gdb/testsuite/ChangeLog:
* gdb.cp/classes.cc (class_with_typedefs, class_with_public_typedef)
(class_with_protected_typedef, class_with_private_typedef)
(struct_with_public_typedef, struct_with_protected_typedef)
(struct_with_private_typedef): New classes/structs.
* gdb.cp/classes.exp (test_ptype_class_objects): Add tests for
typedefs and access specifiers.
Diffstat (limited to 'gdb/testsuite')
-rw-r--r-- | gdb/testsuite/gdb.cp/classes.cc | 83 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/classes.exp | 58 |
2 files changed, 141 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.cp/classes.cc b/gdb/testsuite/gdb.cp/classes.cc index 2a81473..50f0740 100644 --- a/gdb/testsuite/gdb.cp/classes.cc +++ b/gdb/testsuite/gdb.cp/classes.cc @@ -545,6 +545,82 @@ small::method () return x + 5; } +class class_with_typedefs +{ +public: + typedef int public_int; +protected: + typedef int protected_int; +private: + typedef int private_int; + +public: + class_with_typedefs () + : public_int_ (1), protected_int_ (2), private_int_ (3) {} + public_int add_public (public_int a) { return a + public_int_; } + public_int add_all (int a) + { return add_public (a) + add_protected (a) + add_private (a); } + +protected: + protected_int add_protected (protected_int a) { return a + protected_int_; } + +private: + private_int add_private (private_int a) { return a + private_int_; } + +protected: + public_int public_int_; + protected_int protected_int_; + private_int private_int_; +}; + +class class_with_public_typedef +{ + int a; +public: + typedef int INT; + INT b; +}; + +class class_with_protected_typedef +{ + int a; +protected: + typedef int INT; + INT b; +}; + +class class_with_private_typedef +{ + int a; +private: + typedef int INT; + INT b; +}; + +struct struct_with_public_typedef +{ + int a; +public: + typedef int INT; + INT b; +}; + +struct struct_with_protected_typedef +{ + int a; +protected: + typedef int INT; + INT b; +}; + +struct struct_with_private_typedef +{ + int a; +private: + typedef int INT; + INT b; +}; + void marker_reg1 () {} int @@ -624,3 +700,10 @@ protected_class protected_c; default_private_class default_private_c; explicit_private_class explicit_private_c; mixed_protection_class mixed_protection_c; +class_with_typedefs class_with_typedefs_c; +class_with_public_typedef class_with_public_typedef_c; +class_with_protected_typedef class_with_protected_typedef_c; +class_with_private_typedef class_with_private_typedef_c; +struct_with_public_typedef struct_with_public_typedef_s; +struct_with_protected_typedef struct_with_protected_typedef_s; +struct_with_private_typedef struct_with_private_typedef_s; diff --git a/gdb/testsuite/gdb.cp/classes.exp b/gdb/testsuite/gdb.cp/classes.exp index 256fa68..9e2630a 100644 --- a/gdb/testsuite/gdb.cp/classes.exp +++ b/gdb/testsuite/gdb.cp/classes.exp @@ -316,6 +316,64 @@ proc test_ptype_class_objects {} { { field public "int y;" } { method public "DynamicBar(int, int);" } } + + # Classes with typedefs of different access. + + cp_test_ptype_class \ + "class class_with_typedefs" "" "class" "class_with_typedefs" \ + { + { field protected \ + "class_with_typedefs::public_int public_int_;" } + { field protected \ + "class_with_typedefs::protected_int protected_int_;" } + { field protected \ + "class_with_typedefs::private_int private_int_;" } + { method public "class_with_typedefs(void);" } + { method public "class_with_typedefs::public_int add_public(class_with_typedefs::public_int);" } + { method public \ + "class_with_typedefs::public_int add_all(int);" } + { method protected "class_with_typedefs::protected_int add_protected(class_with_typedefs::protected_int);" } + { method private "class_with_typedefs::private_int add_private(class_with_typedefs::private_int);" } + { typedef public "typedef int public_int;" } + { typedef protected "typedef int protected_int;" } + { typedef private "typedef int private_int;" } + } + + cp_test_ptype_class \ + "class class_with_public_typedef" "" "class" \ + "class_with_public_typedef" { + { field private "int a;" } + { field public "class_with_public_typedef::INT b;" } + { typedef public "typedef int INT;" } + } + cp_test_ptype_class \ + "class class_with_protected_typedef" "" "class" \ + "class_with_protected_typedef" { + { field private "int a;" } + { field protected "class_with_protected_typedef::INT b;" } + { typedef protected "typedef int INT;" } + } + cp_test_ptype_class \ + "struct struct_with_protected_typedef" "" "struct" \ + "struct_with_protected_typedef" { + { field public "int a;" } + { field protected "struct_with_protected_typedef::INT b;" } + { typedef protected "typedef int INT;" } + } + cp_test_ptype_class \ + "struct struct_with_private_typedef" "" "struct" \ + "struct_with_private_typedef" { + { field public "int a;" } + { field private "struct_with_private_typedef::INT b;" } + { typedef private "typedef int INT;" } + } + + # For the following two cases, we cannot use cp_test_ptype_class. + # We need to explicitly check whether the access label was suppressed. + set ws {[ \t\r\n]*} + foreach {tag lbl} {"class" "private" "struct" "public"} { + gdb_test "ptype/r ${tag}_with_${lbl}_typedef" "type = $tag ${tag}_with_${lbl}_typedef \{${ws}int a;${ws}${tag}_with_${lbl}_typedef::INT b;${ws}typedef int INT;${ws}\}" + } } # Test simple access to class members. |