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