--- gcc/pdbout.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/pdbout.h | 11 +++++++ 2 files changed, 96 insertions(+)
diff --git a/gcc/pdbout.c b/gcc/pdbout.c index 08bb14364e5..fa3b1fb0312 100644 --- a/gcc/pdbout.c +++ b/gcc/pdbout.c @@ -78,6 +78,7 @@ static struct pdb_type *types = NULL, *last_type = NULL; static struct pdb_type *arglist_types = NULL; static struct pdb_type *pointer_types = NULL; static struct pdb_type *proc_types = NULL; +static struct pdb_type *modifier_types = 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; @@ -863,6 +864,19 @@ write_procedure (struct pdb_proc *proc) fprintf (asm_out_file, "\t.short\t0\n"); // padding } +/* Output lfModifier structure, representing a const or volatile version + * of an existing type. */ +static void +write_modifier (struct pdb_modifier *t) +{ + fprintf (asm_out_file, "\t.short\t0xa\n"); + fprintf (asm_out_file, "\t.short\t0x%x\n", LF_MODIFIER); + fprintf (asm_out_file, "\t.short\t0x%x\n", t->type ? t->type->id : 0); + fprintf (asm_out_file, "\t.short\t0\n"); // padding + fprintf (asm_out_file, "\t.short\t0x%x\n", t->modifier); + fprintf (asm_out_file, "\t.short\t0\n"); // padding +} + /* Given a pdb_type, output its definition. */ static void write_type (struct pdb_type *t) @@ -883,6 +897,10 @@ write_type (struct pdb_type *t) case LF_PROCEDURE: write_procedure ((struct pdb_proc *) t->data); break; + + case LF_MODIFIER: + write_modifier ((struct pdb_modifier *) t->data); + break; } } @@ -1318,6 +1336,68 @@ find_type_function (tree t) return proctype; } +/* Given a CV-modified type t, allocate a new pdb_type modifying + * the base type, and add it to the type list. */ +static struct pdb_type * +find_type_modifier (tree t) +{ + struct pdb_type *type, *last_entry = NULL, *base_type; + struct pdb_modifier *mod; + uint16_t modifier = 0; + struct pdb_type **slot; + + base_type = find_type (TYPE_MAIN_VARIANT (t)); + + if (TYPE_READONLY (t)) + modifier |= CV_MODIFIER_CONST; + + if (TYPE_VOLATILE (t)) + modifier |= CV_MODIFIER_VOLATILE; + + type = modifier_types; + while (type) + { + mod = (struct pdb_modifier *) type->data; + + if (mod->type == base_type && mod->modifier == modifier) + return type; + + last_entry = type; + type = type->next2; + } + + type = + (struct pdb_type *) xmalloc (offsetof (struct pdb_type, data) + + sizeof (struct pdb_modifier)); + type->cv_type = LF_MODIFIER; + type->tree = t; + type->next = type->next2 = NULL; + type->id = 0; + + mod = (struct pdb_modifier *) type->data; + + mod->type = base_type; + mod->modifier = modifier; + + if (last_entry) + last_entry->next2 = type; + else + modifier_types = type; + + if (last_type) + last_type->next = type; + else + types = type; + + last_type = type; + + slot = + tree_hash_table.find_slot_with_hash (t, htab_hash_pointer (t), INSERT); + *slot = type; + + return type; +} + inline hashval_t pdb_type_tree_hasher::hash (pdb_type_tree_hasher::compare_type tree) { @@ -1439,6 +1519,11 @@ find_type (tree t) if (type) return type; + // add modifier type if const or volatile + + if (TYPE_READONLY (t) || TYPE_VOLATILE (t)) + return find_type_modifier (t); + switch (TREE_CODE (t)) { case INTEGER_TYPE: diff --git a/gcc/pdbout.h b/gcc/pdbout.h index a660728158e..1fa2b1ab2fa 100644 --- a/gcc/pdbout.h +++ b/gcc/pdbout.h @@ -21,6 +21,7 @@ #define GCC_PDBOUT_H 1 #define S_END 0x0006 +#define LF_MODIFIER 0x1001 #define LF_POINTER 0x1002 #define LF_PROCEDURE 0x1008 #define S_BLOCK32 0x1103 @@ -262,6 +263,16 @@ struct pdb_source_file char name[1]; }; +#define CV_MODIFIER_CONST 0x1 +#define CV_MODIFIER_VOLATILE 0x2 +#define CV_MODIFIER_UNALIGNED 0x4 + +struct pdb_modifier +{ + struct pdb_type *type; + uint16_t modifier; +}; + enum pdb_x86_register { CV_X86_NONE = 0, -- 2.26.2