[12/24] pdbout: Handle type declarations and typedefs.

Message ID 20210320162652.23346-12-mark@harmstone.com
State New
Headers show
Series
  • [01/24] Add -gcodeview debugging option
Related show

Commit Message

Mark Harmstone March 20, 2021, 4:26 p.m.
---
 gcc/pdbout.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 gcc/pdbout.h | 22 +++++++++++++++
 2 files changed, 97 insertions(+), 1 deletion(-)

-- 
2.26.2

Patch

diff --git a/gcc/pdbout.c b/gcc/pdbout.c
index 8376b0e762c..5089203e339 100644
--- a/gcc/pdbout.c
+++ b/gcc/pdbout.c
@@ -55,6 +55,7 @@  static void pdbout_init (const char *filename);
 static void pdbout_finish (const char *filename);
 static void pdbout_begin_function (tree func);
 static void pdbout_late_global_decl (tree var);
+static void pdbout_type_decl (tree t, int local ATTRIBUTE_UNUSED);
 static void pdbout_start_source_file (unsigned int line ATTRIBUTE_UNUSED,
 				      const char *file);
 static void pdbout_source_line (unsigned int line,
@@ -80,6 +81,7 @@  static struct pdb_type *pointer_types = NULL;
 static struct pdb_type *proc_types = NULL;
 static struct pdb_type *modifier_types = NULL;
 static struct pdb_type *array_types = NULL;
+static struct pdb_alias *aliases = NULL;
 static struct pdb_source_file *source_files = NULL, *last_source_file = NULL;
 static uint32_t source_file_string_offset = 1;
 static unsigned int num_line_number_entries = 0;
@@ -98,6 +100,7 @@  static struct pdb_type *complex16_type, *complex32_type, *complex48_type,
   *complex64_type, *complex80_type, *complex128_type;
 static struct pdb_type *void_type, *nullptr_type;
 static bool builtins_initialized = false;
+static hash_table <alias_hasher> alias_hash_table (31);
 
 const struct gcc_debug_hooks pdb_debug_hooks = {
   pdbout_init,
@@ -122,7 +125,7 @@  const struct gcc_debug_hooks pdb_debug_hooks = {
   pdbout_function_decl,
   debug_nothing_tree,		/* early_global_decl */
   pdbout_late_global_decl,
-  debug_nothing_tree_int,	/* type_decl */
+  pdbout_type_decl,
   debug_nothing_tree_tree_tree_bool_bool,	/* imported_module_or_decl */
   debug_false_tree_charstarstar_uhwistar,	/* die_ref_for_decl */
   debug_nothing_tree_charstar_uhwi,	/* register_external_die */
@@ -999,6 +1002,17 @@  write_pdb_type_section (void)
 
       types = n;
     }
+
+  while (aliases)
+    {
+      struct pdb_alias *n;
+
+      n = aliases->next;
+
+      free (aliases);
+
+      aliases = n;
+    }
 }
 
 /* Loop through our types and assign them sequential numbers. */
@@ -1635,6 +1649,7 @@  static struct pdb_type *
 find_type (tree t)
 {
   struct pdb_type *type;
+  struct pdb_alias *al;
 
   if (!builtins_initialized)
     add_builtin_types ();
@@ -1642,6 +1657,13 @@  find_type (tree t)
   if (!t)
     return NULL;
 
+  // search through typedefs
+
+  al = alias_hash_table.find_with_hash (t, alias_hasher::hash (t));
+
+  if (al)
+    return al->type;
+
   // search through existing types
 
   type = tree_hash_table.find_with_hash (t, pdb_type_tree_hasher::hash (t));
@@ -1824,6 +1846,58 @@  find_type (tree t)
     }
 }
 
+inline hashval_t
+alias_hasher::hash (alias_hasher::compare_type tree)
+{
+  return htab_hash_pointer (tree);
+}
+
+inline bool
+alias_hasher::equal (const value_type type, compare_type tree)
+{
+  return type->tree == tree;
+}
+
+/* We've encountered a type definition - add it to the type list. */
+static void
+pdbout_type_decl (tree t, int local ATTRIBUTE_UNUSED)
+{
+  /* We need to record the typedefs to ensure e.g. that Windows'
+   * LPWSTR gets mapped to wchar_t* rather than uint16_t*.
+   * There is a LF_ALIAS / lfAlias in Microsoft's header files, but
+   * it seems to have been forgotten about - MSVC won't generate it. */
+
+  if (DECL_ORIGINAL_TYPE (t))	// typedef
+    {
+      struct pdb_alias *a, **slot;
+
+      a = (struct pdb_alias *) xmalloc (sizeof (struct pdb_alias));
+
+      a->next = aliases;
+      a->tree = TREE_TYPE (t);
+      a->type = find_type (DECL_ORIGINAL_TYPE (t));
+
+      // HRESULTs have their own value
+      if (a->type == long_type && DECL_NAME (t)
+	  && IDENTIFIER_POINTER (DECL_NAME (t))
+	  && !strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "HRESULT"))
+	a->type = hresult_type;
+
+      slot =
+	alias_hash_table.find_slot_with_hash (TREE_TYPE (t),
+					      htab_hash_pointer (TREE_TYPE
+								 (t)),
+					      INSERT);
+      *slot = a;
+
+      aliases = a;
+
+      return;
+    }
+
+  find_type (TREE_TYPE (t));
+}
+
 #ifndef _WIN32
 /* Given a Unix-style path, construct a fake Windows path, which is what windbg
  * and Visual Studio are expecting. This maps / to Z:\, which is the default
diff --git a/gcc/pdbout.h b/gcc/pdbout.h
index 412378a63ac..3e5ef8ca1a7 100644
--- a/gcc/pdbout.h
+++ b/gcc/pdbout.h
@@ -201,6 +201,13 @@  struct pdb_type
   uint8_t data[1];
 };
 
+struct pdb_alias
+{
+  struct pdb_alias *next;
+  tree_node *tree;
+  struct pdb_type *type;
+};
+
 #define CV_BUILTIN_TYPE_VOID			0x0003
 #define CV_BUILTIN_TYPE_HRESULT			0x0008
 #define CV_BUILTIN_TYPE_SIGNED_CHARACTER	0x0010
@@ -1222,4 +1229,19 @@  enum pdb_amd64_register
   CV_AMD64_YMM15D3 = 687
 };
 
+struct alias_hasher : nofree_ptr_hash <struct pdb_alias>
+{
+  typedef struct pdb_alias *value_type;
+  typedef tree compare_type;
+
+  static inline hashval_t hash (compare_type);
+
+  static inline hashval_t hash (const value_type t)
+  {
+    return hash (t->tree);
+  }
+
+  static inline bool equal (const value_type, compare_type);
+};
+
 #endif