From patchwork Mon May 25 07:48:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 1297165 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=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=adacore-com.20150623.gappssmtp.com header.i=@adacore-com.20150623.gappssmtp.com header.a=rsa-sha256 header.s=20150623 header.b=NtsDAX7i; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (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 49Vq2x3Hbtz9sSd for ; Mon, 25 May 2020 17:48:23 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 540D53851C04; Mon, 25 May 2020 07:48:20 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by sourceware.org (Postfix) with ESMTPS id 171543858D35 for ; Mon, 25 May 2020 07:48:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 171543858D35 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=botcazou@adacore.com Received: by mail-wm1-x333.google.com with SMTP id u13so5712991wml.1 for ; Mon, 25 May 2020 00:48:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=fuSbQmcv5qUrYLdVl28rU3CxMJRxCxVl6UiKnjt23PY=; b=NtsDAX7iUH3lMCWnC1BMWoN/wFIw+5m9jo009rj6uXOGAKPvWZ0MvqXgK0ipQlmFzh 1WMFUXFYN5tfAg/+zS8tOlCxep2jUkY1iaDGZW56w/Lr3JNmp6Ui3i9IpZECEhB2FQjZ Vuv1ezkffuMN1CuaTRsSfATy6pKYrsx6moEgPv0neNybVVjzyPfNd8ua/hZvesSIHM6Y 5y4eF/LjSnBd0QvMu5sOJ1NnzHdFQmcrEBpLC3Fj3sTHUtyZl+oj8FETAJUEWPX/TAHm ziHpyDq3VEIrBbMhX6DVLp5McygWpS8iKSE0UpDygAHH8tBsAW14ub6dI2TWP8a0JhmV C3Ow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=fuSbQmcv5qUrYLdVl28rU3CxMJRxCxVl6UiKnjt23PY=; b=tuqPhdJsLUtaugF8BZYTvDFZdqzhglZfC6WXjfELAlwnvdJkndi6zjcxccuhKI/Vbm z58enzTQqTVcq53GWnz+bToj40VIT/aGlMBlmIsCH9XoPnnomhh8ofVYqYyb+sLn9838 yZ5jkeoBpxeNrZ9F1gNJB4bRgt6sc/ym6Vzihdc9y/aTmKCfoD807NhjKaQHO6G2vqYl yUm7pLI2NyUlFbhd1qJBuepl/qgSsaoHgDtAs2PR1hzYRygznJMGdPDIXpmc8WCLtWRN 2loC9qfXeCOtkboY0R8Iwb2eN/cS7DkpEqwj+ih9b4ryHfJB5hXF9hcJY2OVL2vQJS5p RVkw== X-Gm-Message-State: AOAM530YX3OyO1Ilnj+kGryEcPx9wW18SCrvLlJ/NFelWrVwTkVlT4FI M5iZQyxgjCl1RI8FRr5+PzOftO8pmraU5Q== X-Google-Smtp-Source: ABdhPJyyCh9MzHwWwlj7BCIf1Zur9VBemSJSWlXKLO2Z3zQLnx1A0N1pncOvQkPgNWm+Qt6XpOfbOA== X-Received: by 2002:a05:600c:2255:: with SMTP id a21mr24750345wmm.67.1590392894786; Mon, 25 May 2020 00:48:14 -0700 (PDT) Received: from polaris.localnet ([2a01:e0a:41b:9230:1a03:73ff:fe45:373a]) by smtp.gmail.com with ESMTPSA id x18sm17644218wru.72.2020.05.25.00.48.13 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 May 2020 00:48:14 -0700 (PDT) From: Eric Botcazou X-Google-Original-From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [Ada] Change description of fat pointertype with -fgnat-encodings=minimal Date: Mon, 25 May 2020 09:48:12 +0200 Message-ID: <3431135.9Jl7Y8oFM9@polaris> MIME-Version: 1.0 X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, 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" This makes a step back in the representation of fat pointer types in the debug info with -fgnat-encodings=minimal so as to avoid hiding the data indirection and making it easier for GDB to synthetize the construct. Tested on x86-64/Linux, applied on the mainline. 2020-05-25 Eric Botcazou * gcc-interface/decl.c (gnat_to_gnu_entity) : Add a description of the various types associated with the unconstrained type. Declare the fat pointer earlier. Set the current function as context on the template type, and the fat pointer type on the array type. Always mark the fat pointer type as artificial and set it as the context for the pointer type to the array. Also reuse GNU_ENTITY_NAME. Finish up the unconstrained type at the very end. * gcc-interface/misc.c (gnat_get_array_descr_info): Do not handle fat pointer types and tidy up accordingly. * gcc-interface/utils.c (build_unc_object_type): Do not set the context on the template type. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index d87a82ce8fa..c2a2e5fcd09 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -2099,16 +2099,28 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) /* Array Types and Subtypes - Unconstrained array types are represented by E_Array_Type and - constrained array types are represented by E_Array_Subtype. There - are no actual objects of an unconstrained array type; all we have - are pointers to that type. + In GNAT unconstrained array types are represented by E_Array_Type and + constrained array types are represented by E_Array_Subtype. They are + translated into UNCONSTRAINED_ARRAY_TYPE and ARRAY_TYPE respectively. + But there are no actual objects of an unconstrained array type; all we + have are pointers to that type. In addition to the type node itself, + 4 other types associated with it are built in the process: - The following fields are defined on array types and subtypes: + 1. the array type (suffix XUA) containing the actual data, - Component_Type Component type of the array. - Number_Dimensions Number of dimensions (an int). - First_Index Type of first index. */ + 2. the template type (suffix XUB) containng the bounds, + + 3. the fat pointer type (suffix XUP) representing a pointer or a + reference to the unconstrained array type: + XUP = struct { XUA *, XUB * } + + 4. the object record type (suffix XUT) containing bounds and data: + XUT = struct { XUB, XUA } + + The bounds of the array type XUA (de)reference the XUB * field of a + PLACEHOLDER_EXPR for the fat pointer type XUP, so the array type XUA + is to be interpreted in the context of the fat pointer type XUB for + debug info purposes. */ case E_Array_Type: { @@ -2120,7 +2132,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) tree gnu_template_reference, gnu_template_fields, gnu_fat_type; tree *gnu_index_types = XALLOCAVEC (tree, ndim); tree *gnu_temp_fields = XALLOCAVEC (tree, ndim); - tree gnu_max_size = size_one_node, tem, t; + tree gnu_max_size = size_one_node, tem, obj; Entity_Id gnat_index; int index; tree comp_type; @@ -2195,7 +2207,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) TREE_TYPE (tem) = ptr_type_node; TREE_TYPE (DECL_CHAIN (tem)) = gnu_ptr_template; TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (gnu_fat_type)) = 0; - for (t = gnu_fat_type; t; t = TYPE_NEXT_VARIANT (t)) + for (tree t = gnu_fat_type; t; t = TYPE_NEXT_VARIANT (t)) SET_TYPE_UNCONSTRAINED_ARRAY (t, gnu_type); } else @@ -2212,6 +2224,22 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) SET_TYPE_UNCONSTRAINED_ARRAY (gnu_fat_type, gnu_type); } + /* If the GNAT encodings are used, give the fat pointer type a name. + If this is a packed array, tell the debugger how to interpret the + underlying bits by fetching that of the implementation type. But + in any case, mark it as artificial so the debugger can skip it. */ + const Entity_Id gnat_name + = (Present (Packed_Array_Impl_Type (gnat_entity)) + && gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL) + ? Packed_Array_Impl_Type (gnat_entity) + : gnat_entity; + tree xup_name + = (gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL) + ? create_concat_name (gnat_name, "XUP") + : gnu_entity_name; + create_type_decl (xup_name, gnu_fat_type, true, debug_info_p, + gnat_entity); + /* Build a reference to the template from a PLACEHOLDER_EXPR that is the fat pointer. This will be used to access the individual fields once we build them. */ @@ -2313,6 +2341,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) = chainon (gnu_template_fields, gnu_temp_fields[index]); finish_record_type (gnu_template_type, gnu_template_fields, 0, debug_info_p); + TYPE_CONTEXT (gnu_template_type) = current_function_decl; TYPE_READONLY (gnu_template_type) = 1; /* If Component_Size is not already specified, annotate it with the @@ -2369,14 +2398,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) if (TYPE_ALIAS_SET_KNOWN_P (gnu_fat_type)) record_component_aliases (gnu_fat_type); - /* The result type is an UNCONSTRAINED_ARRAY_TYPE that indicates the - corresponding fat pointer. */ - TREE_TYPE (gnu_type) = gnu_fat_type; - TYPE_POINTER_TO (gnu_type) = gnu_fat_type; - TYPE_REFERENCE_TO (gnu_type) = gnu_fat_type; - SET_TYPE_MODE (gnu_type, BLKmode); - SET_TYPE_ALIGN (gnu_type, TYPE_ALIGN (tem)); - /* If the maximum size doesn't overflow, use it. */ if (gnu_max_size && TREE_CODE (gnu_max_size) == INTEGER_CST @@ -2384,24 +2405,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) && compare_tree_int (gnu_max_size, TYPE_ARRAY_SIZE_LIMIT) <= 0) TYPE_ARRAY_MAX_SIZE (tem) = gnu_max_size; + /* See the above description for the rationale. */ create_type_decl (create_concat_name (gnat_entity, "XUA"), tem, artificial_p, debug_info_p, gnat_entity); - - /* If the GNAT encodings are used, give the fat pointer type a name. - If this is a packed array, tell the debugger how to interpret the - underlying bits by fetching that of the implementation type. */ - const Entity_Id gnat_name - = (Present (Packed_Array_Impl_Type (gnat_entity)) - && gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL) - ? Packed_Array_Impl_Type (gnat_entity) - : gnat_entity; - - tree xup_name - = (gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL) - ? get_entity_name (gnat_name) - : create_concat_name (gnat_name, "XUP"); - create_type_decl (xup_name, gnu_fat_type, artificial_p, debug_info_p, - gnat_entity); + TYPE_CONTEXT (tem) = gnu_fat_type; + TYPE_CONTEXT (TYPE_POINTER_TO (tem)) = gnu_fat_type; /* Create the type to be designated by thin pointers: a record type for the array and its template. We used to shift the fields to have the @@ -2412,14 +2420,22 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) don't have to name them as a GNAT encoding, except if specifically asked to. */ tree xut_name - = (gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL) - ? get_entity_name (gnat_name) - : create_concat_name (gnat_name, "XUT"); - tem = build_unc_object_type (gnu_template_type, tem, xut_name, + = (gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL) + ? create_concat_name (gnat_name, "XUT") + : gnu_entity_name; + obj = build_unc_object_type (gnu_template_type, tem, xut_name, debug_info_p); - SET_TYPE_UNCONSTRAINED_ARRAY (tem, gnu_type); - TYPE_OBJECT_RECORD_TYPE (gnu_type) = tem; + SET_TYPE_UNCONSTRAINED_ARRAY (obj, gnu_type); + TYPE_OBJECT_RECORD_TYPE (gnu_type) = obj; + + /* The result type is an UNCONSTRAINED_ARRAY_TYPE that indicates the + corresponding fat pointer. */ + TREE_TYPE (gnu_type) = gnu_fat_type; + TYPE_POINTER_TO (gnu_type) = gnu_fat_type; + TYPE_REFERENCE_TO (gnu_type) = gnu_fat_type; + SET_TYPE_MODE (gnu_type, BLKmode); + SET_TYPE_ALIGN (gnu_type, TYPE_ALIGN (tem)); } break; diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c index 63e0ca7bebe..5a5850a85e0 100644 --- a/gcc/ada/gcc-interface/misc.c +++ b/gcc/ada/gcc-interface/misc.c @@ -778,7 +778,7 @@ gnat_get_array_descr_info (const_tree const_type, { tree type = const_cast (const_type); tree first_dimen, dimen; - bool is_packed_array, is_array, is_fat_ptr; + bool is_packed_array, is_array; int i; /* Temporaries created in the first pass and used in the second one for thin @@ -807,45 +807,16 @@ gnat_get_array_descr_info (const_tree const_type, && TYPE_INDEX_TYPE (TYPE_DOMAIN (type))) { is_array = true; - is_fat_ptr = false; first_dimen = type; - info->data_location = NULL_TREE; } - else if (TYPE_IS_FAT_POINTER_P (type) - && gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL) - { - tree ua_type = TYPE_UNCONSTRAINED_ARRAY (type); - - /* This will be our base object address. */ - tree placeholder_expr = build0 (PLACEHOLDER_EXPR, type); - - /* We assume below that maybe_unconstrained_array returns an INDIRECT_REF - node. */ - tree ua_val - = maybe_unconstrained_array (build_unary_op (INDIRECT_REF, - ua_type, - placeholder_expr)); - - is_array = false; - is_fat_ptr = true; - first_dimen = TREE_TYPE (ua_val); - - /* Get the *address* of the array, not the array itself. */ - info->data_location = TREE_OPERAND (ua_val, 0); - } - - /* Unlike fat pointers (which appear for unconstrained arrays passed in - argument), thin pointers are used only for array access types, so we want - them to appear in the debug info as pointers to an array type. That's why - we match only the RECORD_TYPE here instead of the POINTER_TYPE with the - TYPE_IS_THIN_POINTER_P predicate. */ + /* As well as array types embedded in a record type with their bounds. */ else if (TREE_CODE (type) == RECORD_TYPE && TYPE_CONTAINS_TEMPLATE_P (type) && gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL) { /* This will be our base object address. Note that we assume that - pointers to these will actually point to the array field (thin + pointers to this will actually point to the array field (thin pointers are shifted). */ tree placeholder_expr = build0 (PLACEHOLDER_EXPR, type); tree placeholder_addr @@ -856,7 +827,7 @@ gnat_get_array_descr_info (const_tree const_type, tree array_field = DECL_CHAIN (bounds_field); tree array_type = TREE_TYPE (array_field); - /* Shift the thin pointer address to get the address of the template. */ + /* Shift back the address to get the address of the template. */ tree shift_amount = fold_build1 (NEGATE_EXPR, sizetype, byte_position (array_field)); tree template_addr @@ -865,18 +836,12 @@ gnat_get_array_descr_info (const_tree const_type, template_addr = fold_convert (TYPE_POINTER_TO (bounds_type), template_addr); + thinptr_template_expr + = build_unary_op (INDIRECT_REF, NULL_TREE, template_addr); + thinptr_bound_field = TYPE_FIELDS (bounds_type); + is_array = false; - is_fat_ptr = false; first_dimen = array_type; - - /* The thin pointer is already the pointer to the array data, so there's - no need for a specific "data location" expression. */ - info->data_location = NULL_TREE; - - thinptr_template_expr = build_unary_op (INDIRECT_REF, - bounds_type, - template_addr); - thinptr_bound_field = TYPE_FIELDS (bounds_type); } else @@ -932,7 +897,7 @@ gnat_get_array_descr_info (const_tree const_type, /* We are interested in the stored bounds for the debug info. */ tree index_type = TYPE_INDEX_TYPE (TYPE_DOMAIN (dimen)); - if (is_array || is_fat_ptr) + if (is_array) { /* GDB does not handle very well the self-referencial bound expressions we are able to generate here for XUA types (they are @@ -983,6 +948,7 @@ gnat_get_array_descr_info (const_tree const_type, /* These are Fortran-specific fields. They make no sense here. */ info->allocated = NULL_TREE; info->associated = NULL_TREE; + info->data_location = NULL_TREE; if (gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL) { diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 1527be4f6d1..fb08b6c90ed 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -891,6 +891,9 @@ gnat_pushdecl (tree decl, Node_Id gnat_node) their GNAT encodings. */ if (TREE_CODE (t) == ARRAY_TYPE && !TYPE_NAME (t)) TYPE_NAME (t) = DECL_NAME (decl); + /* Remark the canonical fat pointer type as artificial. */ + if (TYPE_IS_FAT_POINTER_P (t)) + TYPE_ARTIFICIAL (t) = 1; t = NULL_TREE; } else if (TYPE_NAME (t) @@ -4167,7 +4170,6 @@ tree build_unc_object_type (tree template_type, tree object_type, tree name, bool debug_info_p) { - tree decl; tree type = make_node (RECORD_TYPE); tree template_field = create_field_decl (get_identifier ("BOUNDS"), template_type, type, @@ -4183,12 +4185,7 @@ build_unc_object_type (tree template_type, tree object_type, tree name, /* Declare it now since it will never be declared otherwise. This is necessary to ensure that its subtrees are properly marked. */ - decl = create_type_decl (name, type, true, debug_info_p, Empty); - - /* template_type will not be used elsewhere than here, so to keep the debug - info clean and in order to avoid scoping issues, make decl its - context. */ - gnat_set_type_context (template_type, decl); + create_type_decl (name, type, true, debug_info_p, Empty); return type; }