From b3140b1ee59560b33d08e2583c20be5a615e588b Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mjw@redhat.com>
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
@@ -1,3 +1,33 @@
+2014-06-20 Mark Wielaard <mjw@redhat.com>
+
+ * 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 <kyrylo.tkachov@arm.com>
* config/arm/arm_neon.h (vadd_f32): Change #ifdef to __FAST_MATH.
@@ -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;
@@ -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;
@@ -1,3 +1,9 @@
+2014-06-20 Mark Wielaard <mjw@redhat.com>
+
+ * 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 <thomas.preudhomme@arm.com>
PR tree-optimization/61517
new file mode 100644
@@ -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)" } } */
@@ -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