From patchwork Mon Jan 29 15:31:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alan Hayward X-Patchwork-Id: 25669 Received: (qmail 5669 invoked by alias); 29 Jan 2018 15:31:47 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 5621 invoked by uid 89); 29 Jan 2018 15:31:46 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, MIME_BASE64_BLANKS, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy=Think X-HELO: EUR01-VE1-obe.outbound.protection.outlook.com Received: from mail-ve1eur01on0052.outbound.protection.outlook.com (HELO EUR01-VE1-obe.outbound.protection.outlook.com) (104.47.1.52) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 29 Jan 2018 15:31:39 +0000 Received: from AM3PR08MB0101.eurprd08.prod.outlook.com (10.160.211.19) by AM3PR08MB0215.eurprd08.prod.outlook.com (10.161.35.153) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.444.14; Mon, 29 Jan 2018 15:31:34 +0000 Received: from AM3PR08MB0101.eurprd08.prod.outlook.com ([fe80::c95:81b8:c681:ae2]) by AM3PR08MB0101.eurprd08.prod.outlook.com ([fe80::c95:81b8:c681:ae2%17]) with mapi id 15.20.0444.016; Mon, 29 Jan 2018 15:31:34 +0000 From: Alan Hayward To: Philipp Rudo , Simon Marchi CC: "gdb-patches@sourceware.org" , nd Subject: Re: [PATCH] Use visitors for make_gdb_type Date: Mon, 29 Jan 2018 15:31:34 +0000 Message-ID: <707546ED-241F-4641-97A9-551C6FF0E7B4@arm.com> References: <20180129102836.5d521e5f@ThinkPad> In-Reply-To: <20180129102836.5d521e5f@ThinkPad> authentication-results: spf=none (sender IP is ) smtp.mailfrom=Alan.Hayward@arm.com; x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM3PR08MB0215; 7:eL4+jVQD+48dM3pRin0kmvXnvkv2mgiV93IZGiQNE3z+SLY0F/9k46ZRMa3SM3HQItZy7PWvFD1Nfzrs2Mq+fghCrjvzi7Eu/dH9pUkSh227cusyqGeAy0lS6QjavFYQJFZECXmMRa7UWzHXqqKTdK4/x9BrmaXQAUZSsX0j7kDHnuflnmQRVne+zIwC6DerYkADO5SkM5Hihmc8dW32C5tsvETRNP90UIAb+KbMUXdWCT/KtCg+qzktiJ6Nru75 x-ms-exchange-antispam-srfa-diagnostics: SSOS; x-ms-office365-filtering-ht: Tenant x-ms-office365-filtering-correlation-id: 04eca56c-175b-4c21-3cd2-08d5672d6153 x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(4534165)(4627221)(201703031133081)(201702281549075)(48565401081)(5600026)(4604075)(3008032)(2017052603307)(7153060)(7193020); SRVR:AM3PR08MB0215; x-ms-traffictypediagnostic: AM3PR08MB0215: nodisclaimer: True x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(180628864354917)(131327999870524)(104084551191319)(17755550239193); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(6040501)(2401047)(5005006)(8121501046)(3002001)(10201501046)(3231101)(944501161)(93006095)(93001095)(6055026)(6041288)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123564045)(20161123558120)(20161123562045)(6072148)(201708071742011); SRVR:AM3PR08MB0215; BCL:0; PCL:0; RULEID:; SRVR:AM3PR08MB0215; x-forefront-prvs: 0567A15835 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(366004)(39860400002)(39380400002)(396003)(376002)(346002)(199004)(189003)(51914003)(377424004)(3660700001)(93886005)(8936002)(105586002)(3280700002)(26005)(478600001)(54906003)(229853002)(110136005)(186003)(316002)(14454004)(575784001)(86362001)(83716003)(68736007)(72206003)(5250100002)(102836004)(6246003)(6436002)(6512007)(305945005)(7736002)(3846002)(6116002)(2906002)(82746002)(2950100002)(2900100001)(5660300001)(106356001)(99286004)(36756003)(6506007)(59450400001)(53546011)(66066001)(8676002)(81156014)(81166006)(76176011)(25786009)(53946003)(4326008)(6486002)(53936002)(97736004)(33656002)(579004); DIR:OUT; SFP:1101; SCL:1; SRVR:AM3PR08MB0215; H:AM3PR08MB0101.eurprd08.prod.outlook.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: SiduGuUdHZ8tiX1dglrwpGPpX2rSs0lfP1tgv8FcSGdToIJe36Up77BCz53b9bFqtR80DhqhoXkkNW1kqRH0JA== spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-ID: MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-Network-Message-Id: 04eca56c-175b-4c21-3cd2-08d5672d6153 X-MS-Exchange-CrossTenant-originalarrivaltime: 29 Jan 2018 15:31:34.5733 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM3PR08MB0215 X-IsSubscribed: yes Updated version of patch at the bottom. > On 29 Jan 2018, at 09:28, Philipp Rudo wrote: > > Hi Alan, > > besides the comments Simon already made, the patch looks fine to me. > Thanks! > > On Sun, 28 Jan 2018 21:24:19 -0500 > Simon Marchi wrote: > >> On 2018-01-26 10:30 AM, Alan Hayward wrote: >>> I appear to still have email issues - previous post had the tabs stripped out. >>> Hoping this version is ok. Apologies. >> >> Hi Alan, >> >> I was able to apply it correctly. >>> Very strange! Think I’m ok now. >> >> make_gdb_type_union & co could be methods of gdb_type_creator and access gdbarch >> directly. I think it would make sense to have all the knowledge of the tdesc type >> to gdb type conversion inside that class. Agreed and done. >>> >>> + void visit_pre (const target_desc *e) >>> + {} >> >> I think we should have empty default implementations of these visit functions in the >> base class, instead of having to declare them empty when unnecessary. Maybe Yao had >> a reason not to do this initially? >> I think Yao didn’t add the method because tdesc_element_visitor is meant to be an interface and remain abstract. I considered putting the types into a parent class of tdesc_element_visitor, but that breaks the accept() functions horribly. Instead, I’ve created a new subclass from tdesc_element_visitor called tdesc_element_type_visitor which provides null implementations for all the non type visit functions. gdb_type_creator can now inherit from tdesc_element_type_visitor and only has to provide the three visitors. Are you happy with that? >> In any case, make sure to mark the overriden methods with the "override" keyword. Using >> clang: >> >> /home/simark/src/binutils-gdb/gdb/target-descriptions.c:416:10: error: 'visit_pre' overrides a member function but is not marked 'override' [-Werror,-Winconsistent-missing-override] >> void visit_pre (const target_desc *e) Done. And thanks for the review. New version implements the above changes. Didn’t mention previously, but patches have been tested on a make check on x86 targets=all build with target board unix native-gdbserver. Built for power (because it does not use new target descriptions), but am unable to test. 2018-01-29 Alan Hayward * target-descriptions.c (tdesc_element_type_visitor) Add class. (tdesc_type): Move make_gdb_type from here. (tdesc_type_builtin): Likewise. (tdesc_type_vector): Likewise. (tdesc_type_with_fields): Move make_gdb_type_ functions from here. (make_gdb_type_struct): Move from tdesc_type_with_fields. (make_gdb_type_union): Likewise. (make_gdb_type_flags): Likewise. (make_gdb_type_enum): Likewise. (make_gdb_type): New function. (tdesc_register_type): Use static make_gdb_type. --- gdb/target-descriptions.c | 480 +++++++++++++++++++++++++--------------------- 1 file changed, 264 insertions(+), 216 deletions(-) -- 2.14.3 (Apple Git-98) diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c index 1b20a12d76..df0ad9241f 100644 --- a/gdb/target-descriptions.c +++ b/gdb/target-descriptions.c @@ -38,6 +38,8 @@ #include "completer.h" #include "readline/tilde.h" /* tilde_expand */ +static type *make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype); + /* The interface to visit different elements of target description. */ class tdesc_element_visitor @@ -56,6 +58,32 @@ public: virtual void visit (const tdesc_reg *e) = 0; }; +/* The interface to visit different elements of tdesc type. Restricts vistors + to only the ones that work on types. */ + +class tdesc_element_type_visitor : public tdesc_element_visitor +{ +public: + void visit_pre (const target_desc *e) override + {} + + void visit_post (const target_desc *e) override + {} + + void visit_pre (const tdesc_feature *e) override + {} + + void visit_post (const tdesc_feature *e) override + {} + + virtual void visit (const tdesc_type_builtin *e) = 0; + virtual void visit (const tdesc_type_vector *e) = 0; + virtual void visit (const tdesc_type_with_fields *e) = 0; + + void visit (const tdesc_reg *e) override + {} +}; + class tdesc_element { public: @@ -223,11 +251,6 @@ struct tdesc_type : tdesc_element { return !(*this == other); } - - /* Construct, if necessary, and return the GDB type implementing this - target type for architecture GDBARCH. */ - - virtual type *make_gdb_type (struct gdbarch *gdbarch) const = 0; }; typedef std::unique_ptr tdesc_type_up; @@ -242,81 +265,6 @@ struct tdesc_type_builtin : tdesc_type { v.visit (this); } - - type *make_gdb_type (struct gdbarch *gdbarch) const override - { - switch (this->kind) - { - /* Predefined types. */ - case TDESC_TYPE_BOOL: - return builtin_type (gdbarch)->builtin_bool; - - case TDESC_TYPE_INT8: - return builtin_type (gdbarch)->builtin_int8; - - case TDESC_TYPE_INT16: - return builtin_type (gdbarch)->builtin_int16; - - case TDESC_TYPE_INT32: - return builtin_type (gdbarch)->builtin_int32; - - case TDESC_TYPE_INT64: - return builtin_type (gdbarch)->builtin_int64; - - case TDESC_TYPE_INT128: - return builtin_type (gdbarch)->builtin_int128; - - case TDESC_TYPE_UINT8: - return builtin_type (gdbarch)->builtin_uint8; - - case TDESC_TYPE_UINT16: - return builtin_type (gdbarch)->builtin_uint16; - - case TDESC_TYPE_UINT32: - return builtin_type (gdbarch)->builtin_uint32; - - case TDESC_TYPE_UINT64: - return builtin_type (gdbarch)->builtin_uint64; - - case TDESC_TYPE_UINT128: - return builtin_type (gdbarch)->builtin_uint128; - - case TDESC_TYPE_CODE_PTR: - return builtin_type (gdbarch)->builtin_func_ptr; - - case TDESC_TYPE_DATA_PTR: - return builtin_type (gdbarch)->builtin_data_ptr; - } - - type *gdb_type = tdesc_find_type (gdbarch, this->name.c_str ()); - if (gdb_type != NULL) - return gdb_type; - - switch (this->kind) - { - case TDESC_TYPE_IEEE_SINGLE: - return arch_float_type (gdbarch, -1, "builtin_type_ieee_single", - floatformats_ieee_single); - - case TDESC_TYPE_IEEE_DOUBLE: - return arch_float_type (gdbarch, -1, "builtin_type_ieee_double", - floatformats_ieee_double); - - case TDESC_TYPE_ARM_FPA_EXT: - return arch_float_type (gdbarch, -1, "builtin_type_arm_ext", - floatformats_arm_ext); - - case TDESC_TYPE_I387_EXT: - return arch_float_type (gdbarch, -1, "builtin_type_i387_ext", - floatformats_i387_ext); - } - - internal_error (__FILE__, __LINE__, - "Type \"%s\" has an unknown kind %d", - this->name.c_str (), this->kind); - - return NULL; - } }; /* tdesc_type for vector types. */ @@ -333,19 +281,6 @@ struct tdesc_type_vector : tdesc_type v.visit (this); } - type *make_gdb_type (struct gdbarch *gdbarch) const override - { - type *vector_gdb_type = tdesc_find_type (gdbarch, this->name.c_str ()); - if (vector_gdb_type != NULL) - return vector_gdb_type; - - type *element_gdb_type = this->element_type->make_gdb_type (gdbarch); - vector_gdb_type = init_vector_type (element_gdb_type, this->count); - TYPE_NAME (vector_gdb_type) = xstrdup (this->name.c_str ()); - - return vector_gdb_type; - } - struct tdesc_type *element_type; int count; }; @@ -364,151 +299,264 @@ struct tdesc_type_with_fields : tdesc_type v.visit (this); } - type *make_gdb_type_struct (struct gdbarch *gdbarch) const + std::vector fields; + int size; +}; + +/* Convert a tdesc_type to a gdb type. */ + +static type * +make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype) +{ + class gdb_type_creator : public tdesc_element_type_visitor { - type *struct_gdb_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); - TYPE_NAME (struct_gdb_type) = xstrdup (this->name.c_str ()); - TYPE_TAG_NAME (struct_gdb_type) = TYPE_NAME (struct_gdb_type); + public: + gdb_type_creator (struct gdbarch *gdbarch) + : m_gdbarch (gdbarch) + {} - for (const tdesc_type_field &f : this->fields) - { - if (f.start != -1 && f.end != -1) - { - /* Bitfield. */ - struct field *fld; - struct type *field_gdb_type; - int bitsize, total_size; - - /* This invariant should be preserved while creating types. */ - gdb_assert (this->size != 0); - if (f.type != NULL) - field_gdb_type = f.type->make_gdb_type (gdbarch); - else if (this->size > 4) - field_gdb_type = builtin_type (gdbarch)->builtin_uint64; - else - field_gdb_type = builtin_type (gdbarch)->builtin_uint32; - - fld = append_composite_type_field_raw - (struct_gdb_type, xstrdup (f.name.c_str ()), field_gdb_type); - - /* For little-endian, BITPOS counts from the LSB of - the structure and marks the LSB of the field. For - big-endian, BITPOS counts from the MSB of the - structure and marks the MSB of the field. Either - way, it is the number of bits to the "left" of the - field. To calculate this in big-endian, we need - the total size of the structure. */ - bitsize = f.end - f.start + 1; - total_size = this->size * TARGET_CHAR_BIT; - if (gdbarch_bits_big_endian (gdbarch)) - SET_FIELD_BITPOS (fld[0], total_size - f.start - bitsize); - else - SET_FIELD_BITPOS (fld[0], f.start); - FIELD_BITSIZE (fld[0]) = bitsize; - } - else - { - gdb_assert (f.start == -1 && f.end == -1); - type *field_gdb_type = f.type->make_gdb_type (gdbarch); - append_composite_type_field (struct_gdb_type, - xstrdup (f.name.c_str ()), - field_gdb_type); - } - } + type *get_type () + { + return m_type; + } - if (this->size != 0) - TYPE_LENGTH (struct_gdb_type) = this->size; + void visit (const tdesc_type_builtin *e) override + { + switch (e->kind) + { + /* Predefined types. */ + case TDESC_TYPE_BOOL: + m_type = builtin_type (m_gdbarch)->builtin_bool; + return; + case TDESC_TYPE_INT8: + m_type = builtin_type (m_gdbarch)->builtin_int8; + return; + case TDESC_TYPE_INT16: + m_type = builtin_type (m_gdbarch)->builtin_int16; + return; + case TDESC_TYPE_INT32: + m_type = builtin_type (m_gdbarch)->builtin_int32; + return; + case TDESC_TYPE_INT64: + m_type = builtin_type (m_gdbarch)->builtin_int64; + return; + case TDESC_TYPE_INT128: + m_type = builtin_type (m_gdbarch)->builtin_int128; + return; + case TDESC_TYPE_UINT8: + m_type = builtin_type (m_gdbarch)->builtin_uint8; + return; + case TDESC_TYPE_UINT16: + m_type = builtin_type (m_gdbarch)->builtin_uint16; + return; + case TDESC_TYPE_UINT32: + m_type = builtin_type (m_gdbarch)->builtin_uint32; + return; + case TDESC_TYPE_UINT64: + m_type = builtin_type (m_gdbarch)->builtin_uint64; + return; + case TDESC_TYPE_UINT128: + m_type = builtin_type (m_gdbarch)->builtin_uint128; + return; + case TDESC_TYPE_CODE_PTR: + m_type = builtin_type (m_gdbarch)->builtin_func_ptr; + return; + case TDESC_TYPE_DATA_PTR: + m_type = builtin_type (m_gdbarch)->builtin_data_ptr; + return; + } - return struct_gdb_type; - } + m_type = tdesc_find_type (m_gdbarch, e->name.c_str ()); + if (m_type != NULL) + return; - type *make_gdb_type_union (struct gdbarch *gdbarch) const - { - type *union_gdb_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); - TYPE_NAME (union_gdb_type) = xstrdup (this->name.c_str ()); + switch (e->kind) + { + case TDESC_TYPE_IEEE_SINGLE: + m_type = arch_float_type (m_gdbarch, -1, "builtin_type_ieee_single", + floatformats_ieee_single); + return; + + case TDESC_TYPE_IEEE_DOUBLE: + m_type = arch_float_type (m_gdbarch, -1, "builtin_type_ieee_double", + floatformats_ieee_double); + return; + case TDESC_TYPE_ARM_FPA_EXT: + m_type = arch_float_type (m_gdbarch, -1, "builtin_type_arm_ext", + floatformats_arm_ext); + return; + + case TDESC_TYPE_I387_EXT: + m_type = arch_float_type (m_gdbarch, -1, "builtin_type_i387_ext", + floatformats_i387_ext); + return; + } - for (const tdesc_type_field &f : this->fields) - { - type* field_gdb_type = f.type->make_gdb_type (gdbarch); - append_composite_type_field (union_gdb_type, xstrdup (f.name.c_str ()), - field_gdb_type); - - /* If any of the children of a union are vectors, flag the - union as a vector also. This allows e.g. a union of two - vector types to show up automatically in "info vector". */ - if (TYPE_VECTOR (field_gdb_type)) - TYPE_VECTOR (union_gdb_type) = 1; - } + internal_error (__FILE__, __LINE__, + "Type \"%s\" has an unknown kind %d", + e->name.c_str (), e->kind); + } - return union_gdb_type; - } + void visit (const tdesc_type_vector *e) override + { + m_type = tdesc_find_type (m_gdbarch, e->name.c_str ()); + if (m_type != NULL) + return; + + type *element_gdb_type = make_gdb_type (m_gdbarch, e->element_type); + m_type = init_vector_type (element_gdb_type, e->count); + TYPE_NAME (m_type) = xstrdup (e->name.c_str ()); + return; + } - type *make_gdb_type_flags (struct gdbarch *gdbarch) const - { - type *flags_gdb_type = arch_flags_type (gdbarch, this->name.c_str (), - this->size * TARGET_CHAR_BIT); + void visit (const tdesc_type_with_fields *e) override + { + m_type = tdesc_find_type (m_gdbarch, e->name.c_str ()); + if (m_type != NULL) + return; - for (const tdesc_type_field &f : this->fields) - { - int bitsize = f.end - f.start + 1; + switch (e->kind) + { + case TDESC_TYPE_STRUCT: + make_gdb_type_struct (e); + return; + case TDESC_TYPE_UNION: + make_gdb_type_union (e); + return; + case TDESC_TYPE_FLAGS: + make_gdb_type_flags (e); + return; + case TDESC_TYPE_ENUM: + make_gdb_type_enum (e); + return; + } - gdb_assert (f.type != NULL); - type *field_gdb_type = f.type->make_gdb_type (gdbarch); - append_flags_type_field (flags_gdb_type, f.start, bitsize, - field_gdb_type, f.name.c_str ()); - } + internal_error (__FILE__, __LINE__, + "Type \"%s\" has an unknown kind %d", + e->name.c_str (), e->kind); + } - return flags_gdb_type; - } + private: - type *make_gdb_type_enum (struct gdbarch *gdbarch) const - { - type *enum_gdb_type = arch_type (gdbarch, TYPE_CODE_ENUM, - this->size * TARGET_CHAR_BIT, - this->name.c_str ()); + void make_gdb_type_struct (const tdesc_type_with_fields *e) + { + m_type = arch_composite_type (m_gdbarch, NULL, TYPE_CODE_STRUCT); + TYPE_NAME (m_type) = xstrdup (e->name.c_str ()); + TYPE_TAG_NAME (m_type) = TYPE_NAME (m_type); - TYPE_UNSIGNED (enum_gdb_type) = 1; - for (const tdesc_type_field &f : this->fields) - { - struct field *fld - = append_composite_type_field_raw (enum_gdb_type, + for (const tdesc_type_field &f : e->fields) + { + if (f.start != -1 && f.end != -1) + { + /* Bitfield. */ + struct field *fld; + struct type *field_gdb_type; + int bitsize, total_size; + + /* This invariant should be preserved while creating types. */ + gdb_assert (e->size != 0); + if (f.type != NULL) + field_gdb_type = make_gdb_type (m_gdbarch, f.type); + else if (e->size > 4) + field_gdb_type = builtin_type (m_gdbarch)->builtin_uint64; + else + field_gdb_type = builtin_type (m_gdbarch)->builtin_uint32; + + fld = append_composite_type_field_raw + (m_type, xstrdup (f.name.c_str ()), field_gdb_type); + + /* For little-endian, BITPOS counts from the LSB of + the structure and marks the LSB of the field. For + big-endian, BITPOS counts from the MSB of the + structure and marks the MSB of the field. Either + way, it is the number of bits to the "left" of the + field. To calculate this in big-endian, we need + the total size of the structure. */ + bitsize = f.end - f.start + 1; + total_size = e->size * TARGET_CHAR_BIT; + if (gdbarch_bits_big_endian (m_gdbarch)) + SET_FIELD_BITPOS (fld[0], total_size - f.start - bitsize); + else + SET_FIELD_BITPOS (fld[0], f.start); + FIELD_BITSIZE (fld[0]) = bitsize; + } + else + { + gdb_assert (f.start == -1 && f.end == -1); + type *field_gdb_type = make_gdb_type (m_gdbarch, f.type); + append_composite_type_field (m_type, xstrdup (f.name.c_str ()), - NULL); + field_gdb_type); + } + } - SET_FIELD_BITPOS (fld[0], f.start); - } + if (e->size != 0) + TYPE_LENGTH (m_type) = e->size; + } - return enum_gdb_type; - } + void make_gdb_type_union (const tdesc_type_with_fields *e) + { + m_type = arch_composite_type (m_gdbarch, NULL, TYPE_CODE_UNION); + TYPE_NAME (m_type) = xstrdup (e->name.c_str ()); - type *make_gdb_type (struct gdbarch *gdbarch) const override - { - type *gdb_type = tdesc_find_type (gdbarch, this->name.c_str ()); - if (gdb_type != NULL) - return gdb_type; + for (const tdesc_type_field &f : e->fields) + { + type* field_gdb_type = make_gdb_type (m_gdbarch, f.type); + append_composite_type_field (m_type, xstrdup (f.name.c_str ()), + field_gdb_type); + + /* If any of the children of a union are vectors, flag the + union as a vector also. This allows e.g. a union of two + vector types to show up automatically in "info vector". */ + if (TYPE_VECTOR (field_gdb_type)) + TYPE_VECTOR (m_type) = 1; + } + } - switch (this->kind) + void make_gdb_type_flags (const tdesc_type_with_fields *e) { - case TDESC_TYPE_STRUCT: - return make_gdb_type_struct (gdbarch); - case TDESC_TYPE_UNION: - return make_gdb_type_union (gdbarch); - case TDESC_TYPE_FLAGS: - return make_gdb_type_flags (gdbarch); - case TDESC_TYPE_ENUM: - return make_gdb_type_enum (gdbarch); + m_type = arch_flags_type (m_gdbarch, e->name.c_str (), + e->size * TARGET_CHAR_BIT); + + for (const tdesc_type_field &f : e->fields) + { + int bitsize = f.end - f.start + 1; + + gdb_assert (f.type != NULL); + type *field_gdb_type = make_gdb_type (m_gdbarch, f.type); + append_flags_type_field (m_type, f.start, bitsize, + field_gdb_type, f.name.c_str ()); + } } - internal_error (__FILE__, __LINE__, - "Type \"%s\" has an unknown kind %d", - this->name.c_str (), this->kind); + void make_gdb_type_enum (const tdesc_type_with_fields *e) + { + m_type = arch_type (m_gdbarch, TYPE_CODE_ENUM, e->size * TARGET_CHAR_BIT, + e->name.c_str ()); - return NULL; - } + TYPE_UNSIGNED (m_type) = 1; + for (const tdesc_type_field &f : e->fields) + { + struct field *fld + = append_composite_type_field_raw (m_type, + xstrdup (f.name.c_str ()), + NULL); - std::vector fields; - int size; -}; + SET_FIELD_BITPOS (fld[0], f.start); + } + } + + /* The gdbarch used. */ + struct gdbarch *m_gdbarch; + + /* The type created. */ + type *m_type; + }; + + gdb_type_creator gdb_type (gdbarch); + ttype->accept (gdb_type); + return gdb_type.get_type (); +} /* A feature from a target description. Each feature is a collection of other elements, e.g. registers and types. */ @@ -1216,7 +1264,7 @@ tdesc_register_type (struct gdbarch *gdbarch, int regno) { /* First check for a predefined or target defined type. */ if (reg->tdesc_type) - arch_reg->type = reg->tdesc_type->make_gdb_type (gdbarch); + arch_reg->type = make_gdb_type (gdbarch, reg->tdesc_type); /* Next try size-sensitive type shortcuts. */ else if (reg->type == "float")