From 7b2721ff07f901741f56e22baec0628ca5e4016b Mon Sep 17 00:00:00 2001 From: bellard Date: Sun, 24 Nov 2002 14:18:17 +0000 Subject: [PATCH] added empty structs support - changed double align to 4 (i386 default ABI) - added align support for structs - added GCC defines for basic types --- tcc.c | 98 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 59 insertions(+), 39 deletions(-) diff --git a/tcc.c b/tcc.c index e4a85cb7..53da6d53 100644 --- a/tcc.c +++ b/tcc.c @@ -587,7 +587,7 @@ static Sym *sym_find(int v); static Sym *sym_push(int v, CType *type, int r, int c); /* type handling */ -int type_size(CType *type, int *a); +static int type_size(CType *type, int *a); static inline CType *pointed_type(CType *type); static int pointed_size(CType *type); static int lvalue_type(int t); @@ -2554,6 +2554,9 @@ static void preprocess(int is_bof) else warning("#warning %s", buf); break; + case TOK_PRAGMA: + /* ignored */ + break; default: if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) { /* '!' is ignored to allow C scripts. numbers are ignored @@ -5154,7 +5157,7 @@ static void gen_cast(CType *type) } /* return type size. Put alignment at 'a' */ -int type_size(CType *type, int *a) +static int type_size(CType *type, int *a) { Sym *s; int bt; @@ -5163,7 +5166,7 @@ int type_size(CType *type, int *a) if (bt == VT_STRUCT) { /* struct/union */ s = type->ref; - *a = 4; /* XXX: cannot store it yet. Doing that is safe */ + *a = s->r; return s->c; } else if (bt == VT_PTR) { if (type->t & VT_ARRAY) { @@ -5177,7 +5180,7 @@ int type_size(CType *type, int *a) *a = LDOUBLE_ALIGN; return LDOUBLE_SIZE; } else if (bt == VT_DOUBLE || bt == VT_LLONG) { - *a = 8; + *a = 4; /* XXX: i386 specific */ return 8; } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) { *a = 4; @@ -5634,12 +5637,9 @@ static void struct_decl(CType *type, int u) error("struct/union/enum already defined"); /* cannot be empty */ c = 0; - maxalign = 0; - ps = &s->next; - bit_pos = 0; - offset = 0; - while (1) { - if (a == TOK_ENUM) { + /* non empty enums are not allowed */ + if (a == TOK_ENUM) { + for(;;) { v = tok; next(); if (tok == '=') { @@ -5652,7 +5652,16 @@ static void struct_decl(CType *type, int u) if (tok == ',') next(); c++; - } else { + if (tok == '}') + break; + } + skip('}'); + } else { + maxalign = 1; + ps = &s->next; + bit_pos = 0; + offset = 0; + while (tok != '}') { parse_btype(&btype, &ad); while (1) { bit_size = -1; @@ -5682,7 +5691,8 @@ static void struct_decl(CType *type, int u) bt = type1.t & VT_BTYPE; if (bt != VT_INT && bt != VT_BYTE && - bt != VT_SHORT) + bt != VT_SHORT && + bt != VT_ENUM) error("bitfields must have scalar type"); bsize = size * 8; if (bit_size > bsize) { @@ -5741,18 +5751,17 @@ static void struct_decl(CType *type, int u) *ps = ss; ps = &ss->next; } - if (tok == ';' || tok == -1) + if (tok == ';' || tok == TOK_EOF) break; skip(','); } skip(';'); } - if (tok == '}') - break; + skip('}'); + /* store size and alignment */ + s->c = (c + maxalign - 1) & -maxalign; + s->r = maxalign; } - skip('}'); - /* size for struct/union, dummy for enum */ - s->c = (c + maxalign - 1) & -maxalign; } } @@ -6653,18 +6662,17 @@ static void expr_land(void) int t; expr_or(); - t = 0; - while (1) { - if (tok != TOK_LAND) { - if (t) { - t = gtst(1, t); + if (tok == TOK_LAND) { + t = 0; + for(;;) { + t = gtst(1, t); + if (tok != TOK_LAND) { vseti(VT_JMPI, t); + break; } - break; + next(); + expr_or(); } - t = gtst(1, t); - next(); - expr_or(); } } @@ -6673,18 +6681,17 @@ static void expr_lor(void) int t; expr_land(); - t = 0; - while (1) { - if (tok != TOK_LOR) { - if (t) { - t = gtst(0, t); + if (tok == TOK_LOR) { + t = 0; + for(;;) { + t = gtst(0, t); + if (tok != TOK_LOR) { vseti(VT_JMP, t); + break; } - break; + next(); + expr_land(); } - t = gtst(0, t); - next(); - expr_land(); } } @@ -6714,8 +6721,16 @@ static void expr_eq(void) expr_lor(); if (tok == '?') { next(); - save_regs(1); /* we need to save all registers here except - at the top because it is a branch point */ + if (vtop != vstack) { + /* needed to avoid having different registers saved in + each branch */ + if (is_float(vtop->type.t)) + rc = RC_FLOAT; + else + rc = RC_INT; + gv(rc); + save_regs(1); + } tt = gtst(1, 0); gexpr(); type1 = vtop->type; @@ -6723,7 +6738,6 @@ static void expr_eq(void) vtop--; /* no vpop so that FP stack is not flushed */ skip(':'); u = gjmp(0); - gsym(tt); expr_eq(); type2 = vtop->type; @@ -6776,6 +6790,7 @@ static void expr_eq(void) to handle a complicated move */ rc = RC_IRET; } + r2 = gv(rc); /* this is horrible, but we must also convert first operand */ @@ -8509,6 +8524,11 @@ TCCState *tcc_new(void) #endif /* tiny C specific defines */ tcc_define_symbol(s, "__TINYC__", NULL); + + /* tiny C & gcc defines */ + tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int"); + tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int"); + tcc_define_symbol(s, "__WCHAR_TYPE__", "int"); /* default library paths */ tcc_add_library_path(s, "/usr/local/lib");