- Error on function prototypes

- Fix a last couple of structure related bugs


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@914 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Eric Biederman
2003-06-25 10:38:10 +00:00
parent 0f28460efb
commit 3a51f3bc5e
3 changed files with 518 additions and 44 deletions

View File

@@ -751,7 +751,6 @@ struct compile_state {
const char *label_prefix;
const char *ofilename;
FILE *output;
struct triple *vars;
struct file_state *file;
struct occurance *last_occurance;
const char *function;
@@ -4010,25 +4009,26 @@ static size_t size_of(struct compile_state *state, struct type *type)
static size_t field_offset(struct compile_state *state,
struct type *type, struct hash_entry *field)
{
struct type *member;
size_t size, align;
if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
internal_error(state, 0, "field_offset only works on structures");
}
size = 0;
type = type->left;
while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
align = align_of(state, type->left);
member = type->left;
while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
align = align_of(state, member->left);
size += needed_padding(size, align);
if (type->left->field_ident == field) {
type = type->left;
if (member->left->field_ident == field) {
member = member->left;
break;
}
size += size_of(state, type->left);
type = type->right;
size += size_of(state, member->left);
member = member->right;
}
align = align_of(state, type);
align = align_of(state, member);
size += needed_padding(size, align);
if (type->field_ident != field) {
if (member->field_ident != field) {
error(state, 0, "member %s not present", field->name);
}
return size;
@@ -4037,48 +4037,50 @@ static size_t field_offset(struct compile_state *state,
static struct type *field_type(struct compile_state *state,
struct type *type, struct hash_entry *field)
{
struct type *member;
if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
internal_error(state, 0, "field_type only works on structures");
}
type = type->left;
while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
if (type->left->field_ident == field) {
type = type->left;
member = type->left;
while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
if (member->left->field_ident == field) {
member = member->left;
break;
}
type = type->right;
member = member->right;
}
if (type->field_ident != field) {
if (member->field_ident != field) {
error(state, 0, "member %s not present", field->name);
}
return type;
return member;
}
static struct type *next_field(struct compile_state *state,
struct type *type, struct type *prev_member)
{
struct type *member;
if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
internal_error(state, 0, "next_field only works on structures");
}
type = type->left;
while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
member = type->left;
while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
if (!prev_member) {
type = type->left;
member = member->left;
break;
}
if (type->left == prev_member) {
if (member->left == prev_member) {
prev_member = 0;
}
type = type->right;
member = member->right;
}
if (type == prev_member) {
if (member == prev_member) {
prev_member = 0;
}
if (prev_member) {
internal_error(state, 0, "prev_member %s not present",
prev_member->field_ident->name);
}
return type;
return member;
}
static struct triple *struct_field(struct compile_state *state,
@@ -4477,6 +4479,8 @@ static struct triple *do_mk_addr_expr(struct compile_state *state,
struct triple *result;
clvalue(state, expr);
type = new_type(TYPE_POINTER | (type->type & QUAL_MASK), type, 0);
result = 0;
if (expr->op == OP_ADECL) {
error(state, expr, "address of auto variables not supported");
@@ -4497,13 +4501,7 @@ static struct triple *do_mk_addr_expr(struct compile_state *state,
static struct triple *mk_addr_expr(
struct compile_state *state, struct triple *expr, ulong_t offset)
{
struct type *type;
type = new_type(
TYPE_POINTER | (expr->type->type & QUAL_MASK),
expr->type, 0);
return do_mk_addr_expr(state, expr, type, offset);
return do_mk_addr_expr(state, expr, expr->type, offset);
}
static struct triple *mk_deref_expr(
@@ -4515,6 +4513,21 @@ static struct triple *mk_deref_expr(
return triple(state, OP_DEREF, base_type, expr, 0);
}
static struct triple *array_to_pointer(struct compile_state *state, struct triple *def)
{
if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
struct type *type;
struct triple *addrconst;
type = new_type(
TYPE_POINTER | (def->type->type & QUAL_MASK),
def->type->left, 0);
addrconst = triple(state, OP_ADDRCONST, type, 0, 0);
MISC(addrconst, 0) = def;
def = addrconst;
}
return def;
}
static struct triple *deref_field(
struct compile_state *state, struct triple *expr, struct hash_entry *field)
{
@@ -4555,16 +4568,10 @@ static struct triple *read_expr(struct compile_state *state, struct triple *def)
return def;
}
/* Tranform an array to a pointer to the first element */
#warning "CHECK_ME is this the right place to transform arrays to pointers?"
if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
struct type *type;
struct triple *result;
type = new_type(
TYPE_POINTER | (def->type->type & QUAL_MASK),
def->type->left, 0);
result = triple(state, OP_ADDRCONST, type, 0, 0);
MISC(result, 0) = def;
return result;
return array_to_pointer(state, def);
}
if (is_in_reg(state, def)) {
op = OP_READ;
@@ -8441,14 +8448,14 @@ static struct type *struct_or_union_specifier(
}
if (!ident || (peek(state) == TOK_LBRACE)) {
ulong_t elements;
struct type **next;
elements = 0;
eat(state, TOK_LBRACE);
next = &struct_type;
do {
struct type *base_type;
struct type **next;
int done;
base_type = specifier_qualifier_list(state);
next = &struct_type;
do {
struct type *type;
struct hash_entry *fident;
@@ -9107,6 +9114,9 @@ static struct triple *do_decl(struct compile_state *state,
default:
internal_error(state, 0, "Undefined storage class");
}
if ((type->type & TYPE_MASK) == TYPE_FUNCTION) {
error(state, 0, "Function prototypes not supported");
}
if (ident &&
((type->type & STOR_MASK) == STOR_STATIC) &&
((type->type & QUAL_CONST) == 0)) {