diff mbox series

[15/24] pdbout: Output definitions of unions.

Message ID 20210320162652.23346-15-mark@harmstone.com
State New
Headers show
Series [01/24] Add -gcodeview debugging option | expand

Commit Message

Mark Harmstone March 20, 2021, 4:26 p.m. UTC
---
 gcc/pdbout.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++-----
 gcc/pdbout.h |  1 +
 2 files changed, 57 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/gcc/pdbout.c b/gcc/pdbout.c
index 3bfec519877..7d493513e06 100644
--- a/gcc/pdbout.c
+++ b/gcc/pdbout.c
@@ -829,6 +829,7 @@  free_type (struct pdb_type *t)
 
     case LF_CLASS:
     case LF_STRUCTURE:
+    case LF_UNION:
       {
 	struct pdb_struct *str = (struct pdb_struct *) t->data;
 
@@ -1097,6 +1098,44 @@  write_struct (uint16_t type, struct pdb_struct *str)
     }
 }
 
+/* Output a lfUnion structure. */
+static void
+write_union (struct pdb_struct *str)
+{
+  size_t name_len = str->name ? strlen (str->name) : (sizeof (unnamed) - 1);
+  unsigned int len = 15 + name_len, align;
+
+  if (len % 4 != 0)
+    len += 4 - (len % 4);
+
+  fprintf (asm_out_file, "\t.short\t0x%x\n", len - 2);
+  fprintf (asm_out_file, "\t.short\t0x%x\n", LF_UNION);
+  fprintf (asm_out_file, "\t.short\t0x%x\n", str->count);
+  fprintf (asm_out_file, "\t.short\t0x%x\n", str->property.value);
+  fprintf (asm_out_file, "\t.short\t0x%x\n",
+	   str->field_type ? str->field_type->id : 0);
+  fprintf (asm_out_file, "\t.short\t0\n");
+  fprintf (asm_out_file, "\t.short\t0x%x\n", str->size);
+
+  if (str->name)
+    ASM_OUTPUT_ASCII (asm_out_file, str->name, name_len + 1);
+  else
+    ASM_OUTPUT_ASCII (asm_out_file, unnamed, sizeof (unnamed));
+
+  align = 4 - ((3 + name_len) % 4);
+
+  if (align != 4)
+    {
+      if (align == 3)
+	fprintf (asm_out_file, "\t.byte\t0xf3\n");
+
+      if (align >= 2)
+	fprintf (asm_out_file, "\t.byte\t0xf2\n");
+
+      fprintf (asm_out_file, "\t.byte\t0xf1\n");
+    }
+}
+
 /* Output a lfEnum structure. */
 static void
 write_enum (struct pdb_enum *en)
@@ -1288,6 +1327,10 @@  write_type (struct pdb_type *t)
       write_struct (t->cv_type, (struct pdb_struct *) t->data);
       break;
 
+    case LF_UNION:
+      write_union ((struct pdb_struct *) t->data);
+      break;
+
     case LF_ENUM:
       write_enum ((struct pdb_enum *) t->data);
       break;
@@ -1679,10 +1722,10 @@  struct_hasher::equal (const value_type type, compare_type name)
   return !strcmp (str->name, name);
 }
 
-/* For a given struct or class, allocate a new pdb_type and
+/* For a given struct, class, or union, allocate a new pdb_type and
  * add it to the type list. */
 static struct pdb_type *
-find_type_struct (tree t)
+find_type_struct (tree t, bool is_union)
 {
   tree f;
   struct pdb_type *fltype = NULL, *strtype, *fwddef = NULL,
@@ -1729,7 +1772,8 @@  find_type_struct (tree t)
 
 	      if (type
 		  && (type->cv_type == LF_CLASS
-		      || type->cv_type == LF_STRUCTURE))
+		      || type->cv_type == LF_STRUCTURE
+		      || type->cv_type == LF_UNION))
 		{
 		  struct pdb_struct *str2 = (struct pdb_struct *) type->data;
 
@@ -1811,7 +1855,8 @@  find_type_struct (tree t)
 
 		  if (type
 		      && (type->cv_type == LF_CLASS
-			  || type->cv_type == LF_STRUCTURE))
+			  || type->cv_type == LF_STRUCTURE
+			  || type->cv_type == LF_UNION))
 		    {
 		      struct pdb_struct *str2 =
 			(struct pdb_struct *) type->data;
@@ -1880,7 +1925,9 @@  find_type_struct (tree t)
     (struct pdb_type *) xmalloc (offsetof (struct pdb_type, data) +
 				 sizeof (struct pdb_struct));
 
-  if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
+  if (is_union)
+    strtype->cv_type = LF_UNION;
+  else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
     strtype->cv_type = LF_CLASS;
   else
     strtype->cv_type = LF_STRUCTURE;
@@ -2744,7 +2791,10 @@  find_type (tree t)
       return find_type_array (t);
 
     case RECORD_TYPE:
-      return find_type_struct (t);
+      return find_type_struct (t, false);
+
+    case UNION_TYPE:
+      return find_type_struct (t, true);
 
     case ENUMERAL_TYPE:
       return find_type_enum (t);
diff --git a/gcc/pdbout.h b/gcc/pdbout.h
index 96288d235ea..09b3914d650 100644
--- a/gcc/pdbout.h
+++ b/gcc/pdbout.h
@@ -41,6 +41,7 @@ 
 #define LF_ARRAY			0x1503
 #define LF_CLASS			0x1504
 #define LF_STRUCTURE			0x1505
+#define LF_UNION			0x1506
 #define LF_ENUM				0x1507
 #define LF_MEMBER			0x150d
 #define LF_CHAR				0x8000