aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbellard <bellard>2002-11-24 14:18:17 +0000
committerbellard <bellard>2002-11-24 14:18:17 +0000
commit7b2721ff07f901741f56e22baec0628ca5e4016b (patch)
tree30601ad9265c278cd521a550715048fb67d97f6e
parent0841db04c54fe484df9388f4bbc97432eff005bc (diff)
downloadtinycc-7b2721ff07f901741f56e22baec0628ca5e4016b.tar.gz
tinycc-7b2721ff07f901741f56e22baec0628ca5e4016b.tar.bz2
added empty structs support - changed double align to 4 (i386 default ABI) - added align support for structs - added GCC defines for basic types
-rw-r--r--tcc.c98
1 files changed, 59 insertions, 39 deletions
diff --git a/tcc.c b/tcc.c
index e4a85cb..53da6d5 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");