added empty structs support - changed double align to 4 (i386 default ABI) - added align support for structs - added GCC defines for basic types

This commit is contained in:
bellard 2002-11-24 14:18:17 +00:00
parent 0841db04c5
commit 7b2721ff07

98
tcc.c
View file

@ -587,7 +587,7 @@ static Sym *sym_find(int v);
static Sym *sym_push(int v, CType *type, int r, int c); static Sym *sym_push(int v, CType *type, int r, int c);
/* type handling */ /* 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 inline CType *pointed_type(CType *type);
static int pointed_size(CType *type); static int pointed_size(CType *type);
static int lvalue_type(int t); static int lvalue_type(int t);
@ -2554,6 +2554,9 @@ static void preprocess(int is_bof)
else else
warning("#warning %s", buf); warning("#warning %s", buf);
break; break;
case TOK_PRAGMA:
/* ignored */
break;
default: default:
if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) { if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
/* '!' is ignored to allow C scripts. numbers are ignored /* '!' 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' */ /* return type size. Put alignment at 'a' */
int type_size(CType *type, int *a) static int type_size(CType *type, int *a)
{ {
Sym *s; Sym *s;
int bt; int bt;
@ -5163,7 +5166,7 @@ int type_size(CType *type, int *a)
if (bt == VT_STRUCT) { if (bt == VT_STRUCT) {
/* struct/union */ /* struct/union */
s = type->ref; s = type->ref;
*a = 4; /* XXX: cannot store it yet. Doing that is safe */ *a = s->r;
return s->c; return s->c;
} else if (bt == VT_PTR) { } else if (bt == VT_PTR) {
if (type->t & VT_ARRAY) { if (type->t & VT_ARRAY) {
@ -5177,7 +5180,7 @@ int type_size(CType *type, int *a)
*a = LDOUBLE_ALIGN; *a = LDOUBLE_ALIGN;
return LDOUBLE_SIZE; return LDOUBLE_SIZE;
} else if (bt == VT_DOUBLE || bt == VT_LLONG) { } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
*a = 8; *a = 4; /* XXX: i386 specific */
return 8; return 8;
} else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) { } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
*a = 4; *a = 4;
@ -5634,12 +5637,9 @@ static void struct_decl(CType *type, int u)
error("struct/union/enum already defined"); error("struct/union/enum already defined");
/* cannot be empty */ /* cannot be empty */
c = 0; c = 0;
maxalign = 0; /* non empty enums are not allowed */
ps = &s->next; if (a == TOK_ENUM) {
bit_pos = 0; for(;;) {
offset = 0;
while (1) {
if (a == TOK_ENUM) {
v = tok; v = tok;
next(); next();
if (tok == '=') { if (tok == '=') {
@ -5652,7 +5652,16 @@ static void struct_decl(CType *type, int u)
if (tok == ',') if (tok == ',')
next(); next();
c++; c++;
} else { if (tok == '}')
break;
}
skip('}');
} else {
maxalign = 1;
ps = &s->next;
bit_pos = 0;
offset = 0;
while (tok != '}') {
parse_btype(&btype, &ad); parse_btype(&btype, &ad);
while (1) { while (1) {
bit_size = -1; bit_size = -1;
@ -5682,7 +5691,8 @@ static void struct_decl(CType *type, int u)
bt = type1.t & VT_BTYPE; bt = type1.t & VT_BTYPE;
if (bt != VT_INT && if (bt != VT_INT &&
bt != VT_BYTE && bt != VT_BYTE &&
bt != VT_SHORT) bt != VT_SHORT &&
bt != VT_ENUM)
error("bitfields must have scalar type"); error("bitfields must have scalar type");
bsize = size * 8; bsize = size * 8;
if (bit_size > bsize) { if (bit_size > bsize) {
@ -5741,18 +5751,17 @@ static void struct_decl(CType *type, int u)
*ps = ss; *ps = ss;
ps = &ss->next; ps = &ss->next;
} }
if (tok == ';' || tok == -1) if (tok == ';' || tok == TOK_EOF)
break; break;
skip(','); skip(',');
} }
skip(';'); skip(';');
} }
if (tok == '}') skip('}');
break; /* 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; int t;
expr_or(); expr_or();
t = 0; if (tok == TOK_LAND) {
while (1) { t = 0;
if (tok != TOK_LAND) { for(;;) {
if (t) { t = gtst(1, t);
t = gtst(1, t); if (tok != TOK_LAND) {
vseti(VT_JMPI, t); 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; int t;
expr_land(); expr_land();
t = 0; if (tok == TOK_LOR) {
while (1) { t = 0;
if (tok != TOK_LOR) { for(;;) {
if (t) { t = gtst(0, t);
t = gtst(0, t); if (tok != TOK_LOR) {
vseti(VT_JMP, t); 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(); expr_lor();
if (tok == '?') { if (tok == '?') {
next(); next();
save_regs(1); /* we need to save all registers here except if (vtop != vstack) {
at the top because it is a branch point */ /* 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); tt = gtst(1, 0);
gexpr(); gexpr();
type1 = vtop->type; type1 = vtop->type;
@ -6723,7 +6738,6 @@ static void expr_eq(void)
vtop--; /* no vpop so that FP stack is not flushed */ vtop--; /* no vpop so that FP stack is not flushed */
skip(':'); skip(':');
u = gjmp(0); u = gjmp(0);
gsym(tt); gsym(tt);
expr_eq(); expr_eq();
type2 = vtop->type; type2 = vtop->type;
@ -6776,6 +6790,7 @@ static void expr_eq(void)
to handle a complicated move */ to handle a complicated move */
rc = RC_IRET; rc = RC_IRET;
} }
r2 = gv(rc); r2 = gv(rc);
/* this is horrible, but we must also convert first /* this is horrible, but we must also convert first
operand */ operand */
@ -8509,6 +8524,11 @@ TCCState *tcc_new(void)
#endif #endif
/* tiny C specific defines */ /* tiny C specific defines */
tcc_define_symbol(s, "__TINYC__", NULL); 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 */ /* default library paths */
tcc_add_library_path(s, "/usr/local/lib"); tcc_add_library_path(s, "/usr/local/lib");