From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11379 invoked by alias); 16 Oct 2017 19:57:04 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 11365 invoked by uid 89); 16 Oct 2017 19:57:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.3 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_PASS autolearn=ham version=3.3.2 spammy=3166, 10346, Hx-spam-relays-external:sk:EUR02-V, H*RU:sk:EUR02-V X-HELO: sessmg23.ericsson.net Received: from sessmg23.ericsson.net (HELO sessmg23.ericsson.net) (193.180.251.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 16 Oct 2017 19:57:00 +0000 Received: from ESESSHC021.ericsson.se (Unknown_Domain [153.88.183.81]) by sessmg23.ericsson.net (Symantec Mail Security) with SMTP id E7.A3.09869.A0F05E95; Mon, 16 Oct 2017 21:56:58 +0200 (CEST) Received: from EUR02-VE1-obe.outbound.protection.outlook.com (153.88.183.145) by oa.msg.ericsson.com (153.88.183.81) with Microsoft SMTP Server (TLS) id 14.3.352.0; Mon, 16 Oct 2017 21:56:58 +0200 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=simon.marchi@ericsson.com; Received: from [142.133.49.59] (192.75.88.130) by AM3PR07MB308.eurprd07.prod.outlook.com (2a01:111:e400:881b::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.77.5; Mon, 16 Oct 2017 19:56:55 +0000 Subject: Re: [PATCH] Record and output access specifiers for nested typedefs To: Keith Seitz , References: <1507922334-13603-1-git-send-email-keiths@redhat.com> From: Simon Marchi Message-ID: Date: Mon, 16 Oct 2017 19:57:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 In-Reply-To: <1507922334-13603-1-git-send-email-keiths@redhat.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-ClientProxiedBy: DM5PR16CA0007.namprd16.prod.outlook.com (2603:10b6:3:c0::17) To AM3PR07MB308.eurprd07.prod.outlook.com (2a01:111:e400:881b::19) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 45f07d5c-ccbb-4c22-a91c-08d514d00e1f X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(2017030254152)(2017052603199)(201703131423075)(201703031133081)(201702281549075);SRVR:AM3PR07MB308; X-Microsoft-Exchange-Diagnostics: 1;AM3PR07MB308;3:vSeuGSXUPkFdSoX735Lkk4z7HSaK03J3rQxLI6je5/rb9njkEm4qG7h1aiFrNebHSObiP4uVV4BwWkp5h4hBFKgOewUlV2tye1aEbWTyEM0gZ9wiXjgoaivDbQRpqkwVqvfy9/8bv1XBAZKTmMTYIfWon5TbuzPk2GMLFZ8DiW67O3iCYT0j4s+RDqCBer4qdQ70S+gitQUgart/EkjrnBsd6JH84XbGNGr0WcbCDLfhiVuExYnkLuNm2zJWZ0Ak;25:10+lRfpFDax1qNq4NJ73RQPBk7NtZZRO1wdIaBgM+EWddW2MvS2iHho7ZVTvpNJv6uHSiyJ3OqgfytVx1CQ/Nik9Io8PjDJdrB/C9hmNR8M0uupnvQXvXRNpSDvdRzpnPho5d6YLOP3IcjrKyheBXN3ZVp6xuBre+6VEIHBKjAnrBoc5WOIPUY2rzWX0AOd46RUG7Hn2W+ZFOFekLm5YUwVmVMAUWd1zWguEQM1j4hiiek9Ajm7HQfDOjFB/8EgIvi9r1e+fn3cZJYOLMCwm9svezr9OnfUdVzXeJF4BA0twlTFW+BaicdWsr6uMd9JHrySu/MBttrbJ36MF2U7io2iyJWzJH4LevPuT6CYY2zY=;31:7MWzMK8R2NxDbdcXXH+V+k9MqxZRL4uFluyWMP555NDjhWWHrKAQWejruJEJ+3zzbYfa8LF7BVjA5seXi6dKIVgzm1oGoyBfwhyuZX8+4lybzmpyqmGoOPbivkUZdf6VqLPeja+J3xDKFrpNkdmAvCxxKipuyqcFIc+n7xn/TFfQaHbpSxG1BGhvyoB2Mv2eaGRSTuP8j5nmtmiCYucEPQ4nL2LCRno7BXXx9kEfE6s= X-MS-TrafficTypeDiagnostic: AM3PR07MB308: X-Microsoft-Exchange-Diagnostics: 1;AM3PR07MB308;20:Hcq52guRNhXnkeaoVlKefzTIBxdHuh4WdEsvIfwP1hde8RnGdwRdHjXGzVRrZy3iIjsd+cIxGvIqEbWqnzW4KvoKVqCmvl8XdsSyV4QL9FP8T+FbR/LAWh5pSCY8R++YeX4lBfDG+mVwvqy7MzRhWdjGAwU/kwwBQz/ST8Uf7gVGf7J+Z6UuwfVIKjlDJDOjsd8BSx/cQuOMwJOOElC/GVYPwPWHSBuVEQwnWz9pD0Oq4bpveUMqViWm8WPJKEukymgLqO/IsRM6iUNYKPtwxozDPQPaCBTBKUYs85DmLe16wS+MNFuo39m4w9ssMIrKSPPEJDxUXAlFH+4/CsaYz4jYh/uxkk0dJxkV77SmyQvL8bgE88pk4pHhBSa3H+cQKuiGA37HeEOw2kL7hV3UrhV4IxKQKjP8YB5sUe2be4t+pZ3IVOoZvTf69X1aG6waxqKxrfqNIVGnP881Q2/tVK3ktbkWNE0gnTL6GZu8u/NpdROmYPE29g1YgKTfrvTA;4:ldo/ZNOicw88Pt5kryFQvPj5tzFL4c32G0u2YjC9msT4CAzsn5aga3Jz+VmWrKlmT8BERK1Y9ukYuiNEzzKDHz0PQWght3Hppd+haMlPVIK/ZOxpXc2fw8MXMj4TdT2ixPFAevGuONa06FeNFvUA1x6l1IhEYMxwGeOxfKLgdnfifrW4SmGqeEDxPti6fhxifRNjPs0zxcaSis+W/lysfqze9yDLb+XhOSh44bK/aSBCR+vp6sudl83veFbi+3QuoFJiAsqaHpVdCKRMcML7IoE/nVoZYEByXU68WFkOMIw= X-Exchange-Antispam-Report-Test: UriScan:(17755550239193); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(8121501046)(5005006)(3002001)(100000703101)(100105400095)(93006095)(93001095)(10201501046)(6041248)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123560025)(20161123558100)(20161123564025)(20161123555025)(20161123562025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:AM3PR07MB308;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:AM3PR07MB308; X-Forefront-PRVS: 0462918D61 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6009001)(6049001)(346002)(376002)(39860400002)(24454002)(54534003)(189002)(199003)(377424004)(377454003)(36756003)(65956001)(65806001)(66066001)(97736004)(64126003)(47776003)(16576012)(16526018)(6666003)(478600001)(53546010)(4001150100001)(2950100002)(6486002)(189998001)(230700001)(31686004)(58126008)(49976008)(101416001)(25786009)(316002)(83506001)(33646002)(81166006)(8676002)(7736002)(2906002)(575784001)(86362001)(305945005)(76176999)(81156014)(54356999)(50986999)(23676002)(31696002)(229853002)(50466002)(6246003)(65826007)(105586002)(6116002)(68736007)(106356001)(8936002)(53936002)(3846002)(5660300001)(78286006);DIR:OUT;SFP:1101;SCL:1;SRVR:AM3PR07MB308;H:[142.133.49.59];FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; Received-SPF: None (protection.outlook.com: ericsson.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtBTTNQUjA3TUIzMDg7MjM6dzZmZElJdnZoSkd0ODY3a1k5eHR2TjNYTld5?= =?utf-8?B?ZUxjZjBsTHI2SHJqa2NWTVVyaXhHQnJvNGpnaW52M3pVWnUvd1ZxM1FSZFls?= =?utf-8?B?ZWFWalg3ak1LWmQ5SE8wMFA3M3ZLcmQ4d3VpSm1qdG1FUWxPWTR0Y1ZmVnlY?= =?utf-8?B?NzNWR3p0a2pYQmU4YVFFeW1HUkF0VXZRWGV3MTd0UEt3MVJjR2J3a0UwRFls?= =?utf-8?B?NXg1emhnUHFhK1Z3NjAxNUhhR1RHR1R0QVdqOENJOXp5cjlMa28vcFRuQ2dB?= =?utf-8?B?N3RYZVBWS28rRmVkelNCWWlxZzFqdFB5UHlmZFJubXdmNjVUMzNOSE5ZMmRt?= =?utf-8?B?QlRUbDBNTEVSTUYvb2NrbGsrckc5OHEyemN0VzBKQTJuMVIzRzNtYjZpSE1D?= =?utf-8?B?Y0ZEWXVFQjgvMnlqTGJKb0pOZTkzU1BCNWVTMFlRbG52TFFvd25OQ0dhMjVT?= =?utf-8?B?L29lNCt2TmZNMGdmVnBTcW1GY0hLRDJ4TE0vRllXQmtEWXh0MVVpR25jSUtR?= =?utf-8?B?bjFFSU13WXloRXB2OVd4K3huakc2MHlSYkdnd0plL3h2OEh0cFZwOVRLSExM?= =?utf-8?B?ei9PTUs4NDZoMS85TGltOVZkdldBa2VTVGttRTJOOHhPZktQUW5QRU5lZ2xN?= =?utf-8?B?RmtGTUUweHBtOXUwTnpXQkErNTJmYStXaVJ0RGkwZkRaTFNqVnd1dG5TOVFw?= =?utf-8?B?YmlvZTdxSXNVWjZpMGtXVzRWdGdoaEVKU1NVdmM5bnRWc1JqTHFoV3ZYL1pY?= =?utf-8?B?RjNvM2xLNEVnTzE1ejhNVGx5dXArV25vdmtCUUNtMVJ1bXFJNVluWEw3SSta?= =?utf-8?B?a0RSUkxpVUJoKzJtOXhLaU1pVWM1M3VrMGhiMlozYkxRelBMeks4bjFzcXlW?= =?utf-8?B?WGRsRFh0bGwrRmNxUzgwSEhxT2p5emNjUmZZejk4MnpNRm9HL1ZHTnpyaExX?= =?utf-8?B?S3N0bkNFbmI0cy93cVVMbitxSG1vWVRlM3pmb0VoUGcwaFVqcE9QY1JRQjg1?= =?utf-8?B?T2hEWU5BclgwVjc2aE00QitScXd1M2JVd2l1dHBnOWJsMGZVVzJsRzN1Mk9E?= =?utf-8?B?UisyMGF3YkZ5Z1hpTENuNXhuT1QvemV3bkVpcGtDcWZJZTdrWVhwalRIenhJ?= =?utf-8?B?bVpMZFRNaUNaVmhmSW1lbUE1N0hVNm5USnh3YitKZllCc0tGS25JTDVRa0Ny?= =?utf-8?B?ODNOSUJvWHJmdmpadFk4aTlmYVNmS1k0dEdzYnVjT2hwTk9RaXBmVEdNM2kx?= =?utf-8?B?WEZ4NHd0aEpOMnRPc2p5d2JUR2xCMjdwTnZ2c3c1Z3FmZTdCdHVxTDc0YXNK?= =?utf-8?B?TW5XUk5GcGNUVnNCNHdIMnNQWW9rNGxmSk93NzIwRmJWN21nSUJvQlBFTDYw?= =?utf-8?B?WUtJeVJjd0UzQXNIRzNJcEl3S25TVDJoSVRESVF5cmRFOVZlQVNqZkh6UFMy?= =?utf-8?B?d2x3blRwcGVpYndRUG4xN3AyMVlXUnkwaEE0RUFsNTRHYzhyYkZRRThaMTZG?= =?utf-8?B?VDhNeGhTcTAxZVlhYWpDcjRRUm9vdjZhZWVVNGlZL3QxU05hWGEzeEdTTUdY?= =?utf-8?B?RjUvdG95Y1J1cDYrbm13VXpTeVNaU0lwY2hSTmFWRDBRTENJR2YzVk1XeVZV?= =?utf-8?B?L0NaTlNmdTFRK0lqUk4wZFpYRHR4NDViZy9KK0FBYUZrajVvcnFJU2tsWWgx?= =?utf-8?B?S0JrUi91RU5zaUI4V2NXMVlvckQyMGR3N0Nvak03Ymxqb2JXeWkvZ1BCSUJw?= =?utf-8?B?b054SHVtVkhtWXBtS211N1Myd2RBVzkyM0JldUxNMTB0czVKNERmSDBpeWhC?= =?utf-8?B?Y2RhTzh0TUxYN0tuNVJPNEVsVGhYYlVTWWUySytaT1NpbzF3TDIxd2h0Zktm?= =?utf-8?B?R3hFcnFtTzFDdGNubUFWTDNuN29DOE9xWXJNQkhXemZ2eTl5emhsTWJjYjFO?= =?utf-8?Q?u5N3MegYLGzSV8w4xhTWYe86X+Tis=3D?= X-Microsoft-Exchange-Diagnostics: 1;AM3PR07MB308;6:VcmigF1uqMqIAcwygIRHG/UY5qZffns4HkvGkv7LCA79FGyXOUfDM2TZjrtBdrrJr5wM3U0BJp/qds8YDbyVSYKdWcD3/f+maZNFmKiLrjk+JkYWgSicfANhD/Qlx9Vq0G3LVY97R6wmf5YexEND+XPXE8PgvAm1QSchWDdVBHxGoMYdMCCmrUzwCWRvtwi2HeH0osYYEU3DnlrrLL9TAQ8jHfbcEDTj+g1DiDwpGRQiIpcLCi+xUpHm+JlVWbrgB+F7l16PWd1uhR7plppsE1HZlKK45Y4iK8SvAk9u+yRMynl32mmu0fx3jNAb+DMaLbKJIcBJxGewxrmwJZU1iQ==;5:Wxi5D6Z4dLrF8d0frAwfMuyLWcGbZNVLEBLDTFzULA0rnjF9l2B08o/lJBxC7DxVO1wn1HPv/Wq5pqmx9GitVNZA0FP+EcxXfD8Peind974ZB17wZqmsQUnxZieMYGBSuv4qkuyjeYQQZfpLtZcG8g==;24:l5mSY4M/jHp3Tks+sUDP/fL7XiqhaPryCWX1j4KYTUMlNK+3c7LNIwWHvEX9XoIHwnl1bzL1TRLVw5RAwJzVBX7vgBkkY6GHw0v8Hzl12D4=;7:Rao9E/BN8Rg+o7chwU0Uph8Ux4KH7mrfF4hNmJFaaxD+Kks0NJfGCMYRYwQ2sUZ+L5yM5ycKDl7S8HT459TLRNiAE6uuOx+Tkvjha5KlITl/iTfIAey7V24w8PGJlGeiL6FzCrlWMrYzotgwzTBGzzjDwaYwS87Ap/dACutzo/ljeJUCqRGnLOHMx75wtT0/b6P6AHHGo6yBkfrh8J2hVO8btBnE8rz2o5R+E//57WI= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Oct 2017 19:56:55.9095 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 92e84ceb-fbfd-47ab-be52-080c6b87953f X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM3PR07MB308 X-OriginatorOrg: ericsson.com X-IsSubscribed: yes X-SW-Source: 2017-10/txt/msg00463.txt.bz2 On 2017-10-13 03:18 PM, Keith Seitz wrote: > 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; > } Hi Keith, I just have a few minor comments. > 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) : New > fields. > (TYPE_TYPEDEF_FIELD_PROTECTED, TYPE_TYEPDEF_FIELD_PRIVATE): New "TYPE_TYEPDEF_FIELD_PRIVATE" > 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. > --- > gdb/c-typeprint.c | 145 +++++++++++++++++++++++---------------- > gdb/dwarf2read.c | 22 ++++++ > gdb/gdbtypes.h | 11 +++ > gdb/testsuite/gdb.cp/classes.cc | 83 ++++++++++++++++++++++ > gdb/testsuite/gdb.cp/classes.exp | 58 ++++++++++++++++ > 5 files changed, 259 insertions(+), 60 deletions(-) > > diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c > index 978fcc4..3dc74f9 100644 > --- a/gdb/c-typeprint.c > +++ b/gdb/c-typeprint.c > @@ -32,6 +32,16 @@ > #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_prefix (struct type *, > struct ui_file *, > int, int, int, > @@ -826,7 +836,42 @@ c_type_print_template_args (const struct type_print_options *flags, > fputs_filtered (_("] "), stream); > } > > -/* Print the name of the type (or the ultimate pointer target, > +/* Output an access specifier to STREAM, if needed. */ > + > +static void > +output_access_specifier (struct ui_file *stream, enum access_specifier &access, > + int level, bool is_protected, bool is_private) I would suggest renaming access it to last_access or previous_access. Could you also document it in the function comment? It might also be clearer to have output_access_specifier return the access_specifier, rather than modifying the passed value directly. Otherwise, it's not really obvious what's happening in the caller. > +{ > + if (is_protected) > + { > + if (access != s_protected) > + { > + access = s_protected; > + fprintfi_filtered (level + 2, stream, > + "protected:\n"); > + } > + } > + else if (is_private) > + { > + if (access != s_private) > + { > + access = s_private; > + fprintfi_filtered (level + 2, stream, > + "private:\n"); > + } > + } > + else > + { > + if (access != s_public) > + { > + access = s_public; > + fprintfi_filtered (level + 2, stream, > + "public:\n"); > + } > + } > +} > + > + /* Print the name of the type (or the ultimate pointer target, Spurious indent change on that last line. > function value or array element), or the description of a structure > or union. > > @@ -850,11 +895,7 @@ c_type_print_base (struct type *type, struct ui_file *stream, > { > int i; > int len, real_len; > - enum > - { > - s_none, s_public, s_private, s_protected > - } > - section_type; > + enum access_specifier section_type; > int need_access_label = 0; > int j, len2; > > @@ -1034,6 +1075,18 @@ c_type_print_base (struct type *type, struct ui_file *stream, > break; > } > } > + QUIT; > + if (!need_access_label) > + { > + for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); ++i) > + { > + if (!TYPE_TYPEDEF_FIELD_PRIVATE (type, i)) > + { > + need_access_label = 1; > + break; > + } > + } > + } > } > else > { > @@ -1068,6 +1121,19 @@ c_type_print_base (struct type *type, struct ui_file *stream, > break; > } > } > + QUIT; > + if (!need_access_label) > + { > + for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); ++i) > + { > + if (TYPE_TYPEDEF_FIELD_PROTECTED (type, i) > + || TYPE_TYPEDEF_FIELD_PRIVATE (type, i)) > + { > + need_access_label = 1; > + break; > + } > + } > + } > } > > /* If there is a base class for this type, > @@ -1088,33 +1154,9 @@ c_type_print_base (struct type *type, struct ui_file *stream, > > if (need_access_label) > { > - if (TYPE_FIELD_PROTECTED (type, i)) > - { > - if (section_type != s_protected) > - { > - section_type = s_protected; > - fprintfi_filtered (level + 2, stream, > - "protected:\n"); > - } > - } > - else if (TYPE_FIELD_PRIVATE (type, i)) > - { > - if (section_type != s_private) > - { > - section_type = s_private; > - fprintfi_filtered (level + 2, stream, > - "private:\n"); > - } > - } > - else > - { > - if (section_type != s_public) > - { > - section_type = s_public; > - fprintfi_filtered (level + 2, stream, > - "public:\n"); > - } > - } > + output_access_specifier (stream, section_type, level, > + TYPE_FIELD_PROTECTED (type, i), > + TYPE_FIELD_PRIVATE (type, i)); > } > > print_spaces_filtered (level + 4, stream); > @@ -1188,33 +1230,9 @@ c_type_print_base (struct type *type, struct ui_file *stream, > inner_cleanup = make_cleanup (null_cleanup, NULL); > > QUIT; > - if (TYPE_FN_FIELD_PROTECTED (f, j)) > - { > - if (section_type != s_protected) > - { > - section_type = s_protected; > - fprintfi_filtered (level + 2, stream, > - "protected:\n"); > - } > - } > - else if (TYPE_FN_FIELD_PRIVATE (f, j)) > - { > - if (section_type != s_private) > - { > - section_type = s_private; > - fprintfi_filtered (level + 2, stream, > - "private:\n"); > - } > - } > - else > - { > - if (section_type != s_public) > - { > - section_type = s_public; > - fprintfi_filtered (level + 2, stream, > - "public:\n"); > - } > - } > + output_access_specifier (stream, section_type, level, > + TYPE_FN_FIELD_PROTECTED (f, j), > + TYPE_FN_FIELD_PRIVATE (f, j)); > > print_spaces_filtered (level + 4, stream); > if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) > @@ -1326,6 +1344,13 @@ c_type_print_base (struct type *type, struct ui_file *stream, > gdb_assert (TYPE_CODE (target) == TYPE_CODE_TYPEDEF); > target = TYPE_TARGET_TYPE (target); > > + if (need_access_label) > + { > + output_access_specifier > + (stream, section_type, level, > + TYPE_TYPEDEF_FIELD_PROTECTED (type, i), > + TYPE_TYPEDEF_FIELD_PRIVATE (type, i)); > + } > print_spaces_filtered (level + 4, stream); > fprintf_filtered (stream, "typedef "); > > diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c > index 9bdb75d..c0200f9 100644 > --- a/gdb/dwarf2read.c > +++ b/gdb/dwarf2read.c > @@ -13274,6 +13274,28 @@ dwarf2_add_typedef (struct field_info *fip, struct die_info *die, > > fp->type = read_type_die (die, cu); > > + /* Save accessibility. */ > + enum dwarf_access_attribute accessibility; > + struct attribute *attr = dwarf2_attr (die, DW_AT_accessibility, cu); > + if (attr != NULL) > + accessibility = (enum dwarf_access_attribute) DW_UNSND (attr); > + else > + accessibility = dwarf2_default_access_attribute (die, cu); > + switch (accessibility) > + { > + case DW_ACCESS_public: > + /* The assumed value if neither private nor protected. */ > + break; > + case DW_ACCESS_private: > + fp->is_private = 1; > + break; > + case DW_ACCESS_protected: > + fp->is_protected = 1; > + break; > + default: > + gdb_assert_not_reached ("unexpected accessibility attribute"); > + } > + > new_field->next = fip->typedef_field_list; > fip->typedef_field_list = new_field; > fip->typedef_field_list_count++; > diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h > index 0e0aead..48af6f1 100644 > --- a/gdb/gdbtypes.h > +++ b/gdb/gdbtypes.h > @@ -896,6 +896,12 @@ struct typedef_field > /* * Type this typedef named NAME represents. */ > > struct type *type; > + > + /* * True if this field was declared protected, false otherwise. */ > + unsigned int is_protected : 1; > + > + /* * True if this field was declared private, false otherwise. */ > + unsigned int is_private : 1; > }; > > /* * C++ language-specific information for TYPE_CODE_STRUCT and > @@ -1427,6 +1433,7 @@ extern void set_type_vptr_basetype (struct type *, struct type *); > #define TYPE_FN_FIELD_VIRTUAL_P(thisfn, n) ((thisfn)[n].voffset > 1) > #define TYPE_FN_FIELD_STATIC_P(thisfn, n) ((thisfn)[n].voffset == VOFFSET_STATIC) > > +/* Accessors for typedefs defined by a class. */ > #define TYPE_TYPEDEF_FIELD_ARRAY(thistype) \ > TYPE_CPLUS_SPECIFIC (thistype)->typedef_field > #define TYPE_TYPEDEF_FIELD(thistype, n) \ > @@ -1437,6 +1444,10 @@ extern void set_type_vptr_basetype (struct type *, struct type *); > TYPE_TYPEDEF_FIELD (thistype, n).type > #define TYPE_TYPEDEF_FIELD_COUNT(thistype) \ > TYPE_CPLUS_SPECIFIC (thistype)->typedef_field_count > +#define TYPE_TYPEDEF_FIELD_PROTECTED(thistype, n) \ > + TYPE_TYPEDEF_FIELD (thistype, n).is_protected > +#define TYPE_TYPEDEF_FIELD_PRIVATE(thistype, n) \ > + TYPE_TYPEDEF_FIELD (thistype, n).is_private > > #define TYPE_IS_OPAQUE(thistype) \ > (((TYPE_CODE (thistype) == TYPE_CODE_STRUCT) \ > 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..1f6d377 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 tyepdefs of different access. "tyepdefs". > + > + 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;" } Add spaces after {, for consistency. > + } > + > + 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]*} I don't think it's necessary to escape the space. > + 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. > Thanks! Simon