Preserve relocs across def churning.

Freeing then re-allocating a def to change its storage from external is
really not the right way to do it, but for now this fixes the loss of the
relocs. With this, the menus seem to work :)
This commit is contained in:
Bill Currie 2011-03-09 10:52:29 +09:00
parent 39278ba8cc
commit 2464a89d37
4 changed files with 21 additions and 3 deletions

View file

@ -341,16 +341,21 @@ init_field_def (def_t *def, expr_t *init, storage_class_t storage)
type_t *type = def->type->t.fldptr.type;
def_t *field_def;
symbol_t *field_sym;
reloc_t *relocs = 0;
field_sym = symtab_lookup (pr.entity_fields, def->name);
if (!field_sym)
field_sym = new_symbol_type (def->name, type);
if (field_sym->s.def && field_sym->s.def->external) {
//FIXME this really is not the right way
relocs = field_sym->s.def->relocs;
free_def (field_sym->s.def);
field_sym->s.def = 0;
}
if (!field_sym->s.def)
if (!field_sym->s.def) {
field_sym->s.def = new_def (def->name, type, pr.entity_data, storage);
field_sym->s.def->relocs = relocs;
}
field_def = field_sym->s.def;
if (!field_sym->table)
symtab_addsymbol (pr.entity_fields, field_sym);
@ -372,6 +377,8 @@ initialize_def (symbol_t *sym, type_t *type, expr_t *init, defspace_t *space,
storage_class_t storage)
{
symbol_t *check = symtab_lookup (current_symtab, sym->name);
reloc_t *relocs = 0;
if (!type) {
warning (0, "type for %s defaults to %s", sym->name,
type_default->name);
@ -410,11 +417,15 @@ initialize_def (symbol_t *sym, type_t *type, expr_t *init, defspace_t *space,
return;
}
if (sym->s.def && sym->s.def->external) {
//FIXME this really is not the right way
relocs = sym->s.def->relocs;
free_def (sym->s.def);
sym->s.def = 0;
}
if (!sym->s.def)
if (!sym->s.def) {
sym->s.def = new_def (sym->name, type, space, storage);
sym->s.def->relocs = relocs;
}
if (type == &type_vector && options.code.vector_components)
init_vector_components (sym, 0);
if (type->type == ev_field && storage != st_local)

View file

@ -500,6 +500,7 @@ void
make_function (symbol_t *sym, const char *nice_name, defspace_t *space,
storage_class_t storage)
{
reloc_t *relocs = 0;
if (sym->sy_type != sy_func)
internal_error (0, "%s is not a function", sym->name);
if (storage == st_extern && sym->s.func)
@ -510,11 +511,15 @@ make_function (symbol_t *sym, const char *nice_name, defspace_t *space,
}
if (sym->s.func->def && sym->s.func->def->external
&& storage != st_extern) {
//FIXME this really is not the right way
relocs = sym->s.func->def->relocs;
free_def (sym->s.func->def);
sym->s.func->def = 0;
}
if (!sym->s.func->def)
if (!sym->s.func->def) {
sym->s.func->def = new_def (sym->name, sym->type, space, storage);
sym->s.func->def->relocs = relocs;
}
}
void

View file

@ -262,6 +262,7 @@ qfo_encode_type (type_t *type)
};
if (type->type_def && type->type_def->external) {
//FIXME relocs
free_def (type->type_def);
type->type_def = 0;
}

View file

@ -208,6 +208,7 @@ make_symbol (const char *name, type_t *type, defspace_t *space,
}
}
if (sym->s.def && sym->s.def->external && storage != st_extern) {
//FIXME this really is not the right way
relocs = sym->s.def->relocs;
free_def (sym->s.def);
sym->s.def = 0;