fix function call and ! operator
This commit is contained in:
parent
3c9ab729ae
commit
52ca29cd4f
1 changed files with 34 additions and 31 deletions
63
tcc.c
63
tcc.c
|
|
@ -128,7 +128,7 @@ int func_vt, func_vc; /* current function return type (used by
|
||||||
return instruction) */
|
return instruction) */
|
||||||
int tok_ident;
|
int tok_ident;
|
||||||
TokenSym **table_ident;
|
TokenSym **table_ident;
|
||||||
TokenSym *hash_ident[521];
|
TokenSym *hash_ident[TOK_HASH_SIZE];
|
||||||
char token_buf[STRING_MAX_SIZE + 1];
|
char token_buf[STRING_MAX_SIZE + 1];
|
||||||
char *filename, *funcname;
|
char *filename, *funcname;
|
||||||
/* contains global symbols which remain between each translation unit */
|
/* contains global symbols which remain between each translation unit */
|
||||||
|
|
@ -451,7 +451,7 @@ TokenSym *tok_alloc(char *str, int len)
|
||||||
table_ident = ptable;
|
table_ident = ptable;
|
||||||
}
|
}
|
||||||
ts = malloc(sizeof(TokenSym) + len);
|
ts = malloc(sizeof(TokenSym) + len);
|
||||||
if (!ts)
|
if (!ts || tok_ident >= SYM_FIRST_ANOM)
|
||||||
error("memory full");
|
error("memory full");
|
||||||
table_ident[i] = ts;
|
table_ident[i] = ts;
|
||||||
ts->tok = tok_ident++;
|
ts->tok = tok_ident++;
|
||||||
|
|
@ -1118,8 +1118,6 @@ void next_nomacro1()
|
||||||
*q++ = ch;
|
*q++ = ch;
|
||||||
cinp();
|
cinp();
|
||||||
if (q[-1] == 'L') {
|
if (q[-1] == 'L') {
|
||||||
/* XXX: not supported entirely (needs different
|
|
||||||
preprocessor architecture) */
|
|
||||||
if (ch == '\'') {
|
if (ch == '\'') {
|
||||||
tok = TOK_LCHAR;
|
tok = TOK_LCHAR;
|
||||||
goto char_const;
|
goto char_const;
|
||||||
|
|
@ -1746,23 +1744,23 @@ void gfunc_param(GFuncContext *c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate function call with address in (ft, fc) and free function */
|
/* generate function call with address in (vt, vc) and free function
|
||||||
void gfunc_call(GFuncContext *c, int ft, int fc)
|
context */
|
||||||
|
void gfunc_call(GFuncContext *c)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
r = ft & VT_VALMASK;
|
if ((vt & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
||||||
if (r == VT_CONST) {
|
/* constant case */
|
||||||
/* forward reference */
|
/* forward reference */
|
||||||
if (ft & VT_FORWARD) {
|
if (vt & VT_FORWARD) {
|
||||||
greloc((Sym *)fc, ind + 1, RELOC_REL32);
|
greloc((Sym *)vc, ind + 1, RELOC_REL32);
|
||||||
oad(0xe8, 0);
|
oad(0xe8, 0);
|
||||||
} else {
|
} else {
|
||||||
oad(0xe8, fc - ind - 5);
|
oad(0xe8, vc - ind - 5);
|
||||||
}
|
}
|
||||||
} else if (r == VT_LOCAL) {
|
|
||||||
oad(0x95ff, fc); /* call *xxx(%ebp) */
|
|
||||||
} else {
|
} else {
|
||||||
/* not actually used */
|
/* otherwise, indirect call */
|
||||||
|
r = gv();
|
||||||
o(0xff); /* call *r */
|
o(0xff); /* call *r */
|
||||||
o(0xd0 + r);
|
o(0xd0 + r);
|
||||||
}
|
}
|
||||||
|
|
@ -1776,7 +1774,7 @@ int gjmp(int t)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate a test. set 'inv' to invert test */
|
/* generate a test. set 'inv' to invert test */
|
||||||
int gtst(inv, t)
|
int gtst(int inv, int t)
|
||||||
{
|
{
|
||||||
int v, *p;
|
int v, *p;
|
||||||
v = vt & VT_VALMASK;
|
v = vt & VT_VALMASK;
|
||||||
|
|
@ -1813,7 +1811,7 @@ int gtst(inv, t)
|
||||||
|
|
||||||
/* generate a binary operation 'v = r op fr' instruction and modifies
|
/* generate a binary operation 'v = r op fr' instruction and modifies
|
||||||
(vt,vc) if needed */
|
(vt,vc) if needed */
|
||||||
void gen_op1(op, r, fr)
|
void gen_op1(int op, int r, int fr)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
if (op == '+') {
|
if (op == '+') {
|
||||||
|
|
@ -1990,6 +1988,7 @@ void vpush(void)
|
||||||
*vstack_ptr++ = vt;
|
*vstack_ptr++ = vt;
|
||||||
*vstack_ptr++ = vc;
|
*vstack_ptr++ = vc;
|
||||||
/* cannot let cpu flags if other instruction are generated */
|
/* cannot let cpu flags if other instruction are generated */
|
||||||
|
/* XXX: VT_JMP test too ? */
|
||||||
if ((vt & VT_VALMASK) == VT_CMP)
|
if ((vt & VT_VALMASK) == VT_CMP)
|
||||||
gvp(vstack_ptr - 2);
|
gvp(vstack_ptr - 2);
|
||||||
}
|
}
|
||||||
|
|
@ -2207,8 +2206,8 @@ int type_size(int t, int *a)
|
||||||
} else if (t & VT_ARRAY) {
|
} else if (t & VT_ARRAY) {
|
||||||
s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
|
s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
|
||||||
return type_size(s->t, a) * s->c;
|
return type_size(s->t, a) * s->c;
|
||||||
} else if ((t & VT_PTR) |
|
} else if ((t & VT_PTR) ||
|
||||||
(t & VT_TYPE) == 0 |
|
(t & VT_TYPE & ~VT_UNSIGNED) == VT_INT ||
|
||||||
(t & VT_ENUM)) {
|
(t & VT_ENUM)) {
|
||||||
*a = 4;
|
*a = 4;
|
||||||
return 4;
|
return 4;
|
||||||
|
|
@ -2265,7 +2264,8 @@ void vstore(void)
|
||||||
gfunc_param(&gf);
|
gfunc_param(&gf);
|
||||||
|
|
||||||
save_regs();
|
save_regs();
|
||||||
gfunc_call(&gf, VT_CONST, (int)&memcpy);
|
vset(VT_CONST, (int)&memcpy);
|
||||||
|
gfunc_call(&gf);
|
||||||
|
|
||||||
/* generate again current type */
|
/* generate again current type */
|
||||||
vt = ft;
|
vt = ft;
|
||||||
|
|
@ -2510,13 +2510,14 @@ int post_type(int t)
|
||||||
}
|
}
|
||||||
skip(']');
|
skip(']');
|
||||||
/* parse next post type */
|
/* parse next post type */
|
||||||
t = post_type(t);
|
t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
|
||||||
|
t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN));
|
||||||
|
|
||||||
/* we push a anonymous symbol which will contain the array
|
/* we push a anonymous symbol which will contain the array
|
||||||
element type */
|
element type */
|
||||||
p = anon_sym++;
|
p = anon_sym++;
|
||||||
sym_push(p, t, n);
|
sym_push(p, t, n);
|
||||||
t = VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
|
t = t1 | VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
@ -2669,7 +2670,7 @@ void unary(void)
|
||||||
} else
|
} else
|
||||||
if (t == '!') {
|
if (t == '!') {
|
||||||
unary();
|
unary();
|
||||||
if ((vt & (VT_CONST | VT_LVAL)) == VT_CONST)
|
if ((vt & (VT_VALMASK | VT_LVAL)) == VT_CONST)
|
||||||
vc = !vc;
|
vc = !vc;
|
||||||
else if ((vt & VT_VALMASK) == VT_CMP)
|
else if ((vt & VT_VALMASK) == VT_CMP)
|
||||||
vc = vc ^ 1;
|
vc = vc ^ 1;
|
||||||
|
|
@ -2780,13 +2781,14 @@ void unary(void)
|
||||||
goto error_func;
|
goto error_func;
|
||||||
} else {
|
} else {
|
||||||
error_func:
|
error_func:
|
||||||
expect("function type");
|
expect("function pointer");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
vt &= ~VT_LVAL; /* no lvalue */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get return type */
|
/* get return type */
|
||||||
s = sym_find((unsigned)vt >> VT_STRUCT_SHIFT);
|
s = sym_find((unsigned)vt >> VT_STRUCT_SHIFT);
|
||||||
|
|
||||||
vt &= ~VT_LVAL; /* no lvalue */
|
|
||||||
vpush(); /* push function address */
|
vpush(); /* push function address */
|
||||||
save_regs(); /* save used temporary registers */
|
save_regs(); /* save used temporary registers */
|
||||||
gfunc_start(&gf);
|
gfunc_start(&gf);
|
||||||
|
|
@ -2865,8 +2867,8 @@ void unary(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
skip(')');
|
skip(')');
|
||||||
vpop(&ft, &fc);
|
vpop(&vt, &vc);
|
||||||
gfunc_call(&gf, ft, fc);
|
gfunc_call(&gf);
|
||||||
/* return value */
|
/* return value */
|
||||||
vt = rett;
|
vt = rett;
|
||||||
vc = retc;
|
vc = retc;
|
||||||
|
|
@ -2994,7 +2996,7 @@ void sum(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* only used if non constant */
|
/* only used if non constant */
|
||||||
void eand()
|
void eand(void)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
|
|
@ -3014,7 +3016,7 @@ void eand()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void eor()
|
void eor(void)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
|
|
@ -3450,7 +3452,8 @@ void init_putz(int t, int c, int size)
|
||||||
gfunc_param(&gf);
|
gfunc_param(&gf);
|
||||||
vset(VT_LOCAL, c);
|
vset(VT_LOCAL, c);
|
||||||
gfunc_param(&gf);
|
gfunc_param(&gf);
|
||||||
gfunc_call(&gf, VT_CONST, (int)&memset);
|
vset(VT_CONST, (int)&memset);
|
||||||
|
gfunc_call(&gf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue