public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] dwarf2out.c: Pass DWARF type modifiers around as flags argument.
@ 2014-06-18 20:56 Mark Wielaard
  2014-06-20 11:51 ` Mark Wielaard
  0 siblings, 1 reply; 30+ messages in thread
From: Mark Wielaard @ 2014-06-18 20:56 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill, Cary Coutant, Mark Wielaard

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.

DWARFv3 added restrict_type [PR debug/59051] and DWARFv5 has proposals
for atomic_type and aligned_type) pass the requested modifiers as one
flag value to these functions. 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/ChangeLog   |   30 ++++++++++++
 gcc/dwarf2out.c |  133 ++++++++++++++++++++++++++++++-------------------------
 gcc/dwarf2out.h |    8 +++
 3 files changed, 110 insertions(+), 61 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2d0a07c..d7ee868 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,33 @@
+2014-06-18  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.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 933ec62..0216801 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 (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;
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] dwarf2out.c: Pass DWARF type modifiers around as flags argument.
  2014-06-18 20:56 [PATCH] dwarf2out.c: Pass DWARF type modifiers around as flags argument Mark Wielaard
@ 2014-06-20 11:51 ` Mark Wielaard
  2014-06-20 23:02   ` [PATCH] Emit DW_tag_restrict_type for restrict-qualified pointers Mark Wielaard
  2014-07-03  9:53   ` [PATCH] Add guality [p]type test Mark Wielaard
  0 siblings, 2 replies; 30+ messages in thread
From: Mark Wielaard @ 2014-06-20 11:51 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill, Cary Coutant

[-- Attachment #1: Type: text/plain, Size: 422 bytes --]

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.

[-- Attachment #2: 0001-dwarf2out.c-Pass-type-modifiers-as-flags-arguments.-.patch --]
[-- Type: text/x-patch, Size: 27008 bytes --]

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

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  <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.
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  <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
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


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH] Emit DW_tag_restrict_type for restrict-qualified pointers.
  2014-06-20 11:51 ` Mark Wielaard
@ 2014-06-20 23:02   ` Mark Wielaard
  2014-06-22  9:39     ` [PATCH] DWARFv5 Emit DW_TAG_atomic_type Mark Wielaard
                       ` (2 more replies)
  2014-07-03  9:53   ` [PATCH] Add guality [p]type test Mark Wielaard
  1 sibling, 3 replies; 30+ messages in thread
From: Mark Wielaard @ 2014-06-20 23:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill, Cary Coutant, jsm28, Mark Wielaard

The following patch is based on and extends the guality test from my
earlier "Pass type modifiers as flags arguments. Add guality type test."
patch.

gcc/ChangeLog

	PR debug/59051
	* dwarf2out.h (enum dw_mod_flag): Add dw_mod_restrict.
	* dwarf2out.c (dw_mod_decl_flags): Handle TYPE_RESTRICT.
	(dw_mod_type_flags): Likewise.
	(dw_mods_to_quals): New function.
	(dw_mod_qualified_type): Likewise.
	(modified_type_die): Handle dw_mod_restrict.

gcc/testsuite/ChangeLog

	PR debug/59051
	* gcc.dg/guality/restrict.c: New test.
---
 gcc/ChangeLog                           |   10 ++++
 gcc/dwarf2out.c                         |   76 +++++++++++++++++++++++++-----
 gcc/dwarf2out.h                         |    1 +
 gcc/testsuite/ChangeLog                 |    4 ++
 gcc/testsuite/gcc.dg/guality/restrict.c |   48 +++++++++++++++++++
 5 files changed, 126 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/guality/restrict.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4dfd9a5..06a8767 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,15 @@
 2014-06-20  Mark Wielaard  <mjw@redhat.com>
 
+	PR debug/59051
+	* dwarf2out.h (enum dw_mod_flag): Add dw_mod_restrict.
+	* dwarf2out.c (dw_mod_decl_flags): Handle TYPE_RESTRICT.
+	(dw_mod_type_flags): Likewise.
+	(dw_mods_to_quals): New function.
+	(dw_mod_qualified_type): Likewise.
+	(modified_type_die): Handle dw_mod_restrict.
+
+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.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 3d3508d..b99d1b9 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -10504,14 +10504,52 @@ 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));
+	  | (TREE_THIS_VOLATILE (decl) ? dw_mod_volatile : dw_mod_none)
+	  | ((POINTER_TYPE_P (TREE_TYPE (decl))
+	      && TYPE_RESTRICT (TREE_TYPE (decl)))
+	     ? dw_mod_restrict : 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));
+	  | (TYPE_VOLATILE (type) ? dw_mod_volatile : dw_mod_none)
+	  | ((POINTER_TYPE_P (type) && TYPE_RESTRICT (type))
+	     ? dw_mod_restrict : dw_mod_none));
+}
+
+static int
+dw_mods_to_quals (int mods)
+{
+  return (((mods & dw_mod_const) ? TYPE_QUAL_CONST : 0)
+	  | ((mods & dw_mod_volatile) ? TYPE_QUAL_VOLATILE : 0)
+	  | ((mods & dw_mod_restrict) ? TYPE_QUAL_RESTRICT : 0));
+}
+
+/* Returns true if there is a qualified type with at least one
+   modifier given in mods.  Returns false if mods == dw_mod_none or
+   there is no qualified type with at least one of the given mods.  */
+
+static bool
+dw_mod_qualified_type (tree type, int mods)
+{
+  if (mods == dw_mod_none)
+    return false;
+
+  if (get_qualified_type (type, dw_mods_to_quals (mods)) != NULL_TREE)
+    return true;
+
+  if (mods & dw_mod_const)
+    return dw_mod_qualified_type (type, mods & ~dw_mod_const);
+
+  if (mods & dw_mod_volatile)
+    return dw_mod_qualified_type (type, mods & ~dw_mod_volatile);
+
+  if (mods & dw_mod_restrict)
+    return dw_mod_qualified_type (type, mods & ~dw_mod_restrict);
+
+  gcc_unreachable ();
 }
 
 /* Given a pointer to an arbitrary ..._TYPE tree node, return a debugging
@@ -10531,13 +10569,15 @@ modified_type_die (tree type, int mods, dw_die_ref context_die)
   if (code == ERROR_MARK)
     return NULL;
 
+  /* Don't emit DW_TAG_restrict_type for DWARFv2, since it is a type
+     tag modifier (and not an attribute) old consumers won't be able
+     to handle it.  */
+  if (dwarf_version < 3)
+    mods &= ~dw_mod_restrict;
+
   /* See if we already have the appropriately qualified variant of
      this type.  */
-  qualified_type
-    = get_qualified_type (type, (((mods & dw_mod_const)
-				  ? TYPE_QUAL_CONST : 0)
-				 | ((mods & dw_mod_volatile)
-				    ? TYPE_QUAL_VOLATILE : 0)));
+  qualified_type = get_qualified_type (type, dw_mods_to_quals (mods));
 
   if (qualified_type == sizetype
       && TYPE_NAME (qualified_type)
@@ -10577,8 +10617,10 @@ modified_type_die (tree type, int mods, dw_die_ref context_die)
 	}
       else if ((mods & dw_mod_const) < TYPE_READONLY (dtype)
 	       || (mods & dw_mod_volatile) < TYPE_VOLATILE (dtype)
+	       || (mods & dw_mod_restrict) < TYPE_RESTRICT (dtype)
 	       || ((mods & dw_mod_const) <= TYPE_READONLY (dtype)
 		   && (mods & dw_mod_volatile) <= TYPE_VOLATILE (dtype)
+		   && (mods & dw_mod_restrict) <= TYPE_RESTRICT (dtype)
 		   && DECL_ORIGINAL_TYPE (name) != type))
 	/* cv-unqualified version of named type.  Just use the unnamed
 	   type to which it refers.  */
@@ -10590,20 +10632,28 @@ modified_type_die (tree type, int mods, dw_die_ref context_die)
   mod_scope = scope_die_for (type, context_die);
 
   if ((mods & dw_mod_const)
-      /* If both const_type and volatile_type, prefer the path
-	 which leads to a qualified type.  */
-      && (!(mods & dw_mod_volatile)
-	  || get_qualified_type (type, TYPE_QUAL_CONST) == NULL_TREE
-	  || get_qualified_type (type, TYPE_QUAL_VOLATILE) != NULL_TREE))
+      /* If there are multiple type modifiers, prefer a path which
+	 leads to a qualified type.  */
+      && (((mods & ~dw_mod_const) == dw_mod_none)
+	  || get_qualified_type (type, dw_mods_to_quals (mods)) == NULL_TREE
+	  || dw_mod_qualified_type (type, mods & ~dw_mod_const)))
     {
       mod_type_die = new_die (DW_TAG_const_type, mod_scope, type);
       sub_die = modified_type_die (type, mods & ~dw_mod_const, context_die);
     }
-  else if (mods & dw_mod_volatile)
+  else if ((mods & dw_mod_volatile)
+	   && (((mods & ~dw_mod_volatile) == dw_mod_none)
+	       || get_qualified_type (type, dw_mods_to_quals (mods)) == NULL_TREE
+	       || dw_mod_qualified_type (type, mods & ~dw_mod_volatile)))
     {
       mod_type_die = new_die (DW_TAG_volatile_type, mod_scope, type);
       sub_die = modified_type_die (type, mods & ~dw_mod_volatile, context_die);
     }
+  else if (mods & dw_mod_restrict)
+    {
+      mod_type_die = new_die (DW_TAG_restrict_type, mod_scope, type);
+      sub_die = modified_type_die (type, mods & ~dw_mod_restrict, context_die);
+    }
   else if (code == POINTER_TYPE)
     {
       mod_type_die = new_die (DW_TAG_pointer_type, mod_scope, type);
diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h
index e7de4f8..7c109ea 100644
--- a/gcc/dwarf2out.h
+++ b/gcc/dwarf2out.h
@@ -50,6 +50,7 @@ enum dw_cfi_oprnd_type {
    modified_type_die () to chain a base type.  */
 enum dw_mod_flag {
   dw_mod_none = 0,
+  dw_mod_restrict = 1,
   dw_mod_const = 1 << 1,
   dw_mod_volatile = 1 << 2
 };
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1a94e1b..9c5418c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
 2014-06-20  Mark Wielaard  <mjw@redhat.com>
 
+	* gcc.dg/guality/restrict.c: New test.
+
+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.
diff --git a/gcc/testsuite/gcc.dg/guality/restrict.c b/gcc/testsuite/gcc.dg/guality/restrict.c
new file mode 100644
index 0000000..aba30b1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/restrict.c
@@ -0,0 +1,48 @@
+/* debuginfo tests for combinations of const, volatile, restrict pointers. */
+/* { dg-do run } */
+/* { dg-options "-std=c99 -g" } */
+
+int *ip;
+const int *cip;
+int * restrict irp;
+int * const icp;
+const int * restrict cirp;
+int * const restrict icrp;
+const int * const restrict cicrp;
+
+int * const volatile restrict cvirp;
+const volatile int * restrict pcvir;
+
+static __attribute__((noclone, noinline)) void *
+cpy (void * restrict s1, const void * restrict s2, unsigned int n)
+{
+  char *t1 = s1;
+  const char *t2 = s2;
+  while(n-- > 0)
+    *t1++ = *t2++;
+  return s1;
+}
+
+int
+main (int argc, char **argv)
+{
+  void *foo = 0;
+  if (argc > 16)
+    foo = cpy (argv[0], argv[1], argc);
+
+  return foo != 0;
+}
+
+/* { dg-final { gdb-test 30 "type:ip" "int *" } } */
+/* { dg-final { gdb-test 30 "type:cip" "const int *" } } */
+/* { dg-final { gdb-test 30 "type:irp" "int * restrict" } } */
+/* { dg-final { gdb-test 30 "type:icp" "int * const" } } */
+/* { dg-final { gdb-test 30 "type:cirp" "const int * restrict" } } */
+/* { dg-final { gdb-test 30 "type:icrp" "int * const restrict" } } */
+/* { dg-final { gdb-test 30 "type:cicrp" "const int * const restrict" } } */
+
+/* { dg-final { gdb-test 30 "type:cvirp" "int * const volatile restrict" } } */
+/* { dg-final { gdb-test 30 "type:pcvir" "const volatile int * restrict" } } */
+
+/* { dg-final { gdb-test 30 "type:main" "int (int, char **)" } } */
+/* { dg-final { gdb-test 30 "type:cpy" "void *(void * restrict, const void * restrict, unsigned int)" } } */
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH] DWARFv5 Emit DW_TAG_atomic_type.
  2014-06-20 23:02   ` [PATCH] Emit DW_tag_restrict_type for restrict-qualified pointers Mark Wielaard
@ 2014-06-22  9:39     ` Mark Wielaard
  2014-06-23 16:32       ` Tom Tromey
  2014-07-08 16:39     ` [PATCH 1/2] dwarf2out.c: Pass one cv_quals argument instead of two for const and volatile Mark Wielaard
  2014-07-08 16:39     ` [PATCH 2/2] Emit DW_tag_restrict_type for restrict-qualified pointers Mark Wielaard
  2 siblings, 1 reply; 30+ messages in thread
From: Mark Wielaard @ 2014-06-22  9:39 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill, Cary Coutant, jsm28, Mark Wielaard

The following is just a prototype to try out a new qualifier type tag
proposed for DWARFv5. There is not even a draft yet of DWARFv5, so this
is just based on a proposal that might or might not be adopted and/or
changed http://dwarfstd.org/ShowIssue.php?issue=131112.1

I have a corresponding patch for GDB so that the new testcase added
PASSes. But without that patch the guality.exp tests will notice GDB
doesn't recognize the new type (or DWARFv5 in general of course) and
just mark the test as UNSUPPORTED.

Since there is not even a draft of DWARFv5 I don't recommend adopting
this patch. All details may change in the future. I am mainly doing it
to give better feedback on the DWARFv5 proposals (in this case the
feedback would be that it is unfortunate we cannot easily do this as a
vendor extension with DW_TAG_GNU_atomic_type since that would break
backward compatibility). Feedback on the patch is of course still very
welcome.

Is there a recommended way for doing/keeping these kind of speculative
patches? I'll keep a local git branch with my experiments that I'll
rebase against master for larger updates. And would like to send out
new patches to the list for review even if we won't adopt them for now.
But if there is a better way/best practice for this kind of experimental
changes based on just ideas for a next version of a not yet public
standard please let me know.

gcc/ChangeLog

	* dwarf2out.h (enum dw_mod_flag): Add dw_mod_atomic.
	* dwarf2out.c (dw_mod_decl_flags): Handle TYPE_ATOMIC.
	(dw_mod_type_flags): Likewise.
	(dw_mods_to_quals): Likewise.
	(dw_mod_qualified_type): Likewise.
	(modified_type_die): Likewise.
	opts.c (common_handle_option): Accept -gdwarf-5.

gcc/testsuite/ChangeLog

	* lib/gcc-gdb-test.exp (gdb-test): Catch '<unknown type in ' to
	recognize older gdb versions.
	* gcc.dg/guality/atomic.c: New test.

include/ChangeLog

	* dwarf2.def: Add DWARFv5 DW_TAG_atomic_type.
---
 gcc/ChangeLog                         |   10 ++++++++++
 gcc/dwarf2out.c                       |   28 ++++++++++++++++++++++++----
 gcc/dwarf2out.h                       |    3 ++-
 gcc/opts.c                            |    2 +-
 gcc/testsuite/ChangeLog               |    6 ++++++
 gcc/testsuite/gcc.dg/guality/atomic.c |   13 +++++++++++++
 gcc/testsuite/lib/gcc-gdb-test.exp    |    2 +-
 include/ChangeLog                     |    4 ++++
 include/dwarf2.def                    |    2 ++
 9 files changed, 63 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/guality/atomic.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 06a8767..4d81763 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2014-06-22  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf2out.h (enum dw_mod_flag): Add dw_mod_atomic.
+	* dwarf2out.c (dw_mod_decl_flags): Handle TYPE_ATOMIC.
+	(dw_mod_type_flags): Likewise.
+	(dw_mods_to_quals): Likewise.
+	(dw_mod_qualified_type): Likewise.
+	(modified_type_die): Likewise.
+	opts.c (common_handle_option): Accept -gdwarf-5.
+
 2014-06-20  Mark Wielaard  <mjw@redhat.com>
 
 	PR debug/59051
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index b99d1b9..2b8a4bd 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -10507,7 +10507,8 @@ dw_mod_decl_flags (const_tree decl)
 	  | (TREE_THIS_VOLATILE (decl) ? dw_mod_volatile : dw_mod_none)
 	  | ((POINTER_TYPE_P (TREE_TYPE (decl))
 	      && TYPE_RESTRICT (TREE_TYPE (decl)))
-	     ? dw_mod_restrict : dw_mod_none));
+	     ? dw_mod_restrict : dw_mod_none)
+	  | (TYPE_ATOMIC (TREE_TYPE (decl)) ? dw_mod_atomic : dw_mod_none));
 }
 
 static int
@@ -10516,7 +10517,8 @@ 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)
 	  | ((POINTER_TYPE_P (type) && TYPE_RESTRICT (type))
-	     ? dw_mod_restrict : dw_mod_none));
+	     ? dw_mod_restrict : dw_mod_none)
+	  | (TYPE_ATOMIC (type) ? dw_mod_atomic : dw_mod_none));
 }
 
 static int
@@ -10524,7 +10526,8 @@ dw_mods_to_quals (int mods)
 {
   return (((mods & dw_mod_const) ? TYPE_QUAL_CONST : 0)
 	  | ((mods & dw_mod_volatile) ? TYPE_QUAL_VOLATILE : 0)
-	  | ((mods & dw_mod_restrict) ? TYPE_QUAL_RESTRICT : 0));
+	  | ((mods & dw_mod_restrict) ? TYPE_QUAL_RESTRICT : 0)
+	  | ((mods & dw_mod_atomic) ? TYPE_QUAL_ATOMIC : 0));
 }
 
 /* Returns true if there is a qualified type with at least one
@@ -10549,6 +10552,9 @@ dw_mod_qualified_type (tree type, int mods)
   if (mods & dw_mod_restrict)
     return dw_mod_qualified_type (type, mods & ~dw_mod_restrict);
 
+  if (mods & dw_mod_atomic)
+    return dw_mod_qualified_type (type, mods & ~dw_mod_atomic);
+
   gcc_unreachable ();
 }
 
@@ -10575,6 +10581,10 @@ modified_type_die (tree type, int mods, dw_die_ref context_die)
   if (dwarf_version < 3)
     mods &= ~dw_mod_restrict;
 
+  /* Likewise for DW_TAG_atomic_type for DWARFv5.  */
+  if (dwarf_version < 5)
+    mods &= ~dw_mod_atomic;
+
   /* See if we already have the appropriately qualified variant of
      this type.  */
   qualified_type = get_qualified_type (type, dw_mods_to_quals (mods));
@@ -10618,9 +10628,11 @@ modified_type_die (tree type, int mods, dw_die_ref context_die)
       else if ((mods & dw_mod_const) < TYPE_READONLY (dtype)
 	       || (mods & dw_mod_volatile) < TYPE_VOLATILE (dtype)
 	       || (mods & dw_mod_restrict) < TYPE_RESTRICT (dtype)
+	       || (mods & dw_mod_atomic) < TYPE_ATOMIC (dtype)
 	       || ((mods & dw_mod_const) <= TYPE_READONLY (dtype)
 		   && (mods & dw_mod_volatile) <= TYPE_VOLATILE (dtype)
 		   && (mods & dw_mod_restrict) <= TYPE_RESTRICT (dtype)
+		   && (mods & dw_mod_atomic) <= TYPE_ATOMIC (dtype)
 		   && DECL_ORIGINAL_TYPE (name) != type))
 	/* cv-unqualified version of named type.  Just use the unnamed
 	   type to which it refers.  */
@@ -10649,11 +10661,19 @@ modified_type_die (tree type, int mods, dw_die_ref context_die)
       mod_type_die = new_die (DW_TAG_volatile_type, mod_scope, type);
       sub_die = modified_type_die (type, mods & ~dw_mod_volatile, context_die);
     }
-  else if (mods & dw_mod_restrict)
+  else if ((mods & dw_mod_restrict)
+	   && (((mods & ~dw_mod_restrict) == dw_mod_none)
+	       || get_qualified_type (type, dw_mods_to_quals (mods)) == NULL_TREE
+	       || dw_mod_qualified_type (type, mods & ~dw_mod_restrict)))
     {
       mod_type_die = new_die (DW_TAG_restrict_type, mod_scope, type);
       sub_die = modified_type_die (type, mods & ~dw_mod_restrict, context_die);
     }
+  else if (mods & dw_mod_atomic)
+    {
+      mod_type_die = new_die (DW_TAG_atomic_type, mod_scope, type);
+      sub_die = modified_type_die (type, mods & ~dw_mod_atomic, context_die);
+    }
   else if (code == POINTER_TYPE)
     {
       mod_type_die = new_die (DW_TAG_pointer_type, mod_scope, type);
diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h
index 7c109ea..8d5a5c9 100644
--- a/gcc/dwarf2out.h
+++ b/gcc/dwarf2out.h
@@ -52,7 +52,8 @@ enum dw_mod_flag {
   dw_mod_none = 0,
   dw_mod_restrict = 1,
   dw_mod_const = 1 << 1,
-  dw_mod_volatile = 1 << 2
+  dw_mod_volatile = 1 << 2,
+  dw_mod_atomic = 1 << 3
 };
 
 typedef union GTY(()) {
diff --git a/gcc/opts.c b/gcc/opts.c
index 324d545..719f741 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1839,7 +1839,7 @@ common_handle_option (struct gcc_options *opts,
       
       /* FALLTHRU */
     case OPT_gdwarf_:
-      if (value < 2 || value > 4)
+      if (value < 2 || value > 5)
 	error_at (loc, "dwarf version %d is not supported", value);
       else
 	opts->x_dwarf_version = value;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9c5418c..d370648 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2014-06-22  Mark Wielaard  <mjw@redhat.com>
+
+	* lib/gcc-gdb-test.exp (gdb-test): Catch '<unknown type in ' to
+	recognize older gdb versions.
+	* gcc.dg/guality/atomic.c: New test.
+
 2014-06-20  Mark Wielaard  <mjw@redhat.com>
 
 	* gcc.dg/guality/restrict.c: New test.
diff --git a/gcc/testsuite/gcc.dg/guality/atomic.c b/gcc/testsuite/gcc.dg/guality/atomic.c
new file mode 100644
index 0000000..c76cfa4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/atomic.c
@@ -0,0 +1,13 @@
+/* debuginfo tests for the _Atomic type qualifier.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -gdwarf-5" } */
+
+volatile _Atomic int * const _Atomic hwaddr = (void *) 0x1234;
+
+int
+main (int argc, char **argv)
+{
+  return hwaddr == (void *) argv[0];
+}
+
+/* { dg-final { gdb-test 10 "type:hwaddr" "volatile _Atomic int * const _Atomic" } } */
diff --git a/gcc/testsuite/lib/gcc-gdb-test.exp b/gcc/testsuite/lib/gcc-gdb-test.exp
index 0a8a6df..c729793 100644
--- a/gcc/testsuite/lib/gcc-gdb-test.exp
+++ b/gcc/testsuite/lib/gcc-gdb-test.exp
@@ -83,7 +83,7 @@ proc gdb-test { args } {
 
     remote_expect target [timeout_value] {
 	# Too old GDB
-	-re "Unhandled dwarf expression|Error in sourced command file" {
+	-re "Unhandled dwarf expression|Error in sourced command file|<unknown type in " {
 	    unsupported "$testname"
 	    remote_close target
 	    file delete $cmd_file
diff --git a/include/ChangeLog b/include/ChangeLog
index 1cda0dc..5d42014 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
+2014-06-22  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf2.def: Add DWARFv5 DW_TAG_atomic_type.
+
 2014-06-10  Thomas Schwinge  <thomas@codesourcery.com>
 
 	PR lto/61334
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 71a37b3..6941922 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -133,6 +133,8 @@ DW_TAG (DW_TAG_shared_type, 0x40)
 DW_TAG (DW_TAG_type_unit, 0x41)
 DW_TAG (DW_TAG_rvalue_reference_type, 0x42)
 DW_TAG (DW_TAG_template_alias, 0x43)
+/* DWARF 5.  */
+DW_TAG (DW_TAG_atomic_type, 0x47)
 
 DW_TAG_DUP (DW_TAG_lo_user, 0x4080)
 DW_TAG_DUP (DW_TAG_hi_user, 0xffff)
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] DWARFv5 Emit DW_TAG_atomic_type.
  2014-06-22  9:39     ` [PATCH] DWARFv5 Emit DW_TAG_atomic_type Mark Wielaard
@ 2014-06-23 16:32       ` Tom Tromey
  2014-06-23 17:12         ` Mark Wielaard
  0 siblings, 1 reply; 30+ messages in thread
From: Tom Tromey @ 2014-06-23 16:32 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: gcc-patches, Jason Merrill, Cary Coutant, jsm28

>>>>> "Mark" == Mark Wielaard <mjw@redhat.com> writes:

Mark> The following is just a prototype to try out a new qualifier type tag
Mark> proposed for DWARFv5. There is not even a draft yet of DWARFv5, so this
Mark> is just based on a proposal that might or might not be adopted and/or
Mark> changed http://dwarfstd.org/ShowIssue.php?issue=131112.1

Mark> gcc/ChangeLog

Mark> 	* dwarf2out.h (enum dw_mod_flag): Add dw_mod_atomic.
Mark> 	* dwarf2out.c (dw_mod_decl_flags): Handle TYPE_ATOMIC.
Mark> 	(dw_mod_type_flags): Likewise.
Mark> 	(dw_mods_to_quals): Likewise.
Mark> 	(dw_mod_qualified_type): Likewise.
Mark> 	(modified_type_die): Likewise.
Mark> 	opts.c (common_handle_option): Accept -gdwarf-5.

The ChangeLog should mention PR debug/60782 -- I saw you did this in the
"restrict" patch so you probably just weren't aware of this one...

Tom

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] DWARFv5 Emit DW_TAG_atomic_type.
  2014-06-23 16:32       ` Tom Tromey
@ 2014-06-23 17:12         ` Mark Wielaard
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Wielaard @ 2014-06-23 17:12 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gcc-patches, Jason Merrill, Cary Coutant, jsm28

On Mon, 2014-06-23 at 10:31 -0600, Tom Tromey wrote:
> >>>>> "Mark" == Mark Wielaard <mjw@redhat.com> writes:
> 
> Mark> The following is just a prototype to try out a new qualifier type tag
> Mark> proposed for DWARFv5. There is not even a draft yet of DWARFv5, so this
> Mark> is just based on a proposal that might or might not be adopted and/or
> Mark> changed http://dwarfstd.org/ShowIssue.php?issue=131112.1
> 
> Mark> gcc/ChangeLog
> 
> Mark> 	* dwarf2out.h (enum dw_mod_flag): Add dw_mod_atomic.
> Mark> 	* dwarf2out.c (dw_mod_decl_flags): Handle TYPE_ATOMIC.
> Mark> 	(dw_mod_type_flags): Likewise.
> Mark> 	(dw_mods_to_quals): Likewise.
> Mark> 	(dw_mod_qualified_type): Likewise.
> Mark> 	(modified_type_die): Likewise.
> Mark> 	opts.c (common_handle_option): Accept -gdwarf-5.
> 
> The ChangeLog should mention PR debug/60782 -- I saw you did this in the
> "restrict" patch so you probably just weren't aware of this one...

Thanks, I wasn't aware there was already a bug for this. I have added
myself to the CC, added a comment to the bug pointing at the prototype
patch and added the PR reference to the ChangeLog entry and commit
message.

Cheers,

Mark

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH] Add guality [p]type test.
  2014-06-20 11:51 ` Mark Wielaard
  2014-06-20 23:02   ` [PATCH] Emit DW_tag_restrict_type for restrict-qualified pointers Mark Wielaard
@ 2014-07-03  9:53   ` Mark Wielaard
  2014-07-03 10:05     ` Jakub Jelinek
  2014-07-07  9:58     ` Richard Biener
  1 sibling, 2 replies; 30+ messages in thread
From: Mark Wielaard @ 2014-07-03  9:53 UTC (permalink / raw)
  To: gcc-patches
  Cc: Jason Merrill, Cary Coutant, Alexandre Oliva, Jakub Jelinek,
	Mark Wielaard

Hi,

I pulled out the guality.exp [p]type test extension from the actual
dwarf2out.c changes (which I will repost soon with some tweaks). I think
the test extension itself is useful on its own (and will use it to
add tests for my new patches).

All new tests PASS, except when using -flto, so you'll need the
"Don't run guality.exp tests with LTO_TORTURE_OPTIONS"
if you don't want to add new FAILs. But I hope this patch can go in
even without that because I do think it is useful on its own.

Add a new type:var variant to the guality.exp testsuite to check that
gdb gets the correct type for a variable or function. To use it in a
guality test add something like:

/* { dg-final { gdb-test 50 "type:main" "int (int, char **)" } } */

Which will put a breakpoint at line 50 and check that the type of "main"
equals "int (int, char **)" according to gdb. The test harness will make
sure to squash all extra whitespace/newlines that gdb might use to make
comparisons of large structs easy.

gcc/testsuite/ChangeLog

	* lib/gcc-gdb-test.exp (gdb-test): Handle type:var for gdb ptype
	matching. Catch '<unknown type in ' to recognize older gdb versions.
	* gcc.dg/guality/const-volatile.c: New test.
---
 gcc/testsuite/ChangeLog                       |    6 ++
 gcc/testsuite/gcc.dg/guality/const-volatile.c |   83 +++++++++++++++++++++++++
 gcc/testsuite/lib/gcc-gdb-test.exp            |   47 +++++++++++++-
 3 files changed, 132 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/guality/const-volatile.c

diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 421e006..1abc700 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2014-07-03  Mark Wielaard  <mjw@redhat.com>
+
+	* lib/gcc-gdb-test.exp (gdb-test): Handle type:var for gdb ptype
+	matching. Catch '<unknown type in ' to recognize older gdb versions.
+	* gcc.dg/guality/const-volatile.c: New test.
+
 2014-07-02  Mark Wielaard  <mjw@redhat.com>
 
 	* gcc.dg/guality/guality.exp: Remove LTO_TORTURE_OPTIONS from
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..c729793 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
 
@@ -62,12 +83,13 @@ proc gdb-test { args } {
 
     remote_expect target [timeout_value] {
 	# Too old GDB
-	-re "Unhandled dwarf expression|Error in sourced command file" {
+	-re "Unhandled dwarf expression|Error in sourced command file|<unknown type in " {
 	    unsupported "$testname"
 	    remote_close target
 	    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

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Add guality [p]type test.
  2014-07-03  9:53   ` [PATCH] Add guality [p]type test Mark Wielaard
@ 2014-07-03 10:05     ` Jakub Jelinek
  2014-07-03 11:15       ` Mark Wielaard
  2014-07-07  9:58     ` Richard Biener
  1 sibling, 1 reply; 30+ messages in thread
From: Jakub Jelinek @ 2014-07-03 10:05 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: gcc-patches, Jason Merrill, Cary Coutant, Alexandre Oliva

On Thu, Jul 03, 2014 at 11:53:29AM +0200, Mark Wielaard wrote:
> I pulled out the guality.exp [p]type test extension from the actual
> dwarf2out.c changes (which I will repost soon with some tweaks). I think
> the test extension itself is useful on its own (and will use it to
> add tests for my new patches).
> 
> All new tests PASS, except when using -flto, so you'll need the
> "Don't run guality.exp tests with LTO_TORTURE_OPTIONS"
> if you don't want to add new FAILs. But I hope this patch can go in
> even without that because I do think it is useful on its own.

Is what gdb prints for ptype stable across different gdb versions (except
for whitespace that you canonicalize)?  If yes, this looks good to me.

	Jakub

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Add guality [p]type test.
  2014-07-03 10:05     ` Jakub Jelinek
@ 2014-07-03 11:15       ` Mark Wielaard
  2014-07-03 19:43         ` Tom Tromey
  0 siblings, 1 reply; 30+ messages in thread
From: Mark Wielaard @ 2014-07-03 11:15 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, Jason Merrill, Cary Coutant, Alexandre Oliva

On Thu, 2014-07-03 at 12:05 +0200, Jakub Jelinek wrote:
> On Thu, Jul 03, 2014 at 11:53:29AM +0200, Mark Wielaard wrote:
> > I pulled out the guality.exp [p]type test extension from the actual
> > dwarf2out.c changes (which I will repost soon with some tweaks). I think
> > the test extension itself is useful on its own (and will use it to
> > add tests for my new patches).
> > 
> > All new tests PASS, except when using -flto, so you'll need the
> > "Don't run guality.exp tests with LTO_TORTURE_OPTIONS"
> > if you don't want to add new FAILs. But I hope this patch can go in
> > even without that because I do think it is useful on its own.
> 
> Is what gdb prints for ptype stable across different gdb versions (except
> for whitespace that you canonicalize)?  If yes, this looks good to me.

Yes, I believe it is (I tested against gdb git master and gdb 7.6.50).
It tries to print the expression as a canonical C type, so it should be
stable. GDB itself contains similar tests, but for pregenerated .S files
or synthetic generated DWARF. This just extends it to make sure gcc and
gdb agree on the produced/consumed debuginfo.

Cheers,

Mark

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Add guality [p]type test.
  2014-07-03 11:15       ` Mark Wielaard
@ 2014-07-03 19:43         ` Tom Tromey
  0 siblings, 0 replies; 30+ messages in thread
From: Tom Tromey @ 2014-07-03 19:43 UTC (permalink / raw)
  To: Mark Wielaard
  Cc: Jakub Jelinek, gcc-patches, Jason Merrill, Cary Coutant, Alexandre Oliva

>> Is what gdb prints for ptype stable across different gdb versions (except
>> for whitespace that you canonicalize)?  If yes, this looks good to me.

Mark> Yes, I believe it is (I tested against gdb git master and gdb 7.6.50).
Mark> It tries to print the expression as a canonical C type, so it should be
Mark> stable. GDB itself contains similar tests, but for pregenerated .S files
Mark> or synthetic generated DWARF. This just extends it to make sure gcc and
Mark> gdb agree on the produced/consumed debuginfo.

I think it should be reasonably reliable.
Something like this (but for value-printing) is already done in the
libstdc++ test suite.

Tom

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Add guality [p]type test.
  2014-07-03  9:53   ` [PATCH] Add guality [p]type test Mark Wielaard
  2014-07-03 10:05     ` Jakub Jelinek
@ 2014-07-07  9:58     ` Richard Biener
  2014-08-19 11:06       ` Mark Wielaard
  1 sibling, 1 reply; 30+ messages in thread
From: Richard Biener @ 2014-07-07  9:58 UTC (permalink / raw)
  To: Mark Wielaard
  Cc: GCC Patches, Jason Merrill, Cary Coutant, Alexandre Oliva, Jakub Jelinek

On Thu, Jul 3, 2014 at 11:53 AM, Mark Wielaard <mjw@redhat.com> wrote:
> Hi,
>
> I pulled out the guality.exp [p]type test extension from the actual
> dwarf2out.c changes (which I will repost soon with some tweaks). I think
> the test extension itself is useful on its own (and will use it to
> add tests for my new patches).
>
> All new tests PASS, except when using -flto, so you'll need the
> "Don't run guality.exp tests with LTO_TORTURE_OPTIONS"
> if you don't want to add new FAILs. But I hope this patch can go in
> even without that because I do think it is useful on its own.

You could add a dg-skip-if "" { *-*-* } { "-flto" } with a comment.
Btw, why doesn't it succeed with LTO?  I suspect it's because
we drop the unused variables - try adding __attribute__((used)) to
them.  Same effect should be observable with -fwhole-program
(which doesn't use LTO).

Richard.

> Add a new type:var variant to the guality.exp testsuite to check that
> gdb gets the correct type for a variable or function. To use it in a
> guality test add something like:
>
> /* { dg-final { gdb-test 50 "type:main" "int (int, char **)" } } */
>
> Which will put a breakpoint at line 50 and check that the type of "main"
> equals "int (int, char **)" according to gdb. The test harness will make
> sure to squash all extra whitespace/newlines that gdb might use to make
> comparisons of large structs easy.
>
> gcc/testsuite/ChangeLog
>
>         * lib/gcc-gdb-test.exp (gdb-test): Handle type:var for gdb ptype
>         matching. Catch '<unknown type in ' to recognize older gdb versions.
>         * gcc.dg/guality/const-volatile.c: New test.
> ---
>  gcc/testsuite/ChangeLog                       |    6 ++
>  gcc/testsuite/gcc.dg/guality/const-volatile.c |   83 +++++++++++++++++++++++++
>  gcc/testsuite/lib/gcc-gdb-test.exp            |   47 +++++++++++++-
>  3 files changed, 132 insertions(+), 4 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/guality/const-volatile.c
>
> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
> index 421e006..1abc700 100644
> --- a/gcc/testsuite/ChangeLog
> +++ b/gcc/testsuite/ChangeLog
> @@ -1,3 +1,9 @@
> +2014-07-03  Mark Wielaard  <mjw@redhat.com>
> +
> +       * lib/gcc-gdb-test.exp (gdb-test): Handle type:var for gdb ptype
> +       matching. Catch '<unknown type in ' to recognize older gdb versions.
> +       * gcc.dg/guality/const-volatile.c: New test.
> +
>  2014-07-02  Mark Wielaard  <mjw@redhat.com>
>
>         * gcc.dg/guality/guality.exp: Remove LTO_TORTURE_OPTIONS from
> 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..c729793 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
>
> @@ -62,12 +83,13 @@ proc gdb-test { args } {
>
>      remote_expect target [timeout_value] {
>         # Too old GDB
> -       -re "Unhandled dwarf expression|Error in sourced command file" {
> +       -re "Unhandled dwarf expression|Error in sourced command file|<unknown type in " {
>             unsupported "$testname"
>             remote_close target
>             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
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/2] dwarf2out.c: Pass one cv_quals argument instead of two for const and volatile.
  2014-06-20 23:02   ` [PATCH] Emit DW_tag_restrict_type for restrict-qualified pointers Mark Wielaard
  2014-06-22  9:39     ` [PATCH] DWARFv5 Emit DW_TAG_atomic_type Mark Wielaard
@ 2014-07-08 16:39     ` Mark Wielaard
  2014-07-09 21:36       ` [PATCH 1/2] DWARFv5 Emit DW_TAG_atomic_type Mark Wielaard
                         ` (2 more replies)
  2014-07-08 16:39     ` [PATCH 2/2] Emit DW_tag_restrict_type for restrict-qualified pointers Mark Wielaard
  2 siblings, 3 replies; 30+ messages in thread
From: Mark Wielaard @ 2014-07-08 16:39 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill, Cary Coutant, Joseph S. Myers, Mark Wielaard

Hi,

In my original patch I introduced a new enum to keep track of the qualifiers
that we might want to output. But that seems silly in retrospect. We already
have the tree cv_qualifier enum to encode all possible cv-qualifier
combinations, so this variant of the patch just reuses those and uses
TYPE_QUALS_NO_ADDR_SPACE to extract the qualifiers from the tree types.

I kept this patch separate from the actual patch that introduces the
DW_TAG_restrict_type because I thought that would be easier to review.
But I can merge the two patches together if people feel that is more
appropriate.

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 cv_quals argument
to these functions. And introduce helper function decl_quals to extract
additional cv_quals from declaration trees.

DWARFv3 added restrict_type [PR debug/59051] and DWARFv5 has proposals
for atomic_type and aligned_type. Which will be easier to implement based
on this change.

gcc/ChangeLog

	* dwarf2out.c (decl_quals): New function.
	(modified_type_die): Take one cv_quals argument instead of two,
	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/ChangeLog   |   28 ++++++++++
 gcc/dwarf2out.c |  154 +++++++++++++++++++++++++++++++------------------------
 2 files changed, 115 insertions(+), 67 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cf55712..3f63f1b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,31 @@
+2014-07-07  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf2out.c (decl_quals): New function.
+	(modified_type_die): Take one cv_quals argument instead of two,
+	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-07-01  Jan Hubicka   <hubicka@ucw.cz>
 
 	* ipa-utils.h (method_class_type, vtable_pointer_value_to_binfo,
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index b65b37e..068bbc3 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3140,7 +3140,8 @@ 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 decl_quals (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 +3199,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);
@@ -10490,12 +10491,24 @@ subrange_type_die (tree type, tree low, tree high, dw_die_ref context_die)
   return subrange_die;
 }
 
+/* Returns the (const and/or volatile) cv_qualifiers associated with
+   the decl node.  This will normally be augmented with the
+   cv_qualifiers of the underlying type in add_type_attribute.  */
+
+static int
+decl_quals (const_tree decl)
+{
+  return ((TREE_READONLY (decl)
+	   ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED)
+	  | (TREE_THIS_VOLATILE (decl)
+	     ? TYPE_QUAL_VOLATILE : TYPE_UNQUALIFIED));
+}
+
 /* 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 cv_quals, dw_die_ref context_die)
 {
   enum tree_code code = TREE_CODE (type);
   dw_die_ref mod_type_die;
@@ -10508,12 +10521,12 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
   if (code == ERROR_MARK)
     return NULL;
 
+  /* Only these cv-qualifiers are currently handled.  */
+  cv_quals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+
   /* 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)));
+  qualified_type = get_qualified_type (type, cv_quals);
 
   if (qualified_type == sizetype
       && TYPE_NAME (qualified_type)
@@ -10551,35 +10564,38 @@ 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)
-		   && 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,
-				  context_die);
-      /* Else cv-qualified version of named type; fall through.  */
+      else
+	{
+	  int dquals = TYPE_QUALS_NO_ADDR_SPACE (dtype);
+	  dquals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+	  if ((dquals & ~cv_quals) != TYPE_UNQUALIFIED
+	      || (cv_quals == dquals && 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),
+				      cv_quals, 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 ((cv_quals & TYPE_QUAL_CONST)
+      /* If both const_type and volatile_type, prefer the path
 	 which leads to a qualified type.  */
-      && (!is_volatile_type
+      && (!(cv_quals & TYPE_QUAL_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, cv_quals & ~TYPE_QUAL_CONST,
+				   context_die);
     }
-  else if (is_volatile_type)
+  else if (cv_quals & TYPE_QUAL_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, cv_quals & ~TYPE_QUAL_VOLATILE,
+				   context_die);
     }
   else if (code == POINTER_TYPE)
     {
@@ -10640,7 +10656,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)))
+	       || (cv_quals == TYPE_UNQUALIFIED)))
 	  || (TREE_CODE (name) == TYPE_DECL
 	      && TREE_TYPE (name) == qualified_type
 	      && DECL_NAME (name))))
@@ -10669,8 +10685,7 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
        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),
+				 TYPE_QUALS_NO_ADDR_SPACE (item_type),
 				 context_die);
 
   if (sub_die != NULL)
@@ -10812,8 +10827,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)
+			       ? TYPE_QUAL_VOLATILE : TYPE_UNQUALIFIED),
 			      parent_die);
 	}
       else
@@ -11555,7 +11571,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, TYPE_UNQUALIFIED, comp_unit_die ());
   if (type_die == NULL || type_die->die_tag != DW_TAG_base_type)
     return NULL;
   return type_die;
@@ -16472,7 +16488,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), TYPE_QUAL_CONST, ctx);
 	add_AT_location_description (decl_die, DW_AT_location, list);
 	add_AT_die_ref (subrange_die, bound_attr, decl_die);
 	break;
@@ -16523,8 +16539,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),
+				    TYPE_UNQUALIFIED, type_die);
 	    }
 
 	  /* ??? If upper is NULL, the array has unspecified length,
@@ -17015,11 +17031,12 @@ class_or_namespace_scope_p (dw_die_ref context_die)
 
 /* Many forms of DIEs require a "type description" attribute.  This
    routine locates the proper "type descriptor" die for the type given
-   by 'type', and adds a DW_AT_type attribute below the given die.  */
+   by 'type' plus any additional qualifiers given by 'cv_quals', 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 cv_quals,
+		    dw_die_ref context_die)
 {
   enum tree_code code  = TREE_CODE (type);
   dw_die_ref type_die  = NULL;
@@ -17040,8 +17057,7 @@ add_type_attribute (dw_die_ref object_die, tree type, int decl_const,
     return;
 
   type_die = modified_type_die (type,
-				decl_const || TYPE_READONLY (type),
-				decl_volatile || TYPE_VOLATILE (type),
+				cv_quals | TYPE_QUALS_NO_ADDR_SPACE (type),
 				context_die);
 
   if (type_die != NULL)
@@ -17255,7 +17271,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, TYPE_UNQUALIFIED, context_die);
 
   add_gnat_descriptive_type_attribute (array_die, type, context_die);
   if (TYPE_ARTIFICIAL (type))
@@ -17418,7 +17434,8 @@ 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, TYPE_UNQUALIFIED,
+		      context_die);
 
   if (get_AT (array_die, DW_AT_name))
     add_pubtype (type, array_die);
@@ -17437,7 +17454,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);
+			  TYPE_UNQUALIFIED, context_die);
     }
 
   if (DECL_ABSTRACT (decl))
@@ -17527,7 +17544,8 @@ 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, TYPE_UNQUALIFIED,
+			      context_die);
 	}
       if (TYPE_STUB_DECL (type) != NULL_TREE)
 	{
@@ -17628,12 +17646,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,
-				context_die);
+	    add_type_attribute (parm_die, TREE_TYPE (type),
+				TYPE_UNQUALIFIED, context_die);
 	  else
 	    add_type_attribute (parm_die, type,
-				TREE_READONLY (node_or_origin),
-				TREE_THIS_VOLATILE (node_or_origin),
+				decl_quals (node_or_origin),
 				context_die);
 	}
       if (origin == NULL && DECL_ARTIFICIAL (node))
@@ -17649,7 +17666,8 @@ 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, TYPE_UNQUALIFIED,
+			  context_die);
       break;
 
     default:
@@ -18231,7 +18249,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);
+				    TYPE_UNQUALIFIED, context_die);
 	    }
 	}
     }
@@ -18248,7 +18266,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);
+			      TYPE_UNQUALIFIED, context_die);
 	}
 
       add_pure_or_virtual_attribute (subr_die, decl);
@@ -18863,8 +18881,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), decl_quals (decl),
+			  context_die);
       add_AT_flag (var_die, DW_AT_external, 1);
       if (loc)
 	{
@@ -18957,10 +18975,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), TYPE_UNQUALIFIED,
+			    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, decl_quals (decl_or_origin),
+			    context_die);
     }
 
   if (origin == NULL && !specialization_p)
@@ -19014,7 +19033,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, TYPE_QUAL_CONST, context_die);
   if (TREE_PUBLIC (decl))
     add_AT_flag (const_die, DW_AT_external, 1);
   if (DECL_ARTIFICIAL (decl))
@@ -19257,8 +19276,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);
+		      decl_quals (decl), context_die);
 
   if (DECL_BIT_FIELD_TYPE (decl))
     {
@@ -19292,7 +19310,8 @@ 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), TYPE_UNQUALIFIED,
+		      context_die);
   add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE);
 }
 
@@ -19312,7 +19331,8 @@ 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), TYPE_UNQUALIFIED,
+		      context_die);
   add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE);
 }
 #endif
@@ -19329,7 +19349,8 @@ 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), TYPE_UNQUALIFIED,
+		      context_die);
 }
 
 typedef const char *dchar_p; /* For DEF_VEC_P.  */
@@ -19534,7 +19555,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), TYPE_UNQUALIFIED, context_die);
   add_data_member_location_attribute (die, binfo);
 
   if (BINFO_VIRTUAL_P (binfo))
@@ -19731,7 +19752,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, TYPE_UNQUALIFIED, context_die);
   gen_formal_types_die (type, subr_die);
 
   if (get_AT (subr_die, DW_AT_name))
@@ -19799,8 +19820,7 @@ 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, decl_quals (decl), context_die);
 
       if (is_naming_typedef_decl (decl))
 	/* We want that all subsequent calls to lookup_type_die with
@@ -20375,8 +20395,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, TYPE_QUALS_NO_ADDR_SPACE (type),
+				    context_die);
       gcc_assert (type_die);
     }
   return type_die;
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 2/2] Emit DW_tag_restrict_type for restrict-qualified pointers.
  2014-06-20 23:02   ` [PATCH] Emit DW_tag_restrict_type for restrict-qualified pointers Mark Wielaard
  2014-06-22  9:39     ` [PATCH] DWARFv5 Emit DW_TAG_atomic_type Mark Wielaard
  2014-07-08 16:39     ` [PATCH 1/2] dwarf2out.c: Pass one cv_quals argument instead of two for const and volatile Mark Wielaard
@ 2014-07-08 16:39     ` Mark Wielaard
  2014-07-08 18:12       ` Mark Wielaard
  2 siblings, 1 reply; 30+ messages in thread
From: Mark Wielaard @ 2014-07-08 16:39 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill, Cary Coutant, Joseph S. Myers, Mark Wielaard

gcc/ChangeLog

	PR debug/59051
	* dwarf2out.h (enum dw_mod_flag): Add dw_mod_restrict.
	* dwarf2out.c (dw_mod_decl_flags): Handle TYPE_RESTRICT.
	(dw_mod_type_flags): Likewise.
	(dw_mods_to_quals): New function.
	(dw_mod_qualified_type): Likewise.
	(modified_type_die): Handle dw_mod_restrict.

gcc/testsuite/ChangeLog

	PR debug/59051
	* gcc.dg/guality/restrict.c: New test.
---
 gcc/ChangeLog                           |   10 ++++++
 gcc/dwarf2out.c                         |   33 ++++++++++++++++-----
 gcc/testsuite/ChangeLog                 |    4 ++
 gcc/testsuite/gcc.dg/guality/restrict.c |   48 +++++++++++++++++++++++++++++++
 4 files changed, 87 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/guality/restrict.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3f63f1b..cc68a80 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2014-07-08  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/59051
+	* dwarf2out.h (enum dw_mod_flag): Add dw_mod_restrict.
+	* dwarf2out.c (dw_mod_decl_flags): Handle TYPE_RESTRICT.
+	(dw_mod_type_flags): Likewise.
+	(dw_mods_to_quals): New function.
+	(dw_mod_qualified_type): Likewise.
+	(modified_type_die): Handle dw_mod_restrict.
+
 2014-07-07  Mark Wielaard  <mjw@redhat.com>
 
 	* dwarf2out.c (decl_quals): New function.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 068bbc3..be17cad 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -10522,7 +10522,13 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
     return NULL;
 
   /* Only these cv-qualifiers are currently handled.  */
-  cv_quals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+  cv_quals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT);
+
+  /* Don't emit DW_TAG_restrict_type for DWARFv2, since it is a type
+     tag modifier (and not an attribute) old consumers won't be able
+     to handle it.  */
+  if (dwarf_version < 3)
+    cv_quals &= ~TYPE_QUAL_RESTRICT;
 
   /* See if we already have the appropriately qualified variant of
      this type.  */
@@ -10567,7 +10573,7 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
       else
 	{
 	  int dquals = TYPE_QUALS_NO_ADDR_SPACE (dtype);
-	  dquals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+	  dquals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT);
 	  if ((dquals & ~cv_quals) != TYPE_UNQUALIFIED
 	      || (cv_quals == dquals && DECL_ORIGINAL_TYPE (name) != type))
 	    /* cv-unqualified version of named type.  Just use
@@ -10581,22 +10587,33 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
   mod_scope = scope_die_for (type, context_die);
 
   if ((cv_quals & TYPE_QUAL_CONST)
-      /* If both const_type and volatile_type, prefer the path
-	 which leads to a qualified type.  */
-      && (!(cv_quals & TYPE_QUAL_VOLATILE)
-	  || get_qualified_type (type, TYPE_QUAL_CONST) == NULL_TREE
-	  || get_qualified_type (type, TYPE_QUAL_VOLATILE) != NULL_TREE))
+      /* If there are multiple type modifiers, prefer a path which
+	 leads to a qualified type.  */
+      && (((cv_quals & ~TYPE_QUAL_CONST) == TYPE_UNQUALIFIED)
+	  || get_qualified_type (type, cv_quals) == NULL_TREE
+	  || (get_qualified_type (type, cv_quals & ~TYPE_QUAL_CONST)
+	      != NULL_TREE)))
     {
       mod_type_die = new_die (DW_TAG_const_type, mod_scope, type);
       sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_CONST,
 				   context_die);
     }
-  else if (cv_quals & TYPE_QUAL_VOLATILE)
+  else if ((cv_quals & TYPE_QUAL_VOLATILE)
+	   && (((cv_quals & ~TYPE_QUAL_VOLATILE) == TYPE_UNQUALIFIED)
+	       || get_qualified_type (type, cv_quals) == NULL_TREE
+	       || (get_qualified_type (type, cv_quals & ~TYPE_QUAL_VOLATILE)
+		   != NULL_TREE)))
     {
       mod_type_die = new_die (DW_TAG_volatile_type, mod_scope, type);
       sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_VOLATILE,
 				   context_die);
     }
+  else if (cv_quals & TYPE_QUAL_RESTRICT)
+    {
+      mod_type_die = new_die (DW_TAG_restrict_type, mod_scope, type);
+      sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_RESTRICT,
+				   context_die);
+    }
   else if (code == POINTER_TYPE)
     {
       mod_type_die = new_die (DW_TAG_pointer_type, mod_scope, type);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1abc700..e82c07c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2014-06-20  Mark Wielaard  <mjw@redhat.com>
+
+	* gcc.dg/guality/restrict.c: New test.
+
 2014-07-03  Mark Wielaard  <mjw@redhat.com>
 
 	* lib/gcc-gdb-test.exp (gdb-test): Handle type:var for gdb ptype
diff --git a/gcc/testsuite/gcc.dg/guality/restrict.c b/gcc/testsuite/gcc.dg/guality/restrict.c
new file mode 100644
index 0000000..aba30b1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/restrict.c
@@ -0,0 +1,48 @@
+/* debuginfo tests for combinations of const, volatile, restrict pointers. */
+/* { dg-do run } */
+/* { dg-options "-std=c99 -g" } */
+
+int *ip;
+const int *cip;
+int * restrict irp;
+int * const icp;
+const int * restrict cirp;
+int * const restrict icrp;
+const int * const restrict cicrp;
+
+int * const volatile restrict cvirp;
+const volatile int * restrict pcvir;
+
+static __attribute__((noclone, noinline)) void *
+cpy (void * restrict s1, const void * restrict s2, unsigned int n)
+{
+  char *t1 = s1;
+  const char *t2 = s2;
+  while(n-- > 0)
+    *t1++ = *t2++;
+  return s1;
+}
+
+int
+main (int argc, char **argv)
+{
+  void *foo = 0;
+  if (argc > 16)
+    foo = cpy (argv[0], argv[1], argc);
+
+  return foo != 0;
+}
+
+/* { dg-final { gdb-test 30 "type:ip" "int *" } } */
+/* { dg-final { gdb-test 30 "type:cip" "const int *" } } */
+/* { dg-final { gdb-test 30 "type:irp" "int * restrict" } } */
+/* { dg-final { gdb-test 30 "type:icp" "int * const" } } */
+/* { dg-final { gdb-test 30 "type:cirp" "const int * restrict" } } */
+/* { dg-final { gdb-test 30 "type:icrp" "int * const restrict" } } */
+/* { dg-final { gdb-test 30 "type:cicrp" "const int * const restrict" } } */
+
+/* { dg-final { gdb-test 30 "type:cvirp" "int * const volatile restrict" } } */
+/* { dg-final { gdb-test 30 "type:pcvir" "const volatile int * restrict" } } */
+
+/* { dg-final { gdb-test 30 "type:main" "int (int, char **)" } } */
+/* { dg-final { gdb-test 30 "type:cpy" "void *(void * restrict, const void * restrict, unsigned int)" } } */
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 2/2] Emit DW_tag_restrict_type for restrict-qualified pointers.
  2014-07-08 16:39     ` [PATCH 2/2] Emit DW_tag_restrict_type for restrict-qualified pointers Mark Wielaard
@ 2014-07-08 18:12       ` Mark Wielaard
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Wielaard @ 2014-07-08 18:12 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill, Cary Coutant, Joseph S. Myers

Forgot to rebase my ChangeLog, sorry.
Here is the version with the correct one:

gcc/ChangeLog

	PR debug/59051
	* dwarf2out.h (modified_type_die): Handle TYPE_QUAL_RESTRICT.

gcc/testsuite/ChangeLog

	PR debug/59051
	* gcc.dg/guality/restrict.c: New test.
---
 gcc/ChangeLog                           |    5 +++
 gcc/dwarf2out.c                         |   33 ++++++++++++++++-----
 gcc/testsuite/ChangeLog                 |    5 +++
 gcc/testsuite/gcc.dg/guality/restrict.c |   48 +++++++++++++++++++++++++++++++
 4 files changed, 83 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/guality/restrict.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3f63f1b..339f368 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2014-07-08  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/59051
+	* dwarf2out.c (modified_type_die): Handle TYPE_QUAL_RESTRICT.
+
 2014-07-07  Mark Wielaard  <mjw@redhat.com>
 
 	* dwarf2out.c (decl_quals): New function.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 068bbc3..be17cad 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -10522,7 +10522,13 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
     return NULL;
 
   /* Only these cv-qualifiers are currently handled.  */
-  cv_quals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+  cv_quals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT);
+
+  /* Don't emit DW_TAG_restrict_type for DWARFv2, since it is a type
+     tag modifier (and not an attribute) old consumers won't be able
+     to handle it.  */
+  if (dwarf_version < 3)
+    cv_quals &= ~TYPE_QUAL_RESTRICT;
 
   /* See if we already have the appropriately qualified variant of
      this type.  */
@@ -10567,7 +10573,7 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
       else
 	{
 	  int dquals = TYPE_QUALS_NO_ADDR_SPACE (dtype);
-	  dquals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+	  dquals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT);
 	  if ((dquals & ~cv_quals) != TYPE_UNQUALIFIED
 	      || (cv_quals == dquals && DECL_ORIGINAL_TYPE (name) != type))
 	    /* cv-unqualified version of named type.  Just use
@@ -10581,22 +10587,33 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
   mod_scope = scope_die_for (type, context_die);
 
   if ((cv_quals & TYPE_QUAL_CONST)
-      /* If both const_type and volatile_type, prefer the path
-	 which leads to a qualified type.  */
-      && (!(cv_quals & TYPE_QUAL_VOLATILE)
-	  || get_qualified_type (type, TYPE_QUAL_CONST) == NULL_TREE
-	  || get_qualified_type (type, TYPE_QUAL_VOLATILE) != NULL_TREE))
+      /* If there are multiple type modifiers, prefer a path which
+	 leads to a qualified type.  */
+      && (((cv_quals & ~TYPE_QUAL_CONST) == TYPE_UNQUALIFIED)
+	  || get_qualified_type (type, cv_quals) == NULL_TREE
+	  || (get_qualified_type (type, cv_quals & ~TYPE_QUAL_CONST)
+	      != NULL_TREE)))
     {
       mod_type_die = new_die (DW_TAG_const_type, mod_scope, type);
       sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_CONST,
 				   context_die);
     }
-  else if (cv_quals & TYPE_QUAL_VOLATILE)
+  else if ((cv_quals & TYPE_QUAL_VOLATILE)
+	   && (((cv_quals & ~TYPE_QUAL_VOLATILE) == TYPE_UNQUALIFIED)
+	       || get_qualified_type (type, cv_quals) == NULL_TREE
+	       || (get_qualified_type (type, cv_quals & ~TYPE_QUAL_VOLATILE)
+		   != NULL_TREE)))
     {
       mod_type_die = new_die (DW_TAG_volatile_type, mod_scope, type);
       sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_VOLATILE,
 				   context_die);
     }
+  else if (cv_quals & TYPE_QUAL_RESTRICT)
+    {
+      mod_type_die = new_die (DW_TAG_restrict_type, mod_scope, type);
+      sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_RESTRICT,
+				   context_die);
+    }
   else if (code == POINTER_TYPE)
     {
       mod_type_die = new_die (DW_TAG_pointer_type, mod_scope, type);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1abc700..184ca67 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-07-08  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/59051
+	* gcc.dg/guality/restrict.c: New test.
+
 2014-07-03  Mark Wielaard  <mjw@redhat.com>
 
 	* lib/gcc-gdb-test.exp (gdb-test): Handle type:var for gdb ptype
diff --git a/gcc/testsuite/gcc.dg/guality/restrict.c b/gcc/testsuite/gcc.dg/guality/restrict.c
new file mode 100644
index 0000000..e31224b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/restrict.c
@@ -0,0 +1,48 @@
+/* debuginfo tests for combinations of const, volatile, restrict pointers. */
+/* { dg-do run } */
+/* { dg-options "-std=c99 -gdwarf-3" } */
+
+int *ip;
+const int *cip;
+int * restrict irp;
+int * const icp;
+const int * restrict cirp;
+int * const restrict icrp;
+const int * const restrict cicrp;
+
+int * const volatile restrict cvirp;
+const volatile int * restrict pcvir;
+
+static __attribute__((noclone, noinline)) void *
+cpy (void * restrict s1, const void * restrict s2, unsigned int n)
+{
+  char *t1 = s1;
+  const char *t2 = s2;
+  while(n-- > 0)
+    *t1++ = *t2++;
+  return s1;
+}
+
+int
+main (int argc, char **argv)
+{
+  void *foo = 0;
+  if (argc > 16)
+    foo = cpy (argv[0], argv[1], argc);
+
+  return foo != 0;
+}
+
+/* { dg-final { gdb-test 30 "type:ip" "int *" } } */
+/* { dg-final { gdb-test 30 "type:cip" "const int *" } } */
+/* { dg-final { gdb-test 30 "type:irp" "int * restrict" } } */
+/* { dg-final { gdb-test 30 "type:icp" "int * const" } } */
+/* { dg-final { gdb-test 30 "type:cirp" "const int * restrict" } } */
+/* { dg-final { gdb-test 30 "type:icrp" "int * const restrict" } } */
+/* { dg-final { gdb-test 30 "type:cicrp" "const int * const restrict" } } */
+
+/* { dg-final { gdb-test 30 "type:cvirp" "int * const volatile restrict" } } */
+/* { dg-final { gdb-test 30 "type:pcvir" "const volatile int * restrict" } } */
+
+/* { dg-final { gdb-test 30 "type:main" "int (int, char **)" } } */
+/* { dg-final { gdb-test 30 "type:cpy" "void *(void * restrict, const void * restrict, unsigned int)" } } */




^ permalink raw reply	[flat|nested] 30+ messages in thread

* Some DWARFv5 proposal prototypes (atomic_type, aligned_type)
  2014-07-08 16:39     ` [PATCH 1/2] dwarf2out.c: Pass one cv_quals argument instead of two for const and volatile Mark Wielaard
  2014-07-09 21:36       ` [PATCH 1/2] DWARFv5 Emit DW_TAG_atomic_type Mark Wielaard
@ 2014-07-09 21:36       ` Mark Wielaard
  2014-07-14 20:03         ` Tom Tromey
  2014-07-09 21:37       ` [PATCH 2/2] DWARF5: Add DW_TAG_aligned_type support Mark Wielaard
  2 siblings, 1 reply; 30+ messages in thread
From: Mark Wielaard @ 2014-07-09 21:36 UTC (permalink / raw)
  To: gcc-patches
  Cc: Jason Merrill, Cary Coutant, Joseph S. Myers, Tom Tromey, Joel Brobecker

Hi,

The following two patches are based on the earlier "dwarf2out.c: Pass
one cv_quals argument" and "Emit DW_tag_restrict_type" patches I posted
earlier. Since there currently is not even an early draft yet for DWARFv5,
just a collection of proposals that might or might not be adopted these
patches are not meant to be integrated just yet. But I would like to get
feedback on the code and whether the new debug information is useful.

I have corresponding patches for gdb so that the new guality.exp tests
PASS (without those they will report UNSUPPORTED). The tests only deal
with C code. It would be interesting if people could provide corresponding
tests for other languages that have atomics and/or user aligned types to
see if it works generically or needs some extra language support.

We could try to make them into GNU extensions if people find them useful,
but because they are type qualifier tags, not simple attributes, it would
need some extra coordination with other DWARF consumers to make sure they
are recognized.

Thanks,

Mark

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/2] DWARFv5 Emit DW_TAG_atomic_type.
  2014-07-08 16:39     ` [PATCH 1/2] dwarf2out.c: Pass one cv_quals argument instead of two for const and volatile Mark Wielaard
@ 2014-07-09 21:36       ` Mark Wielaard
  2014-07-09 21:36       ` Some DWARFv5 proposal prototypes (atomic_type, aligned_type) Mark Wielaard
  2014-07-09 21:37       ` [PATCH 2/2] DWARF5: Add DW_TAG_aligned_type support Mark Wielaard
  2 siblings, 0 replies; 30+ messages in thread
From: Mark Wielaard @ 2014-07-09 21:36 UTC (permalink / raw)
  To: gcc-patches
  Cc: Jason Merrill, Cary Coutant, Joseph S. Myers, Tom Tromey,
	Joel Brobecker, Mark Wielaard

gcc/ChangeLog

	PR debug/60782
	* dwarf2out.c (modified_type_die): Handle TYPE_QUAL_ATOMIC.
	* opts.c (common_handle_option): Accept -gdwarf-5.

gcc/testsuite/ChangeLog

	PR debug/60782
	* gcc.dg/guality/atomic.c: New test.

include/ChangeLog

	PR debug/60782
	* dwarf2.def: Add DWARFv5 DW_TAG_atomic_type.
---
 gcc/ChangeLog                         |    6 ++++++
 gcc/dwarf2out.c                       |   22 +++++++++++++++++++---
 gcc/opts.c                            |    2 +-
 gcc/testsuite/ChangeLog               |    5 +++++
 gcc/testsuite/gcc.dg/guality/atomic.c |   13 +++++++++++++
 include/ChangeLog                     |    5 +++++
 include/dwarf2.def                    |    2 ++
 7 files changed, 51 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/guality/atomic.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cb39d7f..7550064 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2014-07-09  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/60782
+	* dwarf2out.c (modified_type_die): Handle TYPE_QUAL_ATOMIC.
+	* opts.c (common_handle_option): Accept -gdwarf-5.
+
 2014-07-08  Mark Wielaard  <mjw@redhat.com>
 
 	PR debug/59051
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index be17cad..c4649c3 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -10522,7 +10522,8 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
     return NULL;
 
   /* Only these cv-qualifiers are currently handled.  */
-  cv_quals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT);
+  cv_quals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT
+	       | TYPE_QUAL_ATOMIC);
 
   /* Don't emit DW_TAG_restrict_type for DWARFv2, since it is a type
      tag modifier (and not an attribute) old consumers won't be able
@@ -10530,6 +10531,10 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
   if (dwarf_version < 3)
     cv_quals &= ~TYPE_QUAL_RESTRICT;
 
+  /* Likewise for DW_TAG_atomic_type for DWARFv5.  */
+  if (dwarf_version < 5)
+    cv_quals &= ~TYPE_QUAL_ATOMIC;
+
   /* See if we already have the appropriately qualified variant of
      this type.  */
   qualified_type = get_qualified_type (type, cv_quals);
@@ -10573,7 +10578,8 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
       else
 	{
 	  int dquals = TYPE_QUALS_NO_ADDR_SPACE (dtype);
-	  dquals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT);
+	  dquals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT
+		     | TYPE_QUAL_ATOMIC);
 	  if ((dquals & ~cv_quals) != TYPE_UNQUALIFIED
 	      || (cv_quals == dquals && DECL_ORIGINAL_TYPE (name) != type))
 	    /* cv-unqualified version of named type.  Just use
@@ -10608,12 +10614,22 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
       sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_VOLATILE,
 				   context_die);
     }
-  else if (cv_quals & TYPE_QUAL_RESTRICT)
+  else if ((cv_quals & TYPE_QUAL_RESTRICT)
+	   && (((cv_quals & ~TYPE_QUAL_RESTRICT) == TYPE_UNQUALIFIED)
+	       || get_qualified_type (type, cv_quals) == NULL_TREE
+	       || (get_qualified_type (type, cv_quals & ~TYPE_QUAL_RESTRICT)
+		   != NULL_TREE)))
     {
       mod_type_die = new_die (DW_TAG_restrict_type, mod_scope, type);
       sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_RESTRICT,
 				   context_die);
     }
+  else if (cv_quals & TYPE_QUAL_ATOMIC)
+    {
+      mod_type_die = new_die (DW_TAG_atomic_type, mod_scope, type);
+      sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_ATOMIC,
+				   context_die);
+    }
   else if (code == POINTER_TYPE)
     {
       mod_type_die = new_die (DW_TAG_pointer_type, mod_scope, type);
diff --git a/gcc/opts.c b/gcc/opts.c
index 419a074..6b9826d 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1847,7 +1847,7 @@ common_handle_option (struct gcc_options *opts,
       
       /* FALLTHRU */
     case OPT_gdwarf_:
-      if (value < 2 || value > 4)
+      if (value < 2 || value > 5)
 	error_at (loc, "dwarf version %d is not supported", value);
       else
 	opts->x_dwarf_version = value;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 17a5774..6ff6a1e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-07-09  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/60782
+	* gcc.dg/guality/atomic.c: New test.
+
 2014-07-08  Mark Wielaard  <mjw@redhat.com>
 
 	PR debug/59051
diff --git a/gcc/testsuite/gcc.dg/guality/atomic.c b/gcc/testsuite/gcc.dg/guality/atomic.c
new file mode 100644
index 0000000..c76cfa4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/atomic.c
@@ -0,0 +1,13 @@
+/* debuginfo tests for the _Atomic type qualifier.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -gdwarf-5" } */
+
+volatile _Atomic int * const _Atomic hwaddr = (void *) 0x1234;
+
+int
+main (int argc, char **argv)
+{
+  return hwaddr == (void *) argv[0];
+}
+
+/* { dg-final { gdb-test 10 "type:hwaddr" "volatile _Atomic int * const _Atomic" } } */
diff --git a/include/ChangeLog b/include/ChangeLog
index 1cda0dc..2609e70 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2014-07-09  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/60782
+	* dwarf2.def: Add DWARFv5 DW_TAG_atomic_type.
+
 2014-06-10  Thomas Schwinge  <thomas@codesourcery.com>
 
 	PR lto/61334
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 71a37b3..6490391 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -133,6 +133,8 @@ DW_TAG (DW_TAG_shared_type, 0x40)
 DW_TAG (DW_TAG_type_unit, 0x41)
 DW_TAG (DW_TAG_rvalue_reference_type, 0x42)
 DW_TAG (DW_TAG_template_alias, 0x43)
+/* DWARF 5.  */
+DW_TAG (DW_TAG_atomic_type, 0x47) /* NOT AN OFFICIAL NUMBER. DWARF5 131112.1 */
 
 DW_TAG_DUP (DW_TAG_lo_user, 0x4080)
 DW_TAG_DUP (DW_TAG_hi_user, 0xffff)
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 2/2] DWARF5: Add DW_TAG_aligned_type support.
  2014-07-08 16:39     ` [PATCH 1/2] dwarf2out.c: Pass one cv_quals argument instead of two for const and volatile Mark Wielaard
  2014-07-09 21:36       ` [PATCH 1/2] DWARFv5 Emit DW_TAG_atomic_type Mark Wielaard
  2014-07-09 21:36       ` Some DWARFv5 proposal prototypes (atomic_type, aligned_type) Mark Wielaard
@ 2014-07-09 21:37       ` Mark Wielaard
  2 siblings, 0 replies; 30+ messages in thread
From: Mark Wielaard @ 2014-07-09 21:37 UTC (permalink / raw)
  To: gcc-patches
  Cc: Jason Merrill, Cary Coutant, Joseph S. Myers, Tom Tromey,
	Joel Brobecker, Mark Wielaard

gcc/ChangeLog

	* dwarf2out.c (decl_user_align): New function.
	(type_user_align): Likewise.
	(modified_type_die): Add and handle align argument.
	(add_bound_info): Likewise.
	(base_type_for_mode): Call modified_type_die with zero user align.
	(add_subscript_info): Call add_type_attribute with zero user align.
	(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

	* gcc.dg/guality/alignas.c: New test.
---
 gcc/ChangeLog                          |   25 +++++++
 gcc/dwarf2out.c                        |  116 ++++++++++++++++++++++----------
 gcc/testsuite/ChangeLog                |    4 +
 gcc/testsuite/gcc.dg/guality/alignas.c |   57 ++++++++++++++++
 include/dwarf2.def                     |    3 +
 5 files changed, 168 insertions(+), 37 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/guality/alignas.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7550064..186fba5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,30 @@
 2014-07-09  Mark Wielaard  <mjw@redhat.com>
 
+	* dwarf2out.c (decl_user_align): New function.
+	(type_user_align): Likewise.
+	(modified_type_die): Add and handle align argument.
+	(add_bound_info): Likewise.
+	(base_type_for_mode): Call modified_type_die with zero user align.
+	(add_subscript_info): Call add_type_attribute with zero user align.
+	(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-07-09  Mark Wielaard  <mjw@redhat.com>
+
 	PR debug/60782
 	* dwarf2out.c (modified_type_die): Handle TYPE_QUAL_ATOMIC.
 	* opts.c (common_handle_option): Accept -gdwarf-5.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index c4649c3..cd7d782 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3141,7 +3141,7 @@ 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 int decl_quals (const_tree);
-static dw_die_ref modified_type_die (tree, int, dw_die_ref);
+static dw_die_ref modified_type_die (tree, int, unsigned 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);
@@ -3199,7 +3199,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, dw_die_ref);
+static void add_type_attribute (dw_die_ref, tree, int, unsigned 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);
@@ -10504,11 +10504,30 @@ decl_quals (const_tree decl)
 	     ? TYPE_QUAL_VOLATILE : TYPE_UNQUALIFIED));
 }
 
+static unsigned int
+decl_user_align (const_tree decl)
+{
+  if (DECL_USER_ALIGN (decl))
+    return DECL_ALIGN_UNIT (decl);
+
+  return 0;
+}
+
+static unsigned int
+type_user_align (const_tree type)
+{
+  if (TYPE_USER_ALIGN (type))
+    return TYPE_ALIGN_UNIT (type);
+
+  return 0;
+}
+
 /* 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 cv_quals, dw_die_ref context_die)
+modified_type_die (tree type, int cv_quals, unsigned int align,
+		   dw_die_ref context_die)
 {
   enum tree_code code = TREE_CODE (type);
   dw_die_ref mod_type_die;
@@ -10531,14 +10550,23 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
   if (dwarf_version < 3)
     cv_quals &= ~TYPE_QUAL_RESTRICT;
 
-  /* Likewise for DW_TAG_atomic_type for DWARFv5.  */
+  /* Likewise for DW_TAG_atomic_type and DW_TAG_aligned_type for DWARFv5.  */
   if (dwarf_version < 5)
-    cv_quals &= ~TYPE_QUAL_ATOMIC;
+    {
+      cv_quals &= ~TYPE_QUAL_ATOMIC;
+      align = 0;
+    }
 
   /* See if we already have the appropriately qualified variant of
      this type.  */
   qualified_type = get_qualified_type (type, cv_quals);
 
+  /* Make sure the qualified type has the correct user alignment if we
+     need one.  */
+  if (align != 0 && qualified_type
+      && type_user_align (qualified_type) != align)
+    qualified_type = NULL_TREE;
+
   if (qualified_type == sizetype
       && TYPE_NAME (qualified_type)
       && TREE_CODE (TYPE_NAME (qualified_type)) == TYPE_DECL)
@@ -10585,7 +10613,7 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
 	    /* cv-unqualified version of named type.  Just use
 	       the unnamed type to which it refers.  */
 	    return modified_type_die (DECL_ORIGINAL_TYPE (name),
-				      cv_quals, context_die);
+				      cv_quals, align, context_die);
 	  /* Else cv-qualified version of named type; fall through.  */
 	}
     }
@@ -10602,7 +10630,7 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
     {
       mod_type_die = new_die (DW_TAG_const_type, mod_scope, type);
       sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_CONST,
-				   context_die);
+				   align, context_die);
     }
   else if ((cv_quals & TYPE_QUAL_VOLATILE)
 	   && (((cv_quals & ~TYPE_QUAL_VOLATILE) == TYPE_UNQUALIFIED)
@@ -10612,7 +10640,7 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
     {
       mod_type_die = new_die (DW_TAG_volatile_type, mod_scope, type);
       sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_VOLATILE,
-				   context_die);
+				   align, context_die);
     }
   else if ((cv_quals & TYPE_QUAL_RESTRICT)
 	   && (((cv_quals & ~TYPE_QUAL_RESTRICT) == TYPE_UNQUALIFIED)
@@ -10622,13 +10650,19 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
     {
       mod_type_die = new_die (DW_TAG_restrict_type, mod_scope, type);
       sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_RESTRICT,
-				   context_die);
+				   align, context_die);
     }
   else if (cv_quals & TYPE_QUAL_ATOMIC)
     {
       mod_type_die = new_die (DW_TAG_atomic_type, mod_scope, type);
       sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_ATOMIC,
-				   context_die);
+				   align, context_die);
+    }
+  else if (align != 0)
+    {
+      mod_type_die = new_die (DW_TAG_aligned_type, mod_scope, type);
+      add_AT_unsigned (mod_type_die, DW_AT_alignment, align);
+      sub_die = modified_type_die (type, cv_quals, 0, context_die);
     }
   else if (code == POINTER_TYPE)
     {
@@ -10719,7 +10753,7 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
        types are possible in Ada.  */
     sub_die = modified_type_die (item_type,
 				 TYPE_QUALS_NO_ADDR_SPACE (item_type),
-				 context_die);
+				 type_user_align (item_type), context_die);
 
   if (sub_die != NULL)
     add_AT_die_ref (mod_type_die, DW_AT_type, sub_die);
@@ -10863,7 +10897,7 @@ generic_parameter_die (tree parm, tree arg,
 	  add_type_attribute (tmpl_die, tmpl_type,
 			      (TREE_THIS_VOLATILE (tmpl_type)
 			       ? TYPE_QUAL_VOLATILE : TYPE_UNQUALIFIED),
-			      parent_die);
+			      0, parent_die);
 	}
       else
 	{
@@ -11604,7 +11638,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, TYPE_UNQUALIFIED, comp_unit_die ());
+    type_die = modified_type_die (type, TYPE_UNQUALIFIED, 0, comp_unit_die ());
   if (type_die == NULL || type_die->die_tag != DW_TAG_base_type)
     return NULL;
   return type_die;
@@ -16521,7 +16555,8 @@ 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), TYPE_QUAL_CONST, ctx);
+	add_type_attribute (decl_die, TREE_TYPE (bound), TYPE_QUAL_CONST, 0,
+			    ctx);
 	add_AT_location_description (decl_die, DW_AT_location, list);
 	add_AT_die_ref (subrange_die, bound_attr, decl_die);
 	break;
@@ -16573,7 +16608,7 @@ add_subscript_info (dw_die_ref type_die, tree type, bool collapse_p)
 		;
 	      else
 		add_type_attribute (subrange_die, TREE_TYPE (domain),
-				    TYPE_UNQUALIFIED, type_die);
+				    TYPE_UNQUALIFIED, 0, type_die);
 	    }
 
 	  /* ??? If upper is NULL, the array has unspecified length,
@@ -17069,10 +17104,11 @@ class_or_namespace_scope_p (dw_die_ref context_die)
 
 static void
 add_type_attribute (dw_die_ref object_die, tree type, int cv_quals,
-		    dw_die_ref context_die)
+		    unsigned int align, dw_die_ref context_die)
 {
   enum tree_code code  = TREE_CODE (type);
   dw_die_ref type_die  = NULL;
+  unsigned int type_align;
 
   /* ??? If this type is an unnamed subrange type of an integral, floating-point
      or fixed-point type, use the inner type.  This is because we have no
@@ -17089,8 +17125,10 @@ add_type_attribute (dw_die_ref object_die, tree type, int cv_quals,
       || code == VOID_TYPE)
     return;
 
+  type_align = type_user_align (type);
   type_die = modified_type_die (type,
 				cv_quals | TYPE_QUALS_NO_ADDR_SPACE (type),
+				(type_align > align ? type_align : align),
 				context_die);
 
   if (type_die != NULL)
@@ -17304,7 +17342,8 @@ gen_array_type_die (tree type, dw_die_ref context_die)
 	element_type = TREE_TYPE (element_type);
       }
 
-  add_type_attribute (array_die, element_type, TYPE_UNQUALIFIED, context_die);
+  add_type_attribute (array_die, element_type, TYPE_UNQUALIFIED, 0,
+		      context_die);
 
   add_gnat_descriptive_type_attribute (array_die, type, context_die);
   if (TYPE_ARTIFICIAL (type))
@@ -17467,7 +17506,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, TYPE_UNQUALIFIED,
+  add_type_attribute (array_die, info->element_type, TYPE_UNQUALIFIED, 0,
 		      context_die);
 
   if (get_AT (array_die, DW_AT_name))
@@ -17487,7 +17526,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)),
-			  TYPE_UNQUALIFIED, context_die);
+			  TYPE_UNQUALIFIED, 0, context_die);
     }
 
   if (DECL_ABSTRACT (decl))
@@ -17577,7 +17616,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, TYPE_UNQUALIFIED,
+	  add_type_attribute (type_die, underlying, TYPE_UNQUALIFIED, 0,
 			      context_die);
 	}
       if (TYPE_STUB_DECL (type) != NULL_TREE)
@@ -17680,11 +17719,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),
-				TYPE_UNQUALIFIED, context_die);
+				TYPE_UNQUALIFIED, 0, context_die);
 	  else
 	    add_type_attribute (parm_die, type,
 				decl_quals (node_or_origin),
-				context_die);
+				decl_user_align (node_or_origin), context_die);
 	}
       if (origin == NULL && DECL_ARTIFICIAL (node))
 	add_AT_flag (parm_die, DW_AT_artificial, 1);
@@ -17699,7 +17738,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, TYPE_UNQUALIFIED,
+      add_type_attribute (parm_die, node_or_origin, TYPE_UNQUALIFIED, 0,
 			  context_die);
       break;
 
@@ -18282,7 +18321,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)),
-				    TYPE_UNQUALIFIED, context_die);
+				    TYPE_UNQUALIFIED, 0, context_die);
 	    }
 	}
     }
@@ -18299,7 +18338,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)),
-			      TYPE_UNQUALIFIED, context_die);
+			      TYPE_UNQUALIFIED, 0, context_die);
 	}
 
       add_pure_or_virtual_attribute (subr_die, decl);
@@ -18915,7 +18954,7 @@ 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), decl_quals (decl),
-			  context_die);
+			  decl_user_align (decl), context_die);
       add_AT_flag (var_die, DW_AT_external, 1);
       if (loc)
 	{
@@ -19008,11 +19047,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), TYPE_UNQUALIFIED,
+	add_type_attribute (var_die, TREE_TYPE (type), TYPE_UNQUALIFIED, 0,
 			    context_die);
       else
 	add_type_attribute (var_die, type, decl_quals (decl_or_origin),
-			    context_die);
+			    decl_user_align (decl_or_origin), context_die);
     }
 
   if (origin == NULL && !specialization_p)
@@ -19066,7 +19105,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, TYPE_QUAL_CONST, context_die);
+  add_type_attribute (const_die, type, TYPE_QUAL_CONST, 0, context_die);
   if (TREE_PUBLIC (decl))
     add_AT_flag (const_die, DW_AT_external, 1);
   if (DECL_ARTIFICIAL (decl))
@@ -19309,7 +19348,8 @@ 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),
-		      decl_quals (decl), context_die);
+		      decl_quals (decl), decl_user_align (decl),
+		      context_die);
 
   if (DECL_BIT_FIELD_TYPE (decl))
     {
@@ -19343,7 +19383,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), TYPE_UNQUALIFIED,
+  add_type_attribute (ptr_die, TREE_TYPE (type), TYPE_UNQUALIFIED, 0,
 		      context_die);
   add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE);
 }
@@ -19364,7 +19404,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), TYPE_UNQUALIFIED,
+  add_type_attribute (ref_die, TREE_TYPE (type), TYPE_UNQUALIFIED, 0,
 		      context_die);
   add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE);
 }
@@ -19382,7 +19422,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), TYPE_UNQUALIFIED,
+  add_type_attribute (ptr_die, TREE_TYPE (type), TYPE_UNQUALIFIED, 0,
 		      context_die);
 }
 
@@ -19588,7 +19628,8 @@ 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), TYPE_UNQUALIFIED, context_die);
+  add_type_attribute (die, BINFO_TYPE (binfo), TYPE_UNQUALIFIED, 0,
+		      context_die);
   add_data_member_location_attribute (die, binfo);
 
   if (BINFO_VIRTUAL_P (binfo))
@@ -19785,7 +19826,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, TYPE_UNQUALIFIED, context_die);
+  add_type_attribute (subr_die, return_type, TYPE_UNQUALIFIED, 0, context_die);
   gen_formal_types_die (type, subr_die);
 
   if (get_AT (subr_die, DW_AT_name))
@@ -19853,7 +19894,8 @@ gen_typedef_die (tree decl, dw_die_ref context_die)
 	    }
 	}
 
-      add_type_attribute (type_die, type, decl_quals (decl), context_die);
+      add_type_attribute (type_die, type, decl_quals (decl),
+			  decl_user_align (decl), context_die);
 
       if (is_naming_typedef_decl (decl))
 	/* We want that all subsequent calls to lookup_type_die with
@@ -20429,7 +20471,7 @@ force_type_die (tree type)
       dw_die_ref context_die = get_context_die (TYPE_CONTEXT (type));
 
       type_die = modified_type_die (type, TYPE_QUALS_NO_ADDR_SPACE (type),
-				    context_die);
+				    type_user_align (type), context_die);
       gcc_assert (type_die);
     }
   return type_die;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6ff6a1e..5706c04 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
 2014-07-09  Mark Wielaard  <mjw@redhat.com>
 
+	* gcc.dg/guality/alignas.c: New test.
+
+2014-07-09  Mark Wielaard  <mjw@redhat.com>
+
 	PR debug/60782
 	* gcc.dg/guality/atomic.c: New test.
 
diff --git a/gcc/testsuite/gcc.dg/guality/alignas.c b/gcc/testsuite/gcc.dg/guality/alignas.c
new file mode 100644
index 0000000..c47b511
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/alignas.c
@@ -0,0 +1,57 @@
+/* debuginfo tests for c11 _Alignas. */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -gdwarf-5" } */
+
+#include <stdlib.h>
+#include <malloc.h>
+
+// char normally has alignment 1, say it aligns 8.
+_Alignas (8) char c8;
+
+// multiple alignment requests pick the strictest (largest).
+_Alignas(16) _Alignas(32) _Alignas(8) int i32;
+
+// _Alignas on an array sets alignment of array element type.
+_Alignas(64) unsigned int buf[128];
+
+// Also for const ints.
+const _Alignas (256) unsigned int buf2[] = {0, 1, 2, 3, 4, 5, 6, 8};
+
+// An aligned pointer.
+// (note this applies to the pointer, not to the target type/value).
+unsigned int _Alignas (64) *uiap;
+
+// A const aligned pointer, pointing to a const type (not aligned).
+const unsigned int _Alignas (128) * const cuicap;
+
+// _Alignas on structure field puts offsets at multiples of alignment.
+struct s { int a; _Alignas (16) int bar; };
+
+// Variables of structs can be aligned themselves.
+_Alignas(32) struct s vs = { 1, 14 };
+
+// _Alignas(0) has no effect.
+_Alignas(0) long l;
+
+// And _Alignas can be combined with other qualifiers.
+_Alignas(16) volatile const float vcf16 = 32.0;
+const _Alignas(16) volatile float cvf16 = 64.0;
+
+int
+main (int argc, char **argv)
+{
+  struct s *p = (struct s *) memalign (64, sizeof (struct s));
+  return p == 0;
+}
+
+/* { dg-final { gdb-test 32 "type:c8" "_Alignas (8) char" } } */
+/* { dg-final { gdb-test 32 "type:i32" "_Alignas (32) int" } } */
+/* { dg-final { gdb-test 32 "type:buf" "_Alignas (64) unsigned int \[128\]" } } */
+/* { dg-final { gdb-test 32 "type:buf2" "const _Alignas (256) unsigned int \[8\]" } } */
+/* { dg-final { gdb-test 32 "type:uiap" "unsigned int _Alignas (64) *" } } */
+/* { dg-final { gdb-test 32 "type:cuicap" "const unsigned int _Alignas (128) * const" } } */
+/* { dg-final { gdb-test 32 "type:struct s" "struct s { int a; _Alignas (16) int bar; }" } } */
+/* { dg-final { gdb-test 32 "type:vs" "_Alignas (32) struct s { int a; _Alignas (16) int bar; }" } } */
+/* { dg-final { gdb-test 32 "type:l" "long" } } */
+/* { dg-final { gdb-test 32 "type:vcf16" "const volatile _Alignas (16) float" } } */
+/* { dg-final { gdb-test 32 "type:cvf16" "const volatile _Alignas (16) float" } } */
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 6490391..7ca0704 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -135,6 +135,7 @@ DW_TAG (DW_TAG_rvalue_reference_type, 0x42)
 DW_TAG (DW_TAG_template_alias, 0x43)
 /* DWARF 5.  */
 DW_TAG (DW_TAG_atomic_type, 0x47) /* NOT AN OFFICIAL NUMBER. DWARF5 131112.1 */
+DW_TAG (DW_TAG_aligned_type, 0x48) /* NOT AN OFFICIAL NUMBER. DWARF5 140528.1  */
 
 DW_TAG_DUP (DW_TAG_lo_user, 0x4080)
 DW_TAG_DUP (DW_TAG_hi_user, 0xffff)
@@ -310,6 +311,8 @@ DW_AT (DW_AT_data_bit_offset, 0x6b)
 DW_AT (DW_AT_const_expr, 0x6c)
 DW_AT (DW_AT_enum_class, 0x6d)
 DW_AT (DW_AT_linkage_name, 0x6e)
+/* DWARF 5.  */
+DW_TAG (DW_AT_alignment, 0x6f) /* NOT AN OFFICIAL NUMBER. DWARF5 140528.1  */
 
 DW_AT_DUP (DW_AT_lo_user, 0x2000) /* Implementation-defined range start.  */
 DW_AT_DUP (DW_AT_hi_user, 0x3fff) /* Implementation-defined range end.  */
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Some DWARFv5 proposal prototypes (atomic_type, aligned_type)
  2014-07-09 21:36       ` Some DWARFv5 proposal prototypes (atomic_type, aligned_type) Mark Wielaard
@ 2014-07-14 20:03         ` Tom Tromey
  2014-07-15 11:57           ` Mark Wielaard
  0 siblings, 1 reply; 30+ messages in thread
From: Tom Tromey @ 2014-07-14 20:03 UTC (permalink / raw)
  To: Mark Wielaard
  Cc: gcc-patches, Jason Merrill, Cary Coutant, Joseph S. Myers,
	Joel Brobecker

>>>>> "Mark" == Mark Wielaard <mjw@redhat.com> writes:

Hi Mark.

Mark> The following two patches are based on the earlier "dwarf2out.c: Pass
Mark> one cv_quals argument" and "Emit DW_tag_restrict_type" patches I posted
Mark> earlier. Since there currently is not even an early draft yet for DWARFv5,
Mark> just a collection of proposals that might or might not be adopted these
Mark> patches are not meant to be integrated just yet. But I would like to get
Mark> feedback on the code and whether the new debug information is useful.

I didn't read the patches I'm afraid.
However, the new debug information is definitely useful for the gcc/gdb
integration project.  Without it I think the user can end up with
mysterious failures in their compiled expressions.

Tom

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Some DWARFv5 proposal prototypes (atomic_type, aligned_type)
  2014-07-14 20:03         ` Tom Tromey
@ 2014-07-15 11:57           ` Mark Wielaard
  2014-07-15 20:55             ` Eric Christopher
  0 siblings, 1 reply; 30+ messages in thread
From: Mark Wielaard @ 2014-07-15 11:57 UTC (permalink / raw)
  To: Tom Tromey
  Cc: gcc-patches, Jason Merrill, Cary Coutant, Joseph S. Myers,
	Joel Brobecker

On Mon, 2014-07-14 at 13:58 -0600, Tom Tromey wrote:
> >>>>> "Mark" == Mark Wielaard <mjw@redhat.com> writes:
> Mark> The following two patches are based on the earlier "dwarf2out.c: Pass
> Mark> one cv_quals argument" and "Emit DW_tag_restrict_type" patches I posted
> Mark> earlier. Since there currently is not even an early draft yet for DWARFv5,
> Mark> just a collection of proposals that might or might not be adopted these
> Mark> patches are not meant to be integrated just yet. But I would like to get
> Mark> feedback on the code and whether the new debug information is useful.
> 
> I didn't read the patches I'm afraid.
> However, the new debug information is definitely useful for the gcc/gdb
> integration project.  Without it I think the user can end up with
> mysterious failures in their compiled expressions.

I don't know how far DWARFv5 is at the moment, these proposals haven't
even made it to a draft yet, so we might have to look at turning them
into GNU extensions first then.

But first I need some feedback on the dwarf2out.c refactoring for
passing around cv-qualifiers and the addition of the restrict tag
patches on which these DWARFv5 prototypes are based:

https://gcc.gnu.org/ml/gcc-patches/2014-07/msg00569.html
https://gcc.gnu.org/ml/gcc-patches/2014-07/msg00575.html

Thanks,

Mark

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Some DWARFv5 proposal prototypes (atomic_type, aligned_type)
  2014-07-15 11:57           ` Mark Wielaard
@ 2014-07-15 20:55             ` Eric Christopher
  0 siblings, 0 replies; 30+ messages in thread
From: Eric Christopher @ 2014-07-15 20:55 UTC (permalink / raw)
  To: Mark Wielaard
  Cc: Tom Tromey, gcc-patches, Jason Merrill, Cary Coutant,
	Joseph S. Myers, Joel Brobecker

On Tue, Jul 15, 2014 at 4:36 AM, Mark Wielaard <mjw@redhat.com> wrote:
> On Mon, 2014-07-14 at 13:58 -0600, Tom Tromey wrote:
>> >>>>> "Mark" == Mark Wielaard <mjw@redhat.com> writes:
>> Mark> The following two patches are based on the earlier "dwarf2out.c: Pass
>> Mark> one cv_quals argument" and "Emit DW_tag_restrict_type" patches I posted
>> Mark> earlier. Since there currently is not even an early draft yet for DWARFv5,
>> Mark> just a collection of proposals that might or might not be adopted these
>> Mark> patches are not meant to be integrated just yet. But I would like to get
>> Mark> feedback on the code and whether the new debug information is useful.
>>
>> I didn't read the patches I'm afraid.
>> However, the new debug information is definitely useful for the gcc/gdb
>> integration project.  Without it I think the user can end up with
>> mysterious failures in their compiled expressions.
>
> I don't know how far DWARFv5 is at the moment, these proposals haven't
> even made it to a draft yet, so we might have to look at turning them
> into GNU extensions first then.
>

Dwarf5 is fairly well locked down at this point. But that doesn't stop
us from getting this fairly well defined so we can put it in 6 and it
can just be an extension until then.

-eric

> But first I need some feedback on the dwarf2out.c refactoring for
> passing around cv-qualifiers and the addition of the restrict tag
> patches on which these DWARFv5 prototypes are based:
>
> https://gcc.gnu.org/ml/gcc-patches/2014-07/msg00569.html
> https://gcc.gnu.org/ml/gcc-patches/2014-07/msg00575.html
>
> Thanks,
>
> Mark
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Add guality [p]type test.
  2014-07-07  9:58     ` Richard Biener
@ 2014-08-19 11:06       ` Mark Wielaard
  2014-08-19 11:23         ` Richard Biener
  0 siblings, 1 reply; 30+ messages in thread
From: Mark Wielaard @ 2014-08-19 11:06 UTC (permalink / raw)
  To: Richard Biener
  Cc: GCC Patches, Jason Merrill, Cary Coutant, Alexandre Oliva, Jakub Jelinek

On Mon, 2014-07-07 at 11:57 +0200, Richard Biener wrote:
> Btw, why doesn't it succeed with LTO?  I suspect it's because
> we drop the unused variables - try adding __attribute__((used)) to
> them.

You are right, this makes the whole new test PASS also with LTO:

2014-08-19  Mark Wielaard  <mjw@redhat.com>

    * gcc.dg/guality/const-volatile.c: Add `used' attribute to pi.

OK to commit?

Thanks,

Mark

diff --git a/gcc/testsuite/gcc.dg/guality/const-volatile.c b/gcc/testsuite/gcc.dg/guality/const-volatile.c
index 6c2b617..86460e4 100644
--- a/gcc/testsuite/gcc.dg/guality/const-volatile.c
+++ b/gcc/testsuite/gcc.dg/guality/const-volatile.c
@@ -7,7 +7,7 @@ const int ci;
 volatile int vi;
 const volatile int cvi;
 
-int *pi;
+int *pi __attribute__((used));
 const int *pci;
 volatile int *pvi;
 const volatile int *pcvi;

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Add guality [p]type test.
  2014-08-19 11:06       ` Mark Wielaard
@ 2014-08-19 11:23         ` Richard Biener
  2014-08-19 12:10           ` Mark Wielaard
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Biener @ 2014-08-19 11:23 UTC (permalink / raw)
  To: Mark Wielaard
  Cc: GCC Patches, Jason Merrill, Cary Coutant, Alexandre Oliva, Jakub Jelinek

On Tue, Aug 19, 2014 at 1:05 PM, Mark Wielaard <mjw@redhat.com> wrote:
> On Mon, 2014-07-07 at 11:57 +0200, Richard Biener wrote:
>> Btw, why doesn't it succeed with LTO?  I suspect it's because
>> we drop the unused variables - try adding __attribute__((used)) to
>> them.
>
> You are right, this makes the whole new test PASS also with LTO:
>
> 2014-08-19  Mark Wielaard  <mjw@redhat.com>
>
>     * gcc.dg/guality/const-volatile.c: Add `used' attribute to pi.
>
> OK to commit?

Ok.

Thanks,
Richard.

> Thanks,
>
> Mark
>
> diff --git a/gcc/testsuite/gcc.dg/guality/const-volatile.c b/gcc/testsuite/gcc.dg/guality/const-volatile.c
> index 6c2b617..86460e4 100644
> --- a/gcc/testsuite/gcc.dg/guality/const-volatile.c
> +++ b/gcc/testsuite/gcc.dg/guality/const-volatile.c
> @@ -7,7 +7,7 @@ const int ci;
>  volatile int vi;
>  const volatile int cvi;
>
> -int *pi;
> +int *pi __attribute__((used));
>  const int *pci;
>  volatile int *pvi;
>  const volatile int *pcvi;
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Add guality [p]type test.
  2014-08-19 11:23         ` Richard Biener
@ 2014-08-19 12:10           ` Mark Wielaard
  2014-08-19 12:16             ` Richard Biener
  0 siblings, 1 reply; 30+ messages in thread
From: Mark Wielaard @ 2014-08-19 12:10 UTC (permalink / raw)
  To: Richard Biener
  Cc: GCC Patches, Jason Merrill, Cary Coutant, Alexandre Oliva, Jakub Jelinek

On Tue, 2014-08-19 at 13:22 +0200, Richard Biener wrote:
> On Tue, Aug 19, 2014 at 1:05 PM, Mark Wielaard <mjw@redhat.com> wrote:
> > On Mon, 2014-07-07 at 11:57 +0200, Richard Biener wrote:
> >> Btw, why doesn't it succeed with LTO?  I suspect it's because
> >> we drop the unused variables - try adding __attribute__((used)) to
> >> them.
> >
> > You are right, this makes the whole new test PASS also with LTO:
> >
> > 2014-08-19  Mark Wielaard  <mjw@redhat.com>
> >
> >     * gcc.dg/guality/const-volatile.c: Add `used' attribute to pi.
> >
> > OK to commit?
> 
> Ok.

Here is the same for the new restrict.c testcase.

gcc/testsuite/ChangeLog
2014-08-19  Mark Wielaard  <mjw@redhat.com>
 
    * gcc.dg/guality/restrict.c: Add `used' attribute to all variables.
    (cpy): Change type of last argument to int.

That last change is necessary to succeed with LTO. Otherwise the type of
the function:

static __attribute__((noclone, noinline)) void *
cpy (void * restrict s1, const void * restrict s2, unsigned int n)

comes out as:

void *(void * restrict, const void * restrict, __unknown__)

That seems a genuine bug. Should I commit the cpy function type change
to make the test PASS with LTO? Or leave it as is so it FAILs and
someone else can look into it?

Thanks,

Mark

diff --git a/gcc/testsuite/gcc.dg/guality/restrict.c b/gcc/testsuite/gcc.dg/guality/restrict.c
index e31224b..43a4ede 100644
--- a/gcc/testsuite/gcc.dg/guality/restrict.c
+++ b/gcc/testsuite/gcc.dg/guality/restrict.c
@@ -2,19 +2,19 @@
 /* { dg-do run } */
 /* { dg-options "-std=c99 -gdwarf-3" } */
 
-int *ip;
-const int *cip;
-int * restrict irp;
-int * const icp;
-const int * restrict cirp;
-int * const restrict icrp;
-const int * const restrict cicrp;
+int *ip __attribute__((used));
+const int *cip __attribute__((used));
+int * restrict irp __attribute__((used));
+int * const icp __attribute__((used));
+const int * restrict cirp __attribute__((used));
+int * const restrict icrp __attribute__((used));
+const int * const restrict cicrp __attribute__((used));
 
-int * const volatile restrict cvirp;
-const volatile int * restrict pcvir;
+int * const volatile restrict cvirp __attribute__((used));
+const volatile int * restrict pcvir __attribute__((used));
 
 static __attribute__((noclone, noinline)) void *
-cpy (void * restrict s1, const void * restrict s2, unsigned int n)
+cpy (void * restrict s1, const void * restrict s2, int n)
 {
   char *t1 = s1;
   const char *t2 = s2;
@@ -45,4 +45,4 @@ main (int argc, char **argv)
 /* { dg-final { gdb-test 30 "type:pcvir" "const volatile int * restrict" } } */
 
 /* { dg-final { gdb-test 30 "type:main" "int (int, char **)" } } */
-/* { dg-final { gdb-test 30 "type:cpy" "void *(void * restrict, const void * restrict, unsigned int)" } } */
+/* { dg-final { gdb-test 30 "type:cpy" "void *(void * restrict, const void * restrict, int)" } } */

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Add guality [p]type test.
  2014-08-19 12:10           ` Mark Wielaard
@ 2014-08-19 12:16             ` Richard Biener
  2014-08-19 17:52               ` Mark Wielaard
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Biener @ 2014-08-19 12:16 UTC (permalink / raw)
  To: Mark Wielaard
  Cc: GCC Patches, Jason Merrill, Cary Coutant, Alexandre Oliva, Jakub Jelinek

On Tue, Aug 19, 2014 at 2:10 PM, Mark Wielaard <mjw@redhat.com> wrote:
> On Tue, 2014-08-19 at 13:22 +0200, Richard Biener wrote:
>> On Tue, Aug 19, 2014 at 1:05 PM, Mark Wielaard <mjw@redhat.com> wrote:
>> > On Mon, 2014-07-07 at 11:57 +0200, Richard Biener wrote:
>> >> Btw, why doesn't it succeed with LTO?  I suspect it's because
>> >> we drop the unused variables - try adding __attribute__((used)) to
>> >> them.
>> >
>> > You are right, this makes the whole new test PASS also with LTO:
>> >
>> > 2014-08-19  Mark Wielaard  <mjw@redhat.com>
>> >
>> >     * gcc.dg/guality/const-volatile.c: Add `used' attribute to pi.
>> >
>> > OK to commit?
>>
>> Ok.
>
> Here is the same for the new restrict.c testcase.
>
> gcc/testsuite/ChangeLog
> 2014-08-19  Mark Wielaard  <mjw@redhat.com>
>
>     * gcc.dg/guality/restrict.c: Add `used' attribute to all variables.
>     (cpy): Change type of last argument to int.
>
> That last change is necessary to succeed with LTO. Otherwise the type of
> the function:
>
> static __attribute__((noclone, noinline)) void *
> cpy (void * restrict s1, const void * restrict s2, unsigned int n)
>
> comes out as:
>
> void *(void * restrict, const void * restrict, __unknown__)
>
> That seems a genuine bug. Should I commit the cpy function type change
> to make the test PASS with LTO? Or leave it as is so it FAILs and
> someone else can look into it?

Yeah, that's a genuine bug.  Not sure why it happens.  If you file a bug
I can have a look later.

Thanks,
Richard.

> Thanks,
>
> Mark
>
> diff --git a/gcc/testsuite/gcc.dg/guality/restrict.c b/gcc/testsuite/gcc.dg/guality/restrict.c
> index e31224b..43a4ede 100644
> --- a/gcc/testsuite/gcc.dg/guality/restrict.c
> +++ b/gcc/testsuite/gcc.dg/guality/restrict.c
> @@ -2,19 +2,19 @@
>  /* { dg-do run } */
>  /* { dg-options "-std=c99 -gdwarf-3" } */
>
> -int *ip;
> -const int *cip;
> -int * restrict irp;
> -int * const icp;
> -const int * restrict cirp;
> -int * const restrict icrp;
> -const int * const restrict cicrp;
> +int *ip __attribute__((used));
> +const int *cip __attribute__((used));
> +int * restrict irp __attribute__((used));
> +int * const icp __attribute__((used));
> +const int * restrict cirp __attribute__((used));
> +int * const restrict icrp __attribute__((used));
> +const int * const restrict cicrp __attribute__((used));
>
> -int * const volatile restrict cvirp;
> -const volatile int * restrict pcvir;
> +int * const volatile restrict cvirp __attribute__((used));
> +const volatile int * restrict pcvir __attribute__((used));
>
>  static __attribute__((noclone, noinline)) void *
> -cpy (void * restrict s1, const void * restrict s2, unsigned int n)
> +cpy (void * restrict s1, const void * restrict s2, int n)
>  {
>    char *t1 = s1;
>    const char *t2 = s2;
> @@ -45,4 +45,4 @@ main (int argc, char **argv)
>  /* { dg-final { gdb-test 30 "type:pcvir" "const volatile int * restrict" } } */
>
>  /* { dg-final { gdb-test 30 "type:main" "int (int, char **)" } } */
> -/* { dg-final { gdb-test 30 "type:cpy" "void *(void * restrict, const void * restrict, unsigned int)" } } */
> +/* { dg-final { gdb-test 30 "type:cpy" "void *(void * restrict, const void * restrict, int)" } } */
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Add guality [p]type test.
  2014-08-19 12:16             ` Richard Biener
@ 2014-08-19 17:52               ` Mark Wielaard
  2014-08-20  8:49                 ` Richard Biener
  0 siblings, 1 reply; 30+ messages in thread
From: Mark Wielaard @ 2014-08-19 17:52 UTC (permalink / raw)
  To: Richard Biener
  Cc: GCC Patches, Jason Merrill, Cary Coutant, Alexandre Oliva, Jakub Jelinek

On Tue, 2014-08-19 at 14:16 +0200, Richard Biener wrote:
> On Tue, Aug 19, 2014 at 2:10 PM, Mark Wielaard <mjw@redhat.com> wrote:
> > gcc/testsuite/ChangeLog
> > 2014-08-19  Mark Wielaard  <mjw@redhat.com>
> >
> >     * gcc.dg/guality/restrict.c: Add `used' attribute to all variables.
> >     (cpy): Change type of last argument to int.
> >
> > That last change is necessary to succeed with LTO. Otherwise the type of
> > the function:
> >
> > static __attribute__((noclone, noinline)) void *
> > cpy (void * restrict s1, const void * restrict s2, unsigned int n)
> >
> > comes out as:
> >
> > void *(void * restrict, const void * restrict, __unknown__)
> >
> > That seems a genuine bug. Should I commit the cpy function type change
> > to make the test PASS with LTO? Or leave it as is so it FAILs and
> > someone else can look into it?
> 
> Yeah, that's a genuine bug.  Not sure why it happens.  If you file a bug
> I can have a look later.

Filed as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62190 "LTO DWARF
produces __unknown__ type for unsigned int function argument type".

I included a smaller testcase in the bug that can just be dropped into
gcc/testsuite/gcc.dg/guality/ to show the issue. Shall I just commit the
change to the restrict.c testcase, so at least that one always PASSes
for now?

Cheers,

Mark

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Add guality [p]type test.
  2014-08-19 17:52               ` Mark Wielaard
@ 2014-08-20  8:49                 ` Richard Biener
  2014-08-20 12:19                   ` Mark Wielaard
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Biener @ 2014-08-20  8:49 UTC (permalink / raw)
  To: Mark Wielaard
  Cc: GCC Patches, Jason Merrill, Cary Coutant, Alexandre Oliva, Jakub Jelinek

On Tue, Aug 19, 2014 at 7:52 PM, Mark Wielaard <mjw@redhat.com> wrote:
> On Tue, 2014-08-19 at 14:16 +0200, Richard Biener wrote:
>> On Tue, Aug 19, 2014 at 2:10 PM, Mark Wielaard <mjw@redhat.com> wrote:
>> > gcc/testsuite/ChangeLog
>> > 2014-08-19  Mark Wielaard  <mjw@redhat.com>
>> >
>> >     * gcc.dg/guality/restrict.c: Add `used' attribute to all variables.
>> >     (cpy): Change type of last argument to int.
>> >
>> > That last change is necessary to succeed with LTO. Otherwise the type of
>> > the function:
>> >
>> > static __attribute__((noclone, noinline)) void *
>> > cpy (void * restrict s1, const void * restrict s2, unsigned int n)
>> >
>> > comes out as:
>> >
>> > void *(void * restrict, const void * restrict, __unknown__)
>> >
>> > That seems a genuine bug. Should I commit the cpy function type change
>> > to make the test PASS with LTO? Or leave it as is so it FAILs and
>> > someone else can look into it?
>>
>> Yeah, that's a genuine bug.  Not sure why it happens.  If you file a bug
>> I can have a look later.
>
> Filed as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62190 "LTO DWARF
> produces __unknown__ type for unsigned int function argument type".
>
> I included a smaller testcase in the bug that can just be dropped into
> gcc/testsuite/gcc.dg/guality/ to show the issue. Shall I just commit the
> change to the restrict.c testcase, so at least that one always PASSes
> for now?

No need - I have a fix in testing.

Richard.

> Cheers,
>
> Mark

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Add guality [p]type test.
  2014-08-20  8:49                 ` Richard Biener
@ 2014-08-20 12:19                   ` Mark Wielaard
  2014-08-20 12:31                     ` Richard Biener
  0 siblings, 1 reply; 30+ messages in thread
From: Mark Wielaard @ 2014-08-20 12:19 UTC (permalink / raw)
  To: Richard Biener
  Cc: GCC Patches, Jason Merrill, Cary Coutant, Alexandre Oliva, Jakub Jelinek

On Wed, 2014-08-20 at 10:49 +0200, Richard Biener wrote:
> On Tue, Aug 19, 2014 at 7:52 PM, Mark Wielaard <mjw@redhat.com> wrote:
> > Filed as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62190 "LTO DWARF
> > produces __unknown__ type for unsigned int function argument type".
> >
> > I included a smaller testcase in the bug that can just be dropped into
> > gcc/testsuite/gcc.dg/guality/ to show the issue. Shall I just commit the
> > change to the restrict.c testcase, so at least that one always PASSes
> > for now?
> 
> No need - I have a fix in testing.

Thanks, that fix works for me. But I still need to mark the variables as
used in the restrict.c test case to turn them from UNSUPPORTED to PASS
with LTO.

2014-08-20  Mark Wielaard  <mjw@redhat.com>

    * gcc.dg/guality/restrict.c: Add `used' attribute to all variables.

OK to push?

Thanks,

Mark

diff --git a/gcc/testsuite/gcc.dg/guality/restrict.c b/gcc/testsuite/gcc.dg/guality/restrict.c
index e31224b..62d7832 100644
--- a/gcc/testsuite/gcc.dg/guality/restrict.c
+++ b/gcc/testsuite/gcc.dg/guality/restrict.c
@@ -2,16 +2,16 @@
 /* { dg-do run } */
 /* { dg-options "-std=c99 -gdwarf-3" } */
 
-int *ip;
-const int *cip;
-int * restrict irp;
-int * const icp;
-const int * restrict cirp;
-int * const restrict icrp;
-const int * const restrict cicrp;
-
-int * const volatile restrict cvirp;
-const volatile int * restrict pcvir;
+int *ip __attribute__((used));
+const int *cip __attribute__((used));
+int * restrict irp __attribute__((used));
+int * const icp __attribute__((used));
+const int * restrict cirp __attribute__((used));
+int * const restrict icrp __attribute__((used));
+const int * const restrict cicrp __attribute__((used));
+
+int * const volatile restrict cvirp __attribute__((used));
+const volatile int * restrict pcvir __attribute__((used));
 
 static __attribute__((noclone, noinline)) void *
 cpy (void * restrict s1, const void * restrict s2, unsigned int n)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Add guality [p]type test.
  2014-08-20 12:19                   ` Mark Wielaard
@ 2014-08-20 12:31                     ` Richard Biener
  0 siblings, 0 replies; 30+ messages in thread
From: Richard Biener @ 2014-08-20 12:31 UTC (permalink / raw)
  To: Mark Wielaard
  Cc: GCC Patches, Jason Merrill, Cary Coutant, Alexandre Oliva, Jakub Jelinek

On Wed, Aug 20, 2014 at 2:19 PM, Mark Wielaard <mjw@redhat.com> wrote:
> On Wed, 2014-08-20 at 10:49 +0200, Richard Biener wrote:
>> On Tue, Aug 19, 2014 at 7:52 PM, Mark Wielaard <mjw@redhat.com> wrote:
>> > Filed as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62190 "LTO DWARF
>> > produces __unknown__ type for unsigned int function argument type".
>> >
>> > I included a smaller testcase in the bug that can just be dropped into
>> > gcc/testsuite/gcc.dg/guality/ to show the issue. Shall I just commit the
>> > change to the restrict.c testcase, so at least that one always PASSes
>> > for now?
>>
>> No need - I have a fix in testing.
>
> Thanks, that fix works for me. But I still need to mark the variables as
> used in the restrict.c test case to turn them from UNSUPPORTED to PASS
> with LTO.
>
> 2014-08-20  Mark Wielaard  <mjw@redhat.com>
>
>     * gcc.dg/guality/restrict.c: Add `used' attribute to all variables.
>
> OK to push?

Ok.

Thanks,
Richard.

> Thanks,
>
> Mark
>
> diff --git a/gcc/testsuite/gcc.dg/guality/restrict.c b/gcc/testsuite/gcc.dg/guality/restrict.c
> index e31224b..62d7832 100644
> --- a/gcc/testsuite/gcc.dg/guality/restrict.c
> +++ b/gcc/testsuite/gcc.dg/guality/restrict.c
> @@ -2,16 +2,16 @@
>  /* { dg-do run } */
>  /* { dg-options "-std=c99 -gdwarf-3" } */
>
> -int *ip;
> -const int *cip;
> -int * restrict irp;
> -int * const icp;
> -const int * restrict cirp;
> -int * const restrict icrp;
> -const int * const restrict cicrp;
> -
> -int * const volatile restrict cvirp;
> -const volatile int * restrict pcvir;
> +int *ip __attribute__((used));
> +const int *cip __attribute__((used));
> +int * restrict irp __attribute__((used));
> +int * const icp __attribute__((used));
> +const int * restrict cirp __attribute__((used));
> +int * const restrict icrp __attribute__((used));
> +const int * const restrict cicrp __attribute__((used));
> +
> +int * const volatile restrict cvirp __attribute__((used));
> +const volatile int * restrict pcvir __attribute__((used));
>
>  static __attribute__((noclone, noinline)) void *
>  cpy (void * restrict s1, const void * restrict s2, unsigned int n)
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 1/2] DWARFv5 Emit DW_TAG_atomic_type.
  2014-08-12 15:35 [PATCH 1/2] DWARFv5 Emit DW_TAG_atomic_type Mark Wielaard
@ 2014-08-12 19:32 ` Jason Merrill
  0 siblings, 0 replies; 30+ messages in thread
From: Jason Merrill @ 2014-08-12 19:32 UTC (permalink / raw)
  To: Mark Wielaard, gcc-patches; +Cc: Cary Coutant, Joseph S. Myers

On 08/12/2014 11:35 AM, Mark Wielaard wrote:
> Ping. This patch is based on the proposed patches to support the
> restrict type. But isn't meant to be integrated at this time. DWARFv5
> is still only a collection of proposals and hasn't seen any draft
> yet. But feedback is highly appreciated. Also if there are tips on how
> (and where) to maintain an experimental patch set for a future standard
> that would be welcome.

The patch looks fine.

As for where to maintain it, I'd suggest a branch in the git repository, 
mark/dwarf5 or some such.

Jason


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/2] DWARFv5 Emit DW_TAG_atomic_type.
@ 2014-08-12 15:35 Mark Wielaard
  2014-08-12 19:32 ` Jason Merrill
  0 siblings, 1 reply; 30+ messages in thread
From: Mark Wielaard @ 2014-08-12 15:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill, Cary Coutant, Joseph S. Myers, Mark Wielaard

Ping. This patch is based on the proposed patches to support the
restrict type. But isn't meant to be integrated at this time. DWARFv5
is still only a collection of proposals and hasn't seen any draft
yet. But feedback is highly appreciated. Also if there are tips on how
(and where) to maintain an experimental patch set for a future standard
that would be welcome.

There is a corresponding patch for GDB:
https://sourceware.org/ml/gdb-patches/2014-06/msg00795.html

gcc/ChangeLog

	PR debug/60782
	* dwarf2out.c (modified_type_die): Handle TYPE_QUAL_ATOMIC.
	* opts.c (common_handle_option): Accept -gdwarf-5.

gcc/testsuite/ChangeLog

	PR debug/60782
	* gcc.dg/guality/atomic.c: New test.

include/ChangeLog

	PR debug/60782
	* dwarf2.def: Add DWARFv5 DW_TAG_atomic_type.
---
 gcc/ChangeLog                         |  6 ++++++
 gcc/dwarf2out.c                       | 22 +++++++++++++++++++---
 gcc/opts.c                            |  2 +-
 gcc/testsuite/ChangeLog               |  5 +++++
 gcc/testsuite/gcc.dg/guality/atomic.c | 13 +++++++++++++
 include/ChangeLog                     |  5 +++++
 include/dwarf2.def                    |  2 ++
 7 files changed, 51 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/guality/atomic.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 428a1e1..1adf6a6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2014-07-09  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/60782
+	* dwarf2out.c (modified_type_die): Handle TYPE_QUAL_ATOMIC.
+	* opts.c (common_handle_option): Accept -gdwarf-5.
+
 2014-07-08  Mark Wielaard  <mjw@redhat.com>
 
 	PR debug/59051
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 51e379e..7792604 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -10478,7 +10478,8 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
     return NULL;
 
   /* Only these cv-qualifiers are currently handled.  */
-  cv_quals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT);
+  cv_quals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT
+	       | TYPE_QUAL_ATOMIC);
 
   /* Don't emit DW_TAG_restrict_type for DWARFv2, since it is a type
      tag modifier (and not an attribute) old consumers won't be able
@@ -10486,6 +10487,10 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
   if (dwarf_version < 3)
     cv_quals &= ~TYPE_QUAL_RESTRICT;
 
+  /* Likewise for DW_TAG_atomic_type for DWARFv5.  */
+  if (dwarf_version < 5)
+    cv_quals &= ~TYPE_QUAL_ATOMIC;
+
   /* See if we already have the appropriately qualified variant of
      this type.  */
   qualified_type = get_qualified_type (type, cv_quals);
@@ -10529,7 +10534,8 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
       else
 	{
 	  int dquals = TYPE_QUALS_NO_ADDR_SPACE (dtype);
-	  dquals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT);
+	  dquals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT
+		     | TYPE_QUAL_ATOMIC);
 	  if ((dquals & ~cv_quals) != TYPE_UNQUALIFIED
 	      || (cv_quals == dquals && DECL_ORIGINAL_TYPE (name) != type))
 	    /* cv-unqualified version of named type.  Just use
@@ -10564,12 +10570,22 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
       sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_VOLATILE,
 				   context_die);
     }
-  else if (cv_quals & TYPE_QUAL_RESTRICT)
+  else if ((cv_quals & TYPE_QUAL_RESTRICT)
+	   && (((cv_quals & ~TYPE_QUAL_RESTRICT) == TYPE_UNQUALIFIED)
+	       || get_qualified_type (type, cv_quals) == NULL_TREE
+	       || (get_qualified_type (type, cv_quals & ~TYPE_QUAL_RESTRICT)
+		   != NULL_TREE)))
     {
       mod_type_die = new_die (DW_TAG_restrict_type, mod_scope, type);
       sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_RESTRICT,
 				   context_die);
     }
+  else if (cv_quals & TYPE_QUAL_ATOMIC)
+    {
+      mod_type_die = new_die (DW_TAG_atomic_type, mod_scope, type);
+      sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_ATOMIC,
+				   context_die);
+    }
   else if (code == POINTER_TYPE)
     {
       mod_type_die = new_die (DW_TAG_pointer_type, mod_scope, type);
diff --git a/gcc/opts.c b/gcc/opts.c
index be1867c..f3f2817 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1884,7 +1884,7 @@ common_handle_option (struct gcc_options *opts,
       
       /* FALLTHRU */
     case OPT_gdwarf_:
-      if (value < 2 || value > 4)
+      if (value < 2 || value > 5)
 	error_at (loc, "dwarf version %d is not supported", value);
       else
 	opts->x_dwarf_version = value;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3f9e53f..4c8ce92 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-07-09  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/60782
+	* gcc.dg/guality/atomic.c: New test.
+
 2014-07-08  Mark Wielaard  <mjw@redhat.com>
 
 	PR debug/59051
diff --git a/gcc/testsuite/gcc.dg/guality/atomic.c b/gcc/testsuite/gcc.dg/guality/atomic.c
new file mode 100644
index 0000000..c76cfa4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/atomic.c
@@ -0,0 +1,13 @@
+/* debuginfo tests for the _Atomic type qualifier.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -gdwarf-5" } */
+
+volatile _Atomic int * const _Atomic hwaddr = (void *) 0x1234;
+
+int
+main (int argc, char **argv)
+{
+  return hwaddr == (void *) argv[0];
+}
+
+/* { dg-final { gdb-test 10 "type:hwaddr" "volatile _Atomic int * const _Atomic" } } */
diff --git a/include/ChangeLog b/include/ChangeLog
index 1cda0dc..2609e70 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2014-07-09  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/60782
+	* dwarf2.def: Add DWARFv5 DW_TAG_atomic_type.
+
 2014-06-10  Thomas Schwinge  <thomas@codesourcery.com>
 
 	PR lto/61334
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 71a37b3..6490391 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -133,6 +133,8 @@ DW_TAG (DW_TAG_shared_type, 0x40)
 DW_TAG (DW_TAG_type_unit, 0x41)
 DW_TAG (DW_TAG_rvalue_reference_type, 0x42)
 DW_TAG (DW_TAG_template_alias, 0x43)
+/* DWARF 5.  */
+DW_TAG (DW_TAG_atomic_type, 0x47) /* NOT AN OFFICIAL NUMBER. DWARF5 131112.1 */
 
 DW_TAG_DUP (DW_TAG_lo_user, 0x4080)
 DW_TAG_DUP (DW_TAG_hi_user, 0xffff)
-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2014-08-20 12:31 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-18 20:56 [PATCH] dwarf2out.c: Pass DWARF type modifiers around as flags argument Mark Wielaard
2014-06-20 11:51 ` Mark Wielaard
2014-06-20 23:02   ` [PATCH] Emit DW_tag_restrict_type for restrict-qualified pointers Mark Wielaard
2014-06-22  9:39     ` [PATCH] DWARFv5 Emit DW_TAG_atomic_type Mark Wielaard
2014-06-23 16:32       ` Tom Tromey
2014-06-23 17:12         ` Mark Wielaard
2014-07-08 16:39     ` [PATCH 1/2] dwarf2out.c: Pass one cv_quals argument instead of two for const and volatile Mark Wielaard
2014-07-09 21:36       ` [PATCH 1/2] DWARFv5 Emit DW_TAG_atomic_type Mark Wielaard
2014-07-09 21:36       ` Some DWARFv5 proposal prototypes (atomic_type, aligned_type) Mark Wielaard
2014-07-14 20:03         ` Tom Tromey
2014-07-15 11:57           ` Mark Wielaard
2014-07-15 20:55             ` Eric Christopher
2014-07-09 21:37       ` [PATCH 2/2] DWARF5: Add DW_TAG_aligned_type support Mark Wielaard
2014-07-08 16:39     ` [PATCH 2/2] Emit DW_tag_restrict_type for restrict-qualified pointers Mark Wielaard
2014-07-08 18:12       ` Mark Wielaard
2014-07-03  9:53   ` [PATCH] Add guality [p]type test Mark Wielaard
2014-07-03 10:05     ` Jakub Jelinek
2014-07-03 11:15       ` Mark Wielaard
2014-07-03 19:43         ` Tom Tromey
2014-07-07  9:58     ` Richard Biener
2014-08-19 11:06       ` Mark Wielaard
2014-08-19 11:23         ` Richard Biener
2014-08-19 12:10           ` Mark Wielaard
2014-08-19 12:16             ` Richard Biener
2014-08-19 17:52               ` Mark Wielaard
2014-08-20  8:49                 ` Richard Biener
2014-08-20 12:19                   ` Mark Wielaard
2014-08-20 12:31                     ` Richard Biener
2014-08-12 15:35 [PATCH 1/2] DWARFv5 Emit DW_TAG_atomic_type Mark Wielaard
2014-08-12 19:32 ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).