Patchwork [1/8] gdb: recognize new DWARF attributes: defaulted, deleted, calling conv.

login
register
mail settings
Submitter Tankut Baris Aktemur
Date April 23, 2019, 2:31 p.m.
Message ID <1556029914-21250-2-git-send-email-tankut.baris.aktemur@intel.com>
Download mbox | patch
Permalink /patch/32384/
State New
Headers show

Comments

Tankut Baris Aktemur - April 23, 2019, 2:31 p.m.
Extend GDB's internal representation of types to include the
DW_AT_calling_convention, DW_AT_defaulted, and DW_AT_deleted attributes
that were introduced in DWARF5.

gdb/ChangeLog:

	* dwarf2read.c (dwarf2_add_member_fn): Read the DW_AT_defaulted
	and DW_AT_deleted attributes of a function.
	(read_structure_type): Read the	DW_AT_calling_convention attribute
	of a type.
	* gdbtypes.h (struct fn_field)<defaulted>: New field to store the
	DW_AT_defaulted attribute.
	(struct fn_field)<is_deleted>: New field to store the DW_AT_deleted
	attribute.
	(struct cplus_struct_type)<calling_convention>: New field to store
	the DW_AT_calling_convention attribute.
	(TYPE_FN_FIELD_DEFAULTED): New macro.
	(TYPE_FN_FIELD_DELETED): New macro.
	(TYPE_CPLUS_CALLING_CONVENTION): New macro.
	* gdbtypes.c:  (dump_fn_fieldlists): Update for the changes made
	to the .h file.
	(print_cplus_stuff): Likewise.

---
 gdb/dwarf2read.c | 20 ++++++++++++++++++++
 gdb/gdbtypes.c   |  7 +++++++
 gdb/gdbtypes.h   | 19 ++++++++++++++++++-
 3 files changed, 45 insertions(+), 1 deletion(-)
Andrew Burgess - April 23, 2019, 9:40 p.m.
* Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> [2019-04-23 16:31:47 +0200]:

> Extend GDB's internal representation of types to include the
> DW_AT_calling_convention, DW_AT_defaulted, and DW_AT_deleted attributes
> that were introduced in DWARF5.
> 
> gdb/ChangeLog:
> 
> 	* dwarf2read.c (dwarf2_add_member_fn): Read the DW_AT_defaulted
> 	and DW_AT_deleted attributes of a function.
> 	(read_structure_type): Read the	DW_AT_calling_convention attribute
> 	of a type.
> 	* gdbtypes.h (struct fn_field)<defaulted>: New field to store the
> 	DW_AT_defaulted attribute.
> 	(struct fn_field)<is_deleted>: New field to store the DW_AT_deleted
> 	attribute.
> 	(struct cplus_struct_type)<calling_convention>: New field to store
> 	the DW_AT_calling_convention attribute.
> 	(TYPE_FN_FIELD_DEFAULTED): New macro.
> 	(TYPE_FN_FIELD_DELETED): New macro.
> 	(TYPE_CPLUS_CALLING_CONVENTION): New macro.
> 	* gdbtypes.c:  (dump_fn_fieldlists): Update for the changes made
> 	to the .h file.
> 	(print_cplus_stuff): Likewise.

This looks good to me, with a couple of requests for extended
comments, see below...

> 
> ---
>  gdb/dwarf2read.c | 20 ++++++++++++++++++++
>  gdb/gdbtypes.c   |  7 +++++++
>  gdb/gdbtypes.h   | 19 ++++++++++++++++++-
>  3 files changed, 45 insertions(+), 1 deletion(-)
> 
> diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
> index 829b07f01ac..435f234f2c9 100644
> --- a/gdb/dwarf2read.c
> +++ b/gdb/dwarf2read.c
> @@ -15539,6 +15539,16 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
>    if (attr && DW_UNSND (attr) != 0)
>      fnp->is_artificial = 1;
>  
> +  /* Check for defaulted methods.  */
> +  attr = dwarf2_attr (die, DW_AT_defaulted, cu);
> +  if (attr)
> +    fnp->defaulted = DW_UNSND (attr);
> +
> +  /* Check for deleted methods.  */
> +  attr = dwarf2_attr (die, DW_AT_deleted, cu);
> +  if (attr && DW_UNSND (attr) != 0)
> +    fnp->is_deleted = 1;
> +
>    fnp->is_constructor = dwarf2_is_constructor (die, cu);
>  
>    /* Get index in virtual function table if it is a virtual member
> @@ -15859,6 +15869,16 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>    if (cu->language == language_cplus && die->tag == DW_TAG_class_type)
>      TYPE_DECLARED_CLASS (type) = 1;
>  
> +  /* Store the calling convention in the type if it's available in
> +     the die.  Otherwise the calling convention remains set to
> +     the default value DW_CC_normal.  */
> +  attr = dwarf2_attr (die, DW_AT_calling_convention, cu);
> +  if (attr)
> +    {
> +      ALLOCATE_CPLUS_STRUCT_TYPE (type);
> +      TYPE_CPLUS_CALLING_CONVENTION (type) = DW_UNSND (attr);
> +    }
> +
>    attr = dwarf2_attr (die, DW_AT_byte_size, cu);
>    if (attr)
>      {
> diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
> index b3424d81be4..b32f13189a9 100644
> --- a/gdb/gdbtypes.c
> +++ b/gdb/gdbtypes.c
> @@ -4389,6 +4389,10 @@ dump_fn_fieldlists (struct type *type, int spaces)
>  			    TYPE_FN_FIELD_PROTECTED (f, overload_idx));
>  	  printfi_filtered (spaces + 8, "is_stub %d\n",
>  			    TYPE_FN_FIELD_STUB (f, overload_idx));
> +	  printfi_filtered (spaces + 8, "defaulted %d\n",
> +			    TYPE_FN_FIELD_DEFAULTED (f, overload_idx));
> +	  printfi_filtered (spaces + 8, "is_deleted %d\n",
> +			    TYPE_FN_FIELD_DELETED (f, overload_idx));
>  	  printfi_filtered (spaces + 8, "voffset %u\n",
>  			    TYPE_FN_FIELD_VOFFSET (f, overload_idx));
>  	}
> @@ -4452,6 +4456,9 @@ print_cplus_stuff (struct type *type, int spaces)
>      {
>        dump_fn_fieldlists (type, spaces);
>      }
> +
> +  printfi_filtered (spaces, "calling_convention %d\n",
> +		    TYPE_CPLUS_CALLING_CONVENTION (type));
>  }
>  
>  /* Print the contents of the TYPE's type_specific union, assuming that
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
> index 147a2de355e..3c7846a0e18 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -915,6 +915,10 @@ struct fn_field
>  
>    struct type *fcontext;
>  
> +  /* * DW_AT_defaulted attribute.  */

Taking inspiration from how 'calling_convention' is commented in the
'struct func_type', it would be nice if this comment mentioned what
values can be expected here, something like:

  /* * The DW_AT_defaulted attribute for this function, the value is one
     of the DW_DEFAULTED enum dwarf_defaulted_attribute constants.  */

> +
> +  unsigned int defaulted;
> +
>    /* Attributes.  */
>  
>    unsigned int is_const:1;
> @@ -932,9 +936,13 @@ struct fn_field
>  
>    unsigned int is_constructor : 1;
>  
> +  /* * True if this function is deleted, false otherwise.  */
> +
> +  unsigned int is_deleted : 1;
> +
>    /* * Unused.  */
>  
> -  unsigned int dummy:9;
> +  unsigned int dummy:8;
>  
>    /* * Index into that baseclass's virtual function table, minus 2;
>       else if static: VOFFSET_STATIC; else: 0.  */
> @@ -1076,6 +1084,11 @@ struct cplus_struct_type
>         classes.  */
>  
>      struct symbol **template_arguments;
> +
> +    /* * The calling convention for this type, fetched from the
> +       DW_AT_calling_convention attribute.  */

Similarly it would be nice to include a comment about which values are
valid here, something like:

    /* * The calling convention for this type, fetched from the
       DW_AT_calling_convention attribute.  The value is one of the
       DW_CC enum dwarf_calling_convention constants.*/


thanks,
Andrew

> +
> +    unsigned calling_convention : 8;
>    };
>  
>  /* * Struct used to store conversion rankings.  */
> @@ -1405,6 +1418,8 @@ extern void set_type_vptr_basetype (struct type *, struct type *);
>      ? (struct cplus_struct_type*)&cplus_struct_default \
>      : TYPE_RAW_CPLUS_SPECIFIC(thistype))
>  #define TYPE_RAW_CPLUS_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff
> +#define TYPE_CPLUS_CALLING_CONVENTION(thistype) \
> +  TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff->calling_convention
>  #define TYPE_FLOATFORMAT(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.floatformat
>  #define TYPE_GNAT_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.gnat_stuff
>  #define TYPE_DESCRIPTIVE_TYPE(thistype) TYPE_GNAT_SPECIFIC(thistype)->descriptive_type
> @@ -1521,6 +1536,8 @@ extern void set_type_vptr_basetype (struct type *, struct type *);
>  #define TYPE_FN_FIELD_VOFFSET(thisfn, n) ((thisfn)[n].voffset-2)
>  #define TYPE_FN_FIELD_VIRTUAL_P(thisfn, n) ((thisfn)[n].voffset > 1)
>  #define TYPE_FN_FIELD_STATIC_P(thisfn, n) ((thisfn)[n].voffset == VOFFSET_STATIC)
> +#define TYPE_FN_FIELD_DEFAULTED(thisfn, n) ((thisfn)[n].defaulted)
> +#define TYPE_FN_FIELD_DELETED(thisfn, n) ((thisfn)[n].is_deleted)
>  
>  /* Accessors for typedefs defined by a class.  */
>  #define TYPE_TYPEDEF_FIELD_ARRAY(thistype) \
> -- 
> 2.21.0
>

Patch

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 829b07f01ac..435f234f2c9 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -15539,6 +15539,16 @@  dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   if (attr && DW_UNSND (attr) != 0)
     fnp->is_artificial = 1;
 
+  /* Check for defaulted methods.  */
+  attr = dwarf2_attr (die, DW_AT_defaulted, cu);
+  if (attr)
+    fnp->defaulted = DW_UNSND (attr);
+
+  /* Check for deleted methods.  */
+  attr = dwarf2_attr (die, DW_AT_deleted, cu);
+  if (attr && DW_UNSND (attr) != 0)
+    fnp->is_deleted = 1;
+
   fnp->is_constructor = dwarf2_is_constructor (die, cu);
 
   /* Get index in virtual function table if it is a virtual member
@@ -15859,6 +15869,16 @@  read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
   if (cu->language == language_cplus && die->tag == DW_TAG_class_type)
     TYPE_DECLARED_CLASS (type) = 1;
 
+  /* Store the calling convention in the type if it's available in
+     the die.  Otherwise the calling convention remains set to
+     the default value DW_CC_normal.  */
+  attr = dwarf2_attr (die, DW_AT_calling_convention, cu);
+  if (attr)
+    {
+      ALLOCATE_CPLUS_STRUCT_TYPE (type);
+      TYPE_CPLUS_CALLING_CONVENTION (type) = DW_UNSND (attr);
+    }
+
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index b3424d81be4..b32f13189a9 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -4389,6 +4389,10 @@  dump_fn_fieldlists (struct type *type, int spaces)
 			    TYPE_FN_FIELD_PROTECTED (f, overload_idx));
 	  printfi_filtered (spaces + 8, "is_stub %d\n",
 			    TYPE_FN_FIELD_STUB (f, overload_idx));
+	  printfi_filtered (spaces + 8, "defaulted %d\n",
+			    TYPE_FN_FIELD_DEFAULTED (f, overload_idx));
+	  printfi_filtered (spaces + 8, "is_deleted %d\n",
+			    TYPE_FN_FIELD_DELETED (f, overload_idx));
 	  printfi_filtered (spaces + 8, "voffset %u\n",
 			    TYPE_FN_FIELD_VOFFSET (f, overload_idx));
 	}
@@ -4452,6 +4456,9 @@  print_cplus_stuff (struct type *type, int spaces)
     {
       dump_fn_fieldlists (type, spaces);
     }
+
+  printfi_filtered (spaces, "calling_convention %d\n",
+		    TYPE_CPLUS_CALLING_CONVENTION (type));
 }
 
 /* Print the contents of the TYPE's type_specific union, assuming that
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 147a2de355e..3c7846a0e18 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -915,6 +915,10 @@  struct fn_field
 
   struct type *fcontext;
 
+  /* * DW_AT_defaulted attribute.  */
+
+  unsigned int defaulted;
+
   /* Attributes.  */
 
   unsigned int is_const:1;
@@ -932,9 +936,13 @@  struct fn_field
 
   unsigned int is_constructor : 1;
 
+  /* * True if this function is deleted, false otherwise.  */
+
+  unsigned int is_deleted : 1;
+
   /* * Unused.  */
 
-  unsigned int dummy:9;
+  unsigned int dummy:8;
 
   /* * Index into that baseclass's virtual function table, minus 2;
      else if static: VOFFSET_STATIC; else: 0.  */
@@ -1076,6 +1084,11 @@  struct cplus_struct_type
        classes.  */
 
     struct symbol **template_arguments;
+
+    /* * The calling convention for this type, fetched from the
+       DW_AT_calling_convention attribute.  */
+
+    unsigned calling_convention : 8;
   };
 
 /* * Struct used to store conversion rankings.  */
@@ -1405,6 +1418,8 @@  extern void set_type_vptr_basetype (struct type *, struct type *);
     ? (struct cplus_struct_type*)&cplus_struct_default \
     : TYPE_RAW_CPLUS_SPECIFIC(thistype))
 #define TYPE_RAW_CPLUS_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff
+#define TYPE_CPLUS_CALLING_CONVENTION(thistype) \
+  TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff->calling_convention
 #define TYPE_FLOATFORMAT(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.floatformat
 #define TYPE_GNAT_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.gnat_stuff
 #define TYPE_DESCRIPTIVE_TYPE(thistype) TYPE_GNAT_SPECIFIC(thistype)->descriptive_type
@@ -1521,6 +1536,8 @@  extern void set_type_vptr_basetype (struct type *, struct type *);
 #define TYPE_FN_FIELD_VOFFSET(thisfn, n) ((thisfn)[n].voffset-2)
 #define TYPE_FN_FIELD_VIRTUAL_P(thisfn, n) ((thisfn)[n].voffset > 1)
 #define TYPE_FN_FIELD_STATIC_P(thisfn, n) ((thisfn)[n].voffset == VOFFSET_STATIC)
+#define TYPE_FN_FIELD_DEFAULTED(thisfn, n) ((thisfn)[n].defaulted)
+#define TYPE_FN_FIELD_DELETED(thisfn, n) ((thisfn)[n].is_deleted)
 
 /* Accessors for typedefs defined by a class.  */
 #define TYPE_TYPEDEF_FIELD_ARRAY(thistype) \