From patchwork Sun Oct 11 10:31:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Sandoe X-Patchwork-Id: 1380300 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sandoe.co.uk Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C8J714dCHz9sSG for ; Sun, 11 Oct 2020 21:33:15 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A74A23857C75; Sun, 11 Oct 2020 10:33:08 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp1.wavenetuk.net (smtp.wavenetuk.net [195.26.36.10]) by sourceware.org (Postfix) with ESMTP id E6F4F3857C4E for ; Sun, 11 Oct 2020 10:33:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E6F4F3857C4E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=sandoe.co.uk Authentication-Results: sourceware.org; spf=none smtp.mailfrom=iain@sandoe.co.uk Received: from [192.168.1.212] (host81-138-1-83.in-addr.btopenworld.com [81.138.1.83]) by smtp1.wavenetuk.net (Postfix) with ESMTPA id 1D50612012A5 for ; Sun, 11 Oct 2020 11:33:04 +0100 (BST) From: Iain Sandoe Mime-Version: 1.0 (Mac OS X Mail 10.3 \(3273\)) Subject: [pushed] Objective-C, Darwin : Update protocol metadata to current version. Message-Id: <2E01B100-D4FB-48DE-9374-7D99E1C3C7AE@sandoe.co.uk> Date: Sun, 11 Oct 2020 11:31:48 +0100 To: GCC Patches X-Mailer: Apple Mail (2.3273) X-Spam-Status: No, score=-16.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_COUK, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KHOP_HELO_FCRDNS, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Hi Later versions of the NeXT runtime protocol metadata contain additional fields. This patch adds these fields and populates a new list of method types. tested across the range of supported Darwin systems, and on x86_64-linux pushed to master, thanks Iain gcc/objc/ChangeLog: * objc-next-runtime-abi-02.c (build_v2_super_template): Add new fields to the template. (build_v2_protocol_template): Build new field entries. (generate_v2_meth_descriptor_table): Adjust to allow recording all method types. (generate_v2_meth_type_list): New. (build_v2_protocol_initializer): Initialize the additional fields. (generate_v2_protocols): Record method types for all entries and generate the additional method type table. --- gcc/objc/objc-next-runtime-abi-02.c | 103 +++++++++++++++++++++++----- 1 file changed, 87 insertions(+), 16 deletions(-) diff --git a/gcc/objc/objc-next-runtime-abi-02.c b/gcc/objc/objc-next-runtime-abi-02.c index 57604255065..3a308975325 100644 --- a/gcc/objc/objc-next-runtime-abi-02.c +++ b/gcc/objc/objc-next-runtime-abi-02.c @@ -743,6 +743,9 @@ build_v2_super_template (void) const struct _prop_list_t * const properties; const uint32_t size; const uint32_t flags; + const char ** extended_method_types; + const char * demangled_name; + const struct _prop_list_t * class_properties; } */ static void @@ -784,6 +787,16 @@ build_v2_protocol_template (void) /* const uint32_t flags; */ add_field_decl (integer_type_node, "flags", &chain); + /* const char **extendedMethodTypes; */ + tree ptr_to_ptr_to_char = build_pointer_type (string_type_node); + add_field_decl (ptr_to_ptr_to_char, "extended_method_types", &chain); + + /* const char *demangledName; */ + add_field_decl (string_type_node, "demangled_name", &chain); + + /* const struct _prop_list_t *class_properties; */ + add_field_decl (objc_prop_list_ptr, "class_properties", &chain); + objc_finish_struct (objc_v2_protocol_template, decls); } @@ -2296,9 +2309,10 @@ build_v2_method_list_template (tree list_type, int size) objc_method_prototype_template which is missing this field. */ static tree generate_v2_meth_descriptor_table (tree chain, tree protocol, - const char *prefix, tree attr) + const char *prefix, tree attr, + vec& all_meths) { - tree method_list_template, initlist, decl, methods; + tree method_list_template, initlist, decl; int size, entsize; vec *v = NULL; char buf[BUFSIZE]; @@ -2306,13 +2320,14 @@ generate_v2_meth_descriptor_table (tree chain, tree protocol, if (!chain || !prefix) return NULL_TREE; - methods = chain; + tree method = chain; size = 0; - while (methods) + while (method) { - if (! METHOD_ENCODING (methods)) - METHOD_ENCODING (methods) = encode_method_prototype (methods); - methods = TREE_CHAIN (methods); + if (! METHOD_ENCODING (method)) + METHOD_ENCODING (method) = encode_method_prototype (method); + all_meths.safe_push (method); + method = TREE_CHAIN (method); size++; } @@ -2337,6 +2352,31 @@ generate_v2_meth_descriptor_table (tree chain, tree protocol, return decl; } +static tree +generate_v2_meth_type_list (vec& all_meths, tree protocol, + const char *prefix) +{ + if (all_meths.is_empty () || !prefix) + return NULL_TREE; + + unsigned size = all_meths.length (); + tree list_type = build_sized_array_type (string_type_node, size); + char *nam; + asprintf (&nam, "%s_%s", prefix, + IDENTIFIER_POINTER (PROTOCOL_NAME (protocol))); + tree decl = start_var_decl (list_type, nam); + free (nam); + OBJCMETA (decl, objc_meta, meta_base); + vec *v = NULL; + + for (unsigned i = 0; i < size; ++i) + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + add_objc_string (METHOD_ENCODING (all_meths[i]), + meth_var_types)); + finish_var_decl (decl, objc_build_constructor (list_type, v)); + return decl; +} + /* This routine builds the initializer list to initialize the 'struct _prop_t prop_list[]' field of 'struct _prop_list_t' meta-data. */ @@ -2463,7 +2503,8 @@ static tree build_v2_protocol_initializer (tree type, tree protocol_name, tree protocol_list, tree inst_methods, tree class_methods, tree opt_ins_meth, tree opt_cls_meth, - tree property_list) + tree property_list, tree ext_meth_types, + tree demangled_name, tree class_prop_list) { tree expr, ttyp; location_t loc; @@ -2518,7 +2559,28 @@ build_v2_protocol_initializer (tree type, tree protocol_name, tree protocol_list /* const uint32_t flags; = 0 */ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, integer_zero_node); - return objc_build_constructor (type, inits); + ttyp = build_pointer_type (string_type_node); + if (ext_meth_types) + expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, ext_meth_types, 0)); + else + expr = convert (ttyp, null_pointer_node); + CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + + ttyp = string_type_node; + if (demangled_name) + expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, demangled_name, 0)); + else + expr = convert (ttyp, null_pointer_node); + CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + + ttyp = objc_prop_list_ptr; + if (class_prop_list) + expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_prop_list, 0)); + else + expr = convert (ttyp, null_pointer_node); + CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + + return objc_build_constructor (type, inits); } /* Main routine to build all meta data for all protocols used in a @@ -2554,25 +2616,26 @@ generate_v2_protocols (void) loc = DECL_SOURCE_LOCATION (decl); some = true; + vec all_meths = vNULL; inst_meth = generate_v2_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p, "_OBJC_ProtocolInstanceMethods", - meta_proto_nst_meth); + meta_proto_nst_meth, all_meths); class_meth = generate_v2_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p, "_OBJC_ProtocolClassMethods", - meta_proto_cls_meth); + meta_proto_cls_meth, all_meths); opt_inst_meth = generate_v2_meth_descriptor_table (PROTOCOL_OPTIONAL_NST_METHODS (p), p, - "_OBJC_OptProtocolInstMethods", - meta_proto_nst_meth); + "_OBJC_ProtocolOptInstMethods", + meta_proto_nst_meth, all_meths); opt_class_meth = generate_v2_meth_descriptor_table (PROTOCOL_OPTIONAL_CLS_METHODS (p), p, - "_OBJC_OptProtocolClassMethods", - meta_proto_cls_meth); + "_OBJC_ProtocolOptClassMethods", + meta_proto_cls_meth, all_meths); if (PROTOCOL_LIST (p)) refs_decl = generate_v2_protocol_list (p, NULL_TREE); @@ -2590,13 +2653,21 @@ generate_v2_protocols (void) props = generate_v2_property_table (p, NULL_TREE); + tree ext_meth_types + = generate_v2_meth_type_list (all_meths, p, + "_OBJC_ProtocolMethodTypes"); + tree demangled_name = NULL_TREE; + tree class_prop_list = NULL_TREE; + initlist = build_v2_protocol_initializer (TREE_TYPE (decl), protocol_name_expr, refs_expr, inst_meth, class_meth, opt_inst_meth, opt_class_meth, - props); + props, ext_meth_types, + demangled_name,class_prop_list); finish_var_decl (decl, initlist); objc_add_to_protocol_list (p, decl); + all_meths.truncate (0); } if (some)