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:
parent
0841db04c5
commit
7b2721ff07
1 changed files with 59 additions and 39 deletions
98
tcc.c
98
tcc.c
|
@ -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 */
|
||||||
|
@ -8510,6 +8525,11 @@ TCCState *tcc_new(void)
|
||||||
/* 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");
|
||||||
tcc_add_library_path(s, "/usr/lib");
|
tcc_add_library_path(s, "/usr/lib");
|
||||||
|
|
Loading…
Reference in a new issue