Handle external field declarations.

This commit is contained in:
Bill Currie 2011-03-07 17:23:52 +09:00
parent 49e446b637
commit 7649549de6

View file

@ -287,43 +287,84 @@ static void
init_vector_components (symbol_t *vector_sym, int is_field) init_vector_components (symbol_t *vector_sym, int is_field)
{ {
expr_t *vector_expr; expr_t *vector_expr;
expr_t *expr; expr_t *expr = 0;
symbol_t *sym; symbol_t *sym;
int i; int i;
const char *name;
static const char *fields[] = { "x", "y", "z" }; static const char *fields[] = { "x", "y", "z" };
vector_expr = new_symbol_expr (vector_sym); vector_expr = new_symbol_expr (vector_sym);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
name = va ("%s_%s", vector_sym->name, fields[i]);
sym = symtab_lookup (current_symtab, name);
if (sym) {
if (sym->table == current_symtab) {
if (sym->sy_type != sy_expr) {
error (0, "%s redefined", name);
sym = 0;
} else {
expr = sym->s.expr;
if (is_field) {
if (expr->type != ex_value
|| expr->e.value.type != ev_field) {
error (0, "%s redefined", name);
sym = 0;
} else {
expr->e.value.v.pointer.def = vector_sym->s.def;
}
}
}
} else {
sym = 0;
}
}
if (!sym)
sym = new_symbol (name);
if (!expr) {
if (is_field) { if (is_field) {
expr = new_field_expr (i, &type_float, vector_sym->s.def); expr = new_field_expr (i, &type_float, vector_sym->s.def);
} else { } else {
expr = binary_expr ('.', vector_expr, expr = binary_expr ('.', vector_expr,
new_symbol_expr (new_symbol (fields[i]))); new_symbol_expr (new_symbol (fields[i])));
} }
sym = new_symbol (va ("%s_%s", vector_sym->name, fields[i])); }
sym->sy_type = sy_expr; sym->sy_type = sy_expr;
sym->s.expr = expr; sym->s.expr = expr;
if (!sym->table)
symtab_addsymbol (current_symtab, sym); symtab_addsymbol (current_symtab, sym);
} }
} }
static void static void
init_field_def (def_t *def) init_field_def (def_t *def, expr_t *init, storage_class_t storage)
{ {
type_t *type = def->type->t.fldptr.type; type_t *type = def->type->t.fldptr.type;
def_t *field_def; def_t *field_def;
symbol_t *field_sym; symbol_t *field_sym;
field_sym = symtab_lookup (pr.entity_fields, def->name);
if (!field_sym)
field_sym = new_symbol_type (def->name, type); field_sym = new_symbol_type (def->name, type);
field_def = new_def (def->name, type, pr.entity_data, st_global); if (field_sym->s.def && field_sym->s.def->external) {
field_sym->s.def = field_def; free_def (field_sym->s.def);
field_sym->s.def = 0;
}
if (!field_sym->s.def)
field_sym->s.def = new_def (def->name, type, pr.entity_data, storage);
field_def = field_sym->s.def;
if (!field_sym->table)
symtab_addsymbol (pr.entity_fields, field_sym); symtab_addsymbol (pr.entity_fields, field_sym);
if (!init) {
if (storage != st_extern) {
D_INT (def) = field_def->offset; D_INT (def) = field_def->offset;
reloc_def_field (def, field_def); reloc_def_field (def, field_def);
def->constant = 1; def->constant = 1;
def->nosave = 1; def->nosave = 1;
}
// no support for initialized field vector componets (yet?)
if (type == &type_vector && options.code.vector_components) if (type == &type_vector && options.code.vector_components)
init_vector_components (field_sym, 1); init_vector_components (field_sym, 1);
}
} }
void void
@ -376,16 +417,15 @@ initialize_def (symbol_t *sym, type_t *type, expr_t *init, defspace_t *space,
sym->s.def = new_def (sym->name, type, space, storage); sym->s.def = new_def (sym->name, type, space, storage);
if (type == &type_vector && options.code.vector_components) if (type == &type_vector && options.code.vector_components)
init_vector_components (sym, 0); init_vector_components (sym, 0);
if (type->type == ev_field)
init_field_def (sym->s.def, init, storage);
if (storage == st_extern) { if (storage == st_extern) {
if (init) if (init)
warning (0, "initializing external variable"); warning (0, "initializing external variable");
return; return;
} }
if (!init) { if (!init)
if (type->type == ev_field)
init_field_def (sym->s.def);
return; return;
}
convert_name (init); convert_name (init);
if (init->type == ex_error) if (init->type == ex_error)
return; return;