From patchwork Fri Jun 20 11:51:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 362171 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id AB900140088 for ; Fri, 20 Jun 2014 21:51:25 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:from:to:cc:in-reply-to:references:content-type:date :message-id:mime-version; q=dns; s=default; b=jhMd19Liey4ZroCFEt gxUWY3mUveagRJ2wm8gTHw6PATpWqAIX+wocyzMotqBP3jX2ZHsMjDdZYHvWgtl/ tYZsGcHQYHb9RNBTkFZz0Or8WAUm9cT7bFDcAFbYPKTfjfkd8i/4F/1dgT/1O0wz OpQMlpfr0Sn2y6ch9ezFD04aQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:from:to:cc:in-reply-to:references:content-type:date :message-id:mime-version; s=default; bh=bCUsJgiOvBnodSvJjt3PTgRA drY=; b=PxVFI09O57IlSUwI/Xg/T2sSQDYp3onvyav1IPOf5bKKYHffmtLgpGCt ptE/xrlIyTLcHD4j7HsowmCVOW55f+I3SmS288+8fmDybp0mroSaXaBD5K8HiweH W9HsD198U2y1vyGFkpFuOtyfpzGeSvHynMLXGtYHR/WZajLKiIQ= Received: (qmail 13619 invoked by alias); 20 Jun 2014 11:51:18 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 13608 invoked by uid 89); 20 Jun 2014 11:51:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.7 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 20 Jun 2014 11:51:15 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s5KBpDc1032490 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 20 Jun 2014 07:51:13 -0400 Received: from [10.36.116.109] (ovpn-116-109.ams2.redhat.com [10.36.116.109]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s5KBpBSe012115; Fri, 20 Jun 2014 07:51:12 -0400 Subject: Re: [PATCH] dwarf2out.c: Pass DWARF type modifiers around as flags argument. From: Mark Wielaard To: gcc-patches@gcc.gnu.org Cc: Jason Merrill , Cary Coutant In-Reply-To: <1403124937-20437-1-git-send-email-mjw@redhat.com> References: <1403124937-20437-1-git-send-email-mjw@redhat.com> Date: Fri, 20 Jun 2014 13:51:11 +0200 Message-ID: <1403265071.6147.5.camel@bordewijk.wildebeest.org> Mime-Version: 1.0 While adding some new type modifiers I did find a typo in my original patch, so I decided to add some testcases to make sure no regressions were introduced. This is the same patch as the original, but with the typo in modified_type_die fixed that could accidentally add an extra layer of type modifiers and a new test based on the guality.exp testsuite, but tweaked to inspect the type of a variable instead of its value. From b3140b1ee59560b33d08e2583c20be5a615e588b Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 18 Jun 2014 22:41:38 +0200 Subject: [PATCH] dwarf2out.c: Pass type modifiers as flags arguments. Add guality type test. modified_type_die and add_type_attribute take two separate arguments for whether the type should be const and/or volatile. To help add more type modifiers pass the requested modifiers as one flag value to these functions. And introduce helper functions dw_mod_type_flags and dw_mod_decl_flags to easily extract the modifiers from type and declaration trees. Add a new type:var variant to the guality.exp testsuite to check that gdb gets the correct type for a variable and use it to make sure the change doesn't cause any regressions. DWARFv3 added restrict_type [PR debug/59051] and DWARFv5 has proposals for atomic_type and aligned_type. Which will hopefully be easier to implement based on this change. gcc/ChangeLog * dwarf2out.h (enum dw_mod_flag): New enum. * dwarf2out.c (dw_mod_decl_flags): New function. (dw_mod_type_flags): Likewise. (modified_type_die): Take one modifiers flag argument instead of one for const and one for volatile. (add_type_attribute): Likewise. (generic_parameter_die): Call add_type_attribute with one modifier argument. (base_type_for_mode): Likewise. (add_bounds_info): Likewise. (add_subscript_info): Likewise. (gen_array_type_die): Likewise. (gen_descr_array_type_die): Likewise. (gen_entry_point_die): Likewise. (gen_enumeration_type_die): Likewise. (gen_formal_parameter_die): Likewise. (gen_subprogram_die): Likewise. (gen_variable_die): Likewise. (gen_const_die): Likewise. (gen_field_die): Likewise. (gen_pointer_type_die): Likewise. (gen_reference_type_die): Likewise. (gen_ptr_to_mbr_type_die): Likewise. (gen_inheritance_die): Likewise. (gen_subroutine_type_die): Likewise. (gen_typedef_die): Likewise. (force_type_die): Likewise. gcc/testsuite/ChangeLog * lib/gcc-gdb-test.exp (gdb-test): Handle type:var for gdb ptype matching. * gcc/testsuite/gcc.dg/guality/const-volatile.c: New test. --- gcc/ChangeLog | 30 ++++++ gcc/dwarf2out.c | 133 +++++++++++++----------- gcc/dwarf2out.h | 8 ++ gcc/testsuite/ChangeLog | 6 + gcc/testsuite/gcc.dg/guality/const-volatile.c | 83 +++++++++++++++ gcc/testsuite/lib/gcc-gdb-test.exp | 45 ++++++++- 6 files changed, 241 insertions(+), 64 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/guality/const-volatile.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2d0a07c..4dfd9a5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,33 @@ +2014-06-20 Mark Wielaard + + * dwarf2out.h (enum dw_mod_flag): New enum. + * dwarf2out.c (dw_mod_decl_flags): New function. + (dw_mod_type_flags): Likewise. + (modified_type_die): Take one modifiers flag argument instead of + one for const and one for volatile. + (add_type_attribute): Likewise. + (generic_parameter_die): Call add_type_attribute with one modifier + argument. + (base_type_for_mode): Likewise. + (add_bounds_info): Likewise. + (add_subscript_info): Likewise. + (gen_array_type_die): Likewise. + (gen_descr_array_type_die): Likewise. + (gen_entry_point_die): Likewise. + (gen_enumeration_type_die): Likewise. + (gen_formal_parameter_die): Likewise. + (gen_subprogram_die): Likewise. + (gen_variable_die): Likewise. + (gen_const_die): Likewise. + (gen_field_die): Likewise. + (gen_pointer_type_die): Likewise. + (gen_reference_type_die): Likewise. + (gen_ptr_to_mbr_type_die): Likewise. + (gen_inheritance_die): Likewise. + (gen_subroutine_type_die): Likewise. + (gen_typedef_die): Likewise. + (force_type_die): Likewise. + 2014-06-18 Kyrylo Tkachov * config/arm/arm_neon.h (vadd_f32): Change #ifdef to __FAST_MATH. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 933ec62..3d3508d 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -3140,7 +3140,9 @@ static void output_file_names (void); static dw_die_ref base_type_die (tree); static int is_base_type (tree); static dw_die_ref subrange_type_die (tree, tree, tree, dw_die_ref); -static dw_die_ref modified_type_die (tree, int, int, dw_die_ref); +static int dw_mod_decl_flags (const_tree); +static int dw_mod_type_flags (const_tree); +static dw_die_ref modified_type_die (tree, int, dw_die_ref); static dw_die_ref generic_parameter_die (tree, tree, bool, dw_die_ref); static dw_die_ref template_parameter_pack_die (tree, tree, dw_die_ref); static int type_is_enum (const_tree); @@ -3198,7 +3200,7 @@ static dw_die_ref scope_die_for (tree, dw_die_ref); static inline int local_scope_p (dw_die_ref); static inline int class_scope_p (dw_die_ref); static inline int class_or_namespace_scope_p (dw_die_ref); -static void add_type_attribute (dw_die_ref, tree, int, int, dw_die_ref); +static void add_type_attribute (dw_die_ref, tree, int, dw_die_ref); static void add_calling_convention_attribute (dw_die_ref, tree); static const char *type_tag (const_tree); static tree member_declared_type (const_tree); @@ -10498,12 +10500,25 @@ subrange_type_die (tree type, tree low, tree high, dw_die_ref context_die) return subrange_die; } +static int +dw_mod_decl_flags (const_tree decl) +{ + return ((TREE_READONLY (decl) ? dw_mod_const : dw_mod_none) + | (TREE_THIS_VOLATILE (decl) ? dw_mod_volatile : dw_mod_none)); +} + +static int +dw_mod_type_flags (const_tree type) +{ + return ((TYPE_READONLY (type) ? dw_mod_const : dw_mod_none) + | (TYPE_VOLATILE (type) ? dw_mod_volatile : dw_mod_none)); +} + /* Given a pointer to an arbitrary ..._TYPE tree node, return a debugging entry that chains various modifiers in front of the given type. */ static dw_die_ref -modified_type_die (tree type, int is_const_type, int is_volatile_type, - dw_die_ref context_die) +modified_type_die (tree type, int mods, dw_die_ref context_die) { enum tree_code code = TREE_CODE (type); dw_die_ref mod_type_die; @@ -10519,9 +10534,10 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type, /* See if we already have the appropriately qualified variant of this type. */ qualified_type - = get_qualified_type (type, - ((is_const_type ? TYPE_QUAL_CONST : 0) - | (is_volatile_type ? TYPE_QUAL_VOLATILE : 0))); + = get_qualified_type (type, (((mods & dw_mod_const) + ? TYPE_QUAL_CONST : 0) + | ((mods & dw_mod_volatile) + ? TYPE_QUAL_VOLATILE : 0))); if (qualified_type == sizetype && TYPE_NAME (qualified_type) @@ -10559,35 +10575,34 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type, gen_type_die (qualified_type, context_die); return lookup_type_die (qualified_type); } - else if (is_const_type < TYPE_READONLY (dtype) - || is_volatile_type < TYPE_VOLATILE (dtype) - || (is_const_type <= TYPE_READONLY (dtype) - && is_volatile_type <= TYPE_VOLATILE (dtype) + else if ((mods & dw_mod_const) < TYPE_READONLY (dtype) + || (mods & dw_mod_volatile) < TYPE_VOLATILE (dtype) + || ((mods & dw_mod_const) <= TYPE_READONLY (dtype) + && (mods & dw_mod_volatile) <= TYPE_VOLATILE (dtype) && DECL_ORIGINAL_TYPE (name) != type)) /* cv-unqualified version of named type. Just use the unnamed type to which it refers. */ - return modified_type_die (DECL_ORIGINAL_TYPE (name), - is_const_type, is_volatile_type, + return modified_type_die (DECL_ORIGINAL_TYPE (name), mods, context_die); /* Else cv-qualified version of named type; fall through. */ } mod_scope = scope_die_for (type, context_die); - if (is_const_type - /* If both is_const_type and is_volatile_type, prefer the path + if ((mods & dw_mod_const) + /* If both const_type and volatile_type, prefer the path which leads to a qualified type. */ - && (!is_volatile_type + && (!(mods & dw_mod_volatile) || get_qualified_type (type, TYPE_QUAL_CONST) == NULL_TREE || get_qualified_type (type, TYPE_QUAL_VOLATILE) != NULL_TREE)) { mod_type_die = new_die (DW_TAG_const_type, mod_scope, type); - sub_die = modified_type_die (type, 0, is_volatile_type, context_die); + sub_die = modified_type_die (type, mods & ~dw_mod_const, context_die); } - else if (is_volatile_type) + else if (mods & dw_mod_volatile) { mod_type_die = new_die (DW_TAG_volatile_type, mod_scope, type); - sub_die = modified_type_die (type, is_const_type, 0, context_die); + sub_die = modified_type_die (type, mods & ~dw_mod_volatile, context_die); } else if (code == POINTER_TYPE) { @@ -10648,7 +10663,7 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type, if (name && ((TREE_CODE (name) != TYPE_DECL && (qualified_type == TYPE_MAIN_VARIANT (type) - || (!is_const_type && !is_volatile_type))) + || (mods == dw_mod_none))) || (TREE_CODE (name) == TYPE_DECL && TREE_TYPE (name) == qualified_type && DECL_NAME (name)))) @@ -10676,9 +10691,7 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type, this is a recursive type. This ensures that the modified_type_die recursion will terminate even if the type is recursive. Recursive types are possible in Ada. */ - sub_die = modified_type_die (item_type, - TYPE_READONLY (item_type), - TYPE_VOLATILE (item_type), + sub_die = modified_type_die (item_type, dw_mod_type_flags (item_type), context_die); if (sub_die != NULL) @@ -10820,8 +10833,9 @@ generic_parameter_die (tree parm, tree arg, If PARM is a type generic parameter, TMPL_DIE should have a child DW_AT_type that is set to ARG. */ tmpl_type = TYPE_P (arg) ? arg : TREE_TYPE (arg); - add_type_attribute (tmpl_die, tmpl_type, 0, - TREE_THIS_VOLATILE (tmpl_type), + add_type_attribute (tmpl_die, tmpl_type, + (TREE_THIS_VOLATILE (tmpl_type) + ? dw_mod_volatile : dw_mod_none), parent_die); } else @@ -11563,7 +11577,7 @@ base_type_for_mode (enum machine_mode mode, bool unsignedp) } type_die = lookup_type_die (type); if (!type_die) - type_die = modified_type_die (type, false, false, comp_unit_die ()); + type_die = modified_type_die (type, dw_mod_none, comp_unit_die ()); if (type_die == NULL || type_die->die_tag != DW_TAG_base_type) return NULL; return type_die; @@ -16480,7 +16494,7 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b decl_die = new_die (DW_TAG_variable, ctx, bound); add_AT_flag (decl_die, DW_AT_artificial, 1); - add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx); + add_type_attribute (decl_die, TREE_TYPE (bound), dw_mod_const, ctx); add_AT_location_description (decl_die, DW_AT_location, list); add_AT_die_ref (subrange_die, bound_attr, decl_die); break; @@ -16531,8 +16545,8 @@ add_subscript_info (dw_die_ref type_die, tree type, bool collapse_p) && TYPE_NAME (TREE_TYPE (domain)) == NULL_TREE) ; else - add_type_attribute (subrange_die, TREE_TYPE (domain), 0, 0, - type_die); + add_type_attribute (subrange_die, TREE_TYPE (domain), + dw_mod_none, type_die); } /* ??? If upper is NULL, the array has unspecified length, @@ -17026,8 +17040,8 @@ class_or_namespace_scope_p (dw_die_ref context_die) by 'type', and adds a DW_AT_type attribute below the given die. */ static void -add_type_attribute (dw_die_ref object_die, tree type, int decl_const, - int decl_volatile, dw_die_ref context_die) +add_type_attribute (dw_die_ref object_die, tree type, int mods, + dw_die_ref context_die) { enum tree_code code = TREE_CODE (type); dw_die_ref type_die = NULL; @@ -17047,9 +17061,7 @@ add_type_attribute (dw_die_ref object_die, tree type, int decl_const, || code == VOID_TYPE) return; - type_die = modified_type_die (type, - decl_const || TYPE_READONLY (type), - decl_volatile || TYPE_VOLATILE (type), + type_die = modified_type_die (type, mods | dw_mod_type_flags (type), context_die); if (type_die != NULL) @@ -17263,7 +17275,7 @@ gen_array_type_die (tree type, dw_die_ref context_die) element_type = TREE_TYPE (element_type); } - add_type_attribute (array_die, element_type, 0, 0, context_die); + add_type_attribute (array_die, element_type, dw_mod_none, context_die); add_gnat_descriptive_type_attribute (array_die, type, context_die); if (TYPE_ARTIFICIAL (type)) @@ -17426,7 +17438,7 @@ gen_descr_array_type_die (tree type, struct array_descr_info *info, } gen_type_die (info->element_type, context_die); - add_type_attribute (array_die, info->element_type, 0, 0, context_die); + add_type_attribute (array_die, info->element_type, dw_mod_none, context_die); if (get_AT (array_die, DW_AT_name)) add_pubtype (type, array_die); @@ -17445,7 +17457,7 @@ gen_entry_point_die (tree decl, dw_die_ref context_die) { add_name_and_src_coords_attributes (decl_die, decl); add_type_attribute (decl_die, TREE_TYPE (TREE_TYPE (decl)), - 0, 0, context_die); + dw_mod_none, context_die); } if (DECL_ABSTRACT (decl)) @@ -17535,7 +17547,7 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die) if (dwarf_version >= 3 || !dwarf_strict) { tree underlying = lang_hooks.types.enum_underlying_base_type (type); - add_type_attribute (type_die, underlying, 0, 0, context_die); + add_type_attribute (type_die, underlying, dw_mod_none, context_die); } if (TYPE_STUB_DECL (type) != NULL_TREE) { @@ -17636,12 +17648,11 @@ gen_formal_parameter_die (tree node, tree origin, bool emit_name_p, { tree type = TREE_TYPE (node_or_origin); if (decl_by_reference_p (node_or_origin)) - add_type_attribute (parm_die, TREE_TYPE (type), 0, 0, + add_type_attribute (parm_die, TREE_TYPE (type), dw_mod_none, context_die); else add_type_attribute (parm_die, type, - TREE_READONLY (node_or_origin), - TREE_THIS_VOLATILE (node_or_origin), + dw_mod_decl_flags (node_or_origin), context_die); } if (origin == NULL && DECL_ARTIFICIAL (node)) @@ -17657,7 +17668,7 @@ gen_formal_parameter_die (tree node, tree origin, bool emit_name_p, case tcc_type: /* We were called with some kind of a ..._TYPE node. */ - add_type_attribute (parm_die, node_or_origin, 0, 0, context_die); + add_type_attribute (parm_die, node_or_origin, dw_mod_none, context_die); break; default: @@ -18239,7 +18250,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) dw_die_ref die = get_AT_ref (old_die, DW_AT_type); if (die == auto_die || die == decltype_auto_die) add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)), - 0, 0, context_die); + dw_mod_none, context_die); } } } @@ -18256,7 +18267,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) { add_prototyped_attribute (subr_die, TREE_TYPE (decl)); add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)), - 0, 0, context_die); + dw_mod_none, context_die); } add_pure_or_virtual_attribute (subr_die, decl); @@ -18871,8 +18882,8 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) } var_die = new_die (DW_TAG_variable, com_die, decl); add_name_and_src_coords_attributes (var_die, decl); - add_type_attribute (var_die, TREE_TYPE (decl), TREE_READONLY (decl), - TREE_THIS_VOLATILE (decl), context_die); + add_type_attribute (var_die, TREE_TYPE (decl), dw_mod_decl_flags (decl), + context_die); add_AT_flag (var_die, DW_AT_external, 1); if (loc) { @@ -18965,10 +18976,11 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) tree type = TREE_TYPE (decl_or_origin); if (decl_by_reference_p (decl_or_origin)) - add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die); + add_type_attribute (var_die, TREE_TYPE (type), dw_mod_none, + context_die); else - add_type_attribute (var_die, type, TREE_READONLY (decl_or_origin), - TREE_THIS_VOLATILE (decl_or_origin), context_die); + add_type_attribute (var_die, type, dw_mod_decl_flags (decl_or_origin), + context_die); } if (origin == NULL && !specialization_p) @@ -19022,7 +19034,7 @@ gen_const_die (tree decl, dw_die_ref context_die) const_die = new_die (DW_TAG_constant, context_die, decl); add_name_and_src_coords_attributes (const_die, decl); - add_type_attribute (const_die, type, 1, 0, context_die); + add_type_attribute (const_die, type, dw_mod_const, context_die); if (TREE_PUBLIC (decl)) add_AT_flag (const_die, DW_AT_external, 1); if (DECL_ARTIFICIAL (decl)) @@ -19265,8 +19277,7 @@ gen_field_die (tree decl, dw_die_ref context_die) decl_die = new_die (DW_TAG_member, context_die, decl); add_name_and_src_coords_attributes (decl_die, decl); add_type_attribute (decl_die, member_declared_type (decl), - TREE_READONLY (decl), TREE_THIS_VOLATILE (decl), - context_die); + dw_mod_decl_flags (decl), context_die); if (DECL_BIT_FIELD_TYPE (decl)) { @@ -19300,7 +19311,7 @@ gen_pointer_type_die (tree type, dw_die_ref context_die) = new_die (DW_TAG_pointer_type, scope_die_for (type, context_die), type); equate_type_number_to_die (type, ptr_die); - add_type_attribute (ptr_die, TREE_TYPE (type), 0, 0, context_die); + add_type_attribute (ptr_die, TREE_TYPE (type), dw_mod_none, context_die); add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE); } @@ -19320,7 +19331,7 @@ gen_reference_type_die (tree type, dw_die_ref context_die) ref_die = new_die (DW_TAG_reference_type, scope_die, type); equate_type_number_to_die (type, ref_die); - add_type_attribute (ref_die, TREE_TYPE (type), 0, 0, context_die); + add_type_attribute (ref_die, TREE_TYPE (type), dw_mod_none, context_die); add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE); } #endif @@ -19337,7 +19348,7 @@ gen_ptr_to_mbr_type_die (tree type, dw_die_ref context_die) equate_type_number_to_die (type, ptr_die); add_AT_die_ref (ptr_die, DW_AT_containing_type, lookup_type_die (TYPE_OFFSET_BASETYPE (type))); - add_type_attribute (ptr_die, TREE_TYPE (type), 0, 0, context_die); + add_type_attribute (ptr_die, TREE_TYPE (type), dw_mod_none, context_die); } typedef const char *dchar_p; /* For DEF_VEC_P. */ @@ -19542,7 +19553,7 @@ gen_inheritance_die (tree binfo, tree access, dw_die_ref context_die) { dw_die_ref die = new_die (DW_TAG_inheritance, context_die, binfo); - add_type_attribute (die, BINFO_TYPE (binfo), 0, 0, context_die); + add_type_attribute (die, BINFO_TYPE (binfo), dw_mod_none, context_die); add_data_member_location_attribute (die, binfo); if (BINFO_VIRTUAL_P (binfo)) @@ -19739,7 +19750,7 @@ gen_subroutine_type_die (tree type, dw_die_ref context_die) equate_type_number_to_die (type, subr_die); add_prototyped_attribute (subr_die, type); - add_type_attribute (subr_die, return_type, 0, 0, context_die); + add_type_attribute (subr_die, return_type, dw_mod_none, context_die); gen_formal_types_die (type, subr_die); if (get_AT (subr_die, DW_AT_name)) @@ -19807,8 +19818,8 @@ gen_typedef_die (tree decl, dw_die_ref context_die) } } - add_type_attribute (type_die, type, TREE_READONLY (decl), - TREE_THIS_VOLATILE (decl), context_die); + add_type_attribute (type_die, type, dw_mod_decl_flags (decl), + context_die); if (is_naming_typedef_decl (decl)) /* We want that all subsequent calls to lookup_type_die with @@ -20383,8 +20394,8 @@ force_type_die (tree type) { dw_die_ref context_die = get_context_die (TYPE_CONTEXT (type)); - type_die = modified_type_die (type, TYPE_READONLY (type), - TYPE_VOLATILE (type), context_die); + type_die = modified_type_die (type, dw_mod_type_flags (type), + context_die); gcc_assert (type_die); } return type_die; diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h index bac5077..e7de4f8 100644 --- a/gcc/dwarf2out.h +++ b/gcc/dwarf2out.h @@ -46,6 +46,14 @@ enum dw_cfi_oprnd_type { dw_cfi_oprnd_loc }; +/* DWARF type modifier flags for base types. Used by + modified_type_die () to chain a base type. */ +enum dw_mod_flag { + dw_mod_none = 0, + dw_mod_const = 1 << 1, + dw_mod_volatile = 1 << 2 +}; + typedef union GTY(()) { unsigned int GTY ((tag ("dw_cfi_oprnd_reg_num"))) dw_cfi_reg_num; HOST_WIDE_INT GTY ((tag ("dw_cfi_oprnd_offset"))) dw_cfi_offset; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c673056..1a94e1b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-06-20 Mark Wielaard + + * lib/gcc-gdb-test.exp (gdb-test): Handle type:var for gdb ptype + matching. + * gcc/testsuite/gcc.dg/guality/const-volatile.c: New test. + 2014-06-18 Thomas Preud'homme PR tree-optimization/61517 diff --git a/gcc/testsuite/gcc.dg/guality/const-volatile.c b/gcc/testsuite/gcc.dg/guality/const-volatile.c new file mode 100644 index 0000000..6c2b617 --- /dev/null +++ b/gcc/testsuite/gcc.dg/guality/const-volatile.c @@ -0,0 +1,83 @@ +/* debuginfo tests for combinations of const and volatile type qualifiers. */ +/* { dg-do run } */ +/* { dg-options "-g" } */ + +int i; +const int ci; +volatile int vi; +const volatile int cvi; + +int *pi; +const int *pci; +volatile int *pvi; +const volatile int *pcvi; + +int * const cip; +int * volatile vip; +int * const volatile cvip; + +volatile struct +{ + const long cli; + const signed char csc; +} vs; + +struct foo +{ + const long cli; + const signed char csc; +}; + +struct foo foo; +const struct foo cfoo; +volatile struct foo vfoo; +const volatile struct foo cvfoo; + +typedef volatile signed char score; + +score s; +const score cs; + +static __attribute__((noclone, noinline)) int +f (const char *progname, volatile struct foo *dummy, const score s) +{ + return progname == 0 || dummy == 0 || dummy->csc == s; +} + +int +main (int argc, char **argv) +{ + score as = argc; + struct foo dummy = { 1, 1 }; + return f (argv[0], &dummy, as) - 1; +} + +/* { dg-final { gdb-test 50 "type:main" "int (int, char **)" } } */ + +/* { dg-final { gdb-test 50 "type:i" "int" } } */ +/* { dg-final { gdb-test 50 "type:ci" "const int" } } */ +/* { dg-final { gdb-test 50 "type:vi" "volatile int" } } */ +/* { dg-final { gdb-test 50 "type:cvi" "const volatile int" } } */ + +/* { dg-final { gdb-test 50 "type:pi" "int *" } } */ +/* { dg-final { gdb-test 50 "type:pci" "const int *" } } */ +/* { dg-final { gdb-test 50 "type:pvi" "volatile int *" } } */ +/* { dg-final { gdb-test 50 "type:pcvi" "const volatile int *" } } */ + +/* { dg-final { gdb-test 50 "type:cip" "int * const" } } */ +/* { dg-final { gdb-test 50 "type:vip" "int * volatile" } } */ +/* { dg-final { gdb-test 50 "type:cvip" "int * const volatile" } } */ + +/* { dg-final { gdb-test 50 "type:vs" "volatile struct { const long cli; const signed char csc; }" } } */ + +/* { dg-final { gdb-test 50 "type:cvip" "int * const volatile" } } */ + +/* { dg-final { gdb-test 50 "type:foo" "struct foo { const long cli; const signed char csc; }" } } */ +/* { dg-final { gdb-test 50 "type:cfoo" "const struct foo { const long cli; const signed char csc; }" } } */ +/* { dg-final { gdb-test 50 "type:vfoo" "volatile struct foo { const long cli; const signed char csc; }" } } */ +/* { dg-final { gdb-test 50 "type:cvfoo" "const volatile struct foo { const long cli; const signed char csc; }" } } */ + +/* { dg-final { gdb-test 58 "type:s" "volatile signed char" } } */ +/* { dg-final { gdb-test 50 "type:cs" "const volatile signed char" } } */ + +/* { dg-final { gdb-test 50 "type:f" "int (const char *, volatile struct foo *, const score)" } } */ diff --git a/gcc/testsuite/lib/gcc-gdb-test.exp b/gcc/testsuite/lib/gcc-gdb-test.exp index d182d88..0a8a6df 100644 --- a/gcc/testsuite/lib/gcc-gdb-test.exp +++ b/gcc/testsuite/lib/gcc-gdb-test.exp @@ -19,7 +19,12 @@ # # Argument 0 is the line number on which to put a breakpoint # Argument 1 is the name of the variable to be checked -# Argument 2 is the expected value of the variable +# possibly prefixed with type: to get the type of the variable +# instead of the value of the variable (the default). +# Argument 2 is the expected value (or type) of the variable +# When asking for the value, the expected value is produced +# calling print on it in gdb. When asking for the type it is +# the literal string with extra whitespace removed. # Argument 3 handles expected failures and the like proc gdb-test { args } { if { ![isnative] || [is_remote target] } { return } @@ -39,6 +44,16 @@ proc gdb-test { args } { upvar 2 name testcase upvar 2 prog prog + # The command to run on the variable + set arg1 [lindex $args 1] + if { [string equal -length 5 "type:" $arg1] == 1 } { + set command "ptype" + set var [string range $arg1 5 end] + } else { + set command "print" + set var $arg1 + } + set gdb_name $::env(GUALITY_GDB_NAME) set testname "$testcase line [lindex $args 0] [lindex $args 1] == [lindex $args 2]" set output_file "[file rootname [file tail $prog]].exe" @@ -47,8 +62,14 @@ proc gdb-test { args } { set fd [open $cmd_file "w"] puts $fd "break [lindex $args 0]" puts $fd "run" - puts $fd "print [lindex $args 1]" - puts $fd "print [lindex $args 2]" + puts $fd "$command $var" + if { $command == "print" } { + # For values, let gdb interpret them by printing them. + puts $fd "print [lindex $args 2]" + } else { + # Since types can span multiple lines, we need an end marker. + puts $fd "echo TYPE_END\\n" + } puts $fd "quit" close $fd @@ -68,6 +89,7 @@ proc gdb-test { args } { file delete $cmd_file return } + # print var; print expected -re {[\n\r]\$1 = ([^\n\r]*)[\n\r]+\$2 = ([^\n\r]*)[\n\r]} { set first $expect_out(1,string) set second $expect_out(2,string) @@ -83,6 +105,23 @@ proc gdb-test { args } { file delete $cmd_file return } + # ptype var; + -re {[\n\r]type = (.*)[\n\r][\n\r]TYPE_END[\n\r]} { + set type $expect_out(1,string) + # Squash all extra whitespace/newlines that gdb might use for + # "pretty printing" into one so result is just one line. + regsub -all {[\n\r\t ]+} $type " " type + set expected [lindex $args 2] + if { $type == $expected } { + pass "$testname" + } else { + send_log -- "$type != $expected\n" + fail "$testname" + } + remote_close target + file delete $cmd_file + return + } timeout { unsupported "$testname" remote_close target -- 1.7.1