[PATCH 12/24] pdbout: Handle type declarations and typedefs.
Mark Harmstone
mark@harmstone.com
Sat Mar 20 16:26:40 GMT 2021
---
gcc/pdbout.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++-
gcc/pdbout.h | 22 +++++++++++++++
2 files changed, 97 insertions(+), 1 deletion(-)
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
--
2.26.2
More information about the Gcc-patches
mailing list