added bitfields support
This commit is contained in:
		
							parent
							
								
									cb693e5318
								
							
						
					
					
						commit
						3d1bdcf70e
					
				
					 1 changed files with 181 additions and 54 deletions
				
			
		
							
								
								
									
										235
									
								
								tcc.c
									
										
									
									
									
								
							
							
						
						
									
										235
									
								
								tcc.c
									
										
									
									
									
								
							| 
						 | 
					@ -164,7 +164,7 @@ int gnu_ext = 1;
 | 
				
			||||||
#define VT_TYPEDEF 0x00000100  /* typedef definition */
 | 
					#define VT_TYPEDEF 0x00000100  /* typedef definition */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* types */
 | 
					/* types */
 | 
				
			||||||
#define VT_STRUCT_SHIFT 15   /* structure/enum name shift (14 bits left) */
 | 
					#define VT_STRUCT_SHIFT 16   /* structure/enum name shift (16 bits left) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VT_BTYPE_SHIFT 9
 | 
					#define VT_BTYPE_SHIFT 9
 | 
				
			||||||
#define VT_INT        (0 << VT_BTYPE_SHIFT)  /* integer type */
 | 
					#define VT_INT        (0 << VT_BTYPE_SHIFT)  /* integer type */
 | 
				
			||||||
| 
						 | 
					@ -178,6 +178,7 @@ int gnu_ext = 1;
 | 
				
			||||||
#define VT_BTYPE      (0xf << VT_BTYPE_SHIFT) /* mask for basic type */
 | 
					#define VT_BTYPE      (0xf << VT_BTYPE_SHIFT) /* mask for basic type */
 | 
				
			||||||
#define VT_UNSIGNED   (0x10 << VT_BTYPE_SHIFT)  /* unsigned type */
 | 
					#define VT_UNSIGNED   (0x10 << VT_BTYPE_SHIFT)  /* unsigned type */
 | 
				
			||||||
#define VT_ARRAY      (0x20 << VT_BTYPE_SHIFT)  /* array type (also has VT_PTR) */
 | 
					#define VT_ARRAY      (0x20 << VT_BTYPE_SHIFT)  /* array type (also has VT_PTR) */
 | 
				
			||||||
 | 
					#define VT_BITFIELD   (0x40 << VT_BTYPE_SHIFT)  /* bitfield modifier */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VT_TYPE    0xfffffe00  /* type mask */
 | 
					#define VT_TYPE    0xfffffe00  /* type mask */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -313,6 +314,7 @@ int get_reg(void);
 | 
				
			||||||
void macro_subst(int **tok_str, int *tok_len, 
 | 
					void macro_subst(int **tok_str, int *tok_len, 
 | 
				
			||||||
                 Sym **nested_list, int *macro_str);
 | 
					                 Sym **nested_list, int *macro_str);
 | 
				
			||||||
int save_reg_forced(int r);
 | 
					int save_reg_forced(int r);
 | 
				
			||||||
 | 
					void gen_op(int op);
 | 
				
			||||||
void vstore(void);
 | 
					void vstore(void);
 | 
				
			||||||
int type_size(int t, int *a);
 | 
					int type_size(int t, int *a);
 | 
				
			||||||
int pointed_type(int t);
 | 
					int pointed_type(int t);
 | 
				
			||||||
| 
						 | 
					@ -1635,7 +1637,7 @@ void gen_addr32(int c, int t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* XXX: generate correct pointer for forward references to functions */
 | 
					/* XXX: generate correct pointer for forward references to functions */
 | 
				
			||||||
/* r = (ft, fc) */
 | 
					/* r = (ft, fc) */
 | 
				
			||||||
void load(r, ft, fc)
 | 
					void load(int r, int ft, int fc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int v, t;
 | 
					    int v, t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1975,18 +1977,35 @@ void move_reg(r, s)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* convert a stack entry in register. lvalues are converted as
 | 
					/* convert a (vt, vc) in register. lvalues are converted as
 | 
				
			||||||
   values. Cannot be used if cannot be converted to register value
 | 
					   values. Cannot be used if cannot be converted to register value
 | 
				
			||||||
   (such as structures). */
 | 
					   (such as structures). */
 | 
				
			||||||
int gvp(int *p)
 | 
					int gvp(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int r;
 | 
					    int r, bit_pos, bit_size;
 | 
				
			||||||
    r = p[0] & VT_VALMASK;
 | 
					
 | 
				
			||||||
    if (r >= VT_CONST || (p[0] & VT_LVAL))
 | 
					    /* NOTE: get_reg can modify vstack[] */
 | 
				
			||||||
        r = get_reg();
 | 
					    if (vt & VT_BITFIELD) {
 | 
				
			||||||
    /* NOTE: get_reg can modify p[] */
 | 
					        bit_pos = (vt >> VT_STRUCT_SHIFT) & 0x3f;
 | 
				
			||||||
    load(r, p[0], p[1]);
 | 
					        bit_size = (vt >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
 | 
				
			||||||
    p[0] = (p[0] & VT_TYPE) | r;
 | 
					        /* remove bit field info to avoid loops */
 | 
				
			||||||
 | 
					        vt &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
 | 
				
			||||||
 | 
					        /* generate shifts */
 | 
				
			||||||
 | 
					        vpush();
 | 
				
			||||||
 | 
					        vset(VT_CONST, 32 - (bit_pos + bit_size));
 | 
				
			||||||
 | 
					        gen_op(TOK_SHL);
 | 
				
			||||||
 | 
					        vpush();
 | 
				
			||||||
 | 
					        vset(VT_CONST, 32 - bit_size);
 | 
				
			||||||
 | 
					        /* NOTE: transformed to SHR if unsigned */
 | 
				
			||||||
 | 
					        gen_op(TOK_SAR);
 | 
				
			||||||
 | 
					        r = gv();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        r = vt & VT_VALMASK;
 | 
				
			||||||
 | 
					        if (r >= VT_CONST || (vt & VT_LVAL))
 | 
				
			||||||
 | 
					            r = get_reg();
 | 
				
			||||||
 | 
					        load(r, vt, vc);
 | 
				
			||||||
 | 
					        vt = (vt & VT_TYPE) | r;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return r;
 | 
					    return r;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1994,12 +2013,12 @@ void vpush(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (vstack_ptr >= vstack + VSTACK_SIZE)
 | 
					    if (vstack_ptr >= vstack + VSTACK_SIZE)
 | 
				
			||||||
        error("memory full");
 | 
					        error("memory full");
 | 
				
			||||||
    *vstack_ptr++ = vt;
 | 
					 | 
				
			||||||
    *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 ? */
 | 
					    /* XXX: VT_JMP test too ? */
 | 
				
			||||||
    if ((vt & VT_VALMASK) == VT_CMP)
 | 
					    if ((vt & VT_VALMASK) == VT_CMP)
 | 
				
			||||||
        gvp(vstack_ptr - 2);
 | 
					        gvp();
 | 
				
			||||||
 | 
					    *vstack_ptr++ = vt;
 | 
				
			||||||
 | 
					    *vstack_ptr++ = vc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void vpop(int *ft, int *fc)
 | 
					void vpop(int *ft, int *fc)
 | 
				
			||||||
| 
						 | 
					@ -2008,18 +2027,25 @@ void vpop(int *ft, int *fc)
 | 
				
			||||||
    *ft = *--vstack_ptr;
 | 
					    *ft = *--vstack_ptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void vswap(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    swap(vstack_ptr - 4, vstack_ptr - 2);
 | 
				
			||||||
 | 
					    swap(vstack_ptr - 3, vstack_ptr - 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* generate a value in a register from vt and vc */
 | 
					/* generate a value in a register from vt and vc */
 | 
				
			||||||
int gv(void)
 | 
					int gv(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int r;
 | 
					    int r;
 | 
				
			||||||
    vpush();
 | 
					    vpush(); /* need so that gvp does not allocate the register we
 | 
				
			||||||
    r = gvp(vstack_ptr - 2);
 | 
					                currently use */
 | 
				
			||||||
    vpop(&vt, &vc);
 | 
					    r = gvp();
 | 
				
			||||||
 | 
					    vstack_ptr -= 2;
 | 
				
			||||||
    return r;
 | 
					    return r;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* handle constant optimizations and various machine independant opt */
 | 
					/* handle constant optimizations and various machine independant opt */
 | 
				
			||||||
void gen_opc(op)
 | 
					void gen_opc(int op)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int fr, ft, fc, r, c1, c2, n;
 | 
					    int fr, ft, fc, r, c1, c2, n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2098,11 +2124,15 @@ void gen_opc(op)
 | 
				
			||||||
            vpush();
 | 
					            vpush();
 | 
				
			||||||
            vt = ft;
 | 
					            vt = ft;
 | 
				
			||||||
            vc = fc;
 | 
					            vc = fc;
 | 
				
			||||||
            vpush();
 | 
					
 | 
				
			||||||
            r = gvp(vstack_ptr - 4);
 | 
					            fr = gv(); /* second operand */
 | 
				
			||||||
            fr = gvp(vstack_ptr - 2);
 | 
					 | 
				
			||||||
            vpop(&ft, &fc);
 | 
					            vpop(&ft, &fc);
 | 
				
			||||||
            vpop(&vt, &vc);
 | 
					            vpush();
 | 
				
			||||||
 | 
					            vt = ft;
 | 
				
			||||||
 | 
					            vc = fc;
 | 
				
			||||||
 | 
					            r = gv(); /* first operand */
 | 
				
			||||||
 | 
					            vpop(&ft, &fc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* call low level op generator */
 | 
					            /* call low level op generator */
 | 
				
			||||||
            gen_op1(op, r, fr);
 | 
					            gen_op1(op, r, fr);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -2217,12 +2247,15 @@ int type_size(int t, int *a)
 | 
				
			||||||
        s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
 | 
					        s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
 | 
				
			||||||
        *a = 4; /* XXX: cannot store it yet. Doing that is safe */
 | 
					        *a = 4; /* XXX: cannot store it yet. Doing that is safe */
 | 
				
			||||||
        return s->c;
 | 
					        return s->c;
 | 
				
			||||||
    } else if (t & VT_ARRAY) {
 | 
					    } else if (bt == VT_PTR) {
 | 
				
			||||||
        s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
 | 
					        if (t & VT_ARRAY) {
 | 
				
			||||||
        return type_size(s->t, a) * s->c;
 | 
					            s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
 | 
				
			||||||
    } else if (bt == VT_PTR ||
 | 
					            return type_size(s->t, a) * s->c;
 | 
				
			||||||
               bt == VT_INT ||
 | 
					        } else {
 | 
				
			||||||
               bt == VT_ENUM) {
 | 
					            *a = 4;
 | 
				
			||||||
 | 
					            return 4;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else if (bt == VT_INT || bt == VT_ENUM) {
 | 
				
			||||||
        *a = 4;
 | 
					        *a = 4;
 | 
				
			||||||
        return 4;
 | 
					        return 4;
 | 
				
			||||||
    } else if (bt == VT_SHORT) {
 | 
					    } else if (bt == VT_SHORT) {
 | 
				
			||||||
| 
						 | 
					@ -2254,7 +2287,7 @@ int mk_pointer(int t)
 | 
				
			||||||
/* store value in lvalue pushed on stack */
 | 
					/* store value in lvalue pushed on stack */
 | 
				
			||||||
void vstore(void)
 | 
					void vstore(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ft, fc, r, t, size, align;
 | 
					    int ft, fc, r, t, size, align, bit_size, bit_pos;
 | 
				
			||||||
    GFuncContext gf;
 | 
					    GFuncContext gf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((vt & VT_BTYPE) == VT_STRUCT) {
 | 
					    if ((vt & VT_BTYPE) == VT_STRUCT) {
 | 
				
			||||||
| 
						 | 
					@ -2285,6 +2318,31 @@ void vstore(void)
 | 
				
			||||||
        /* generate again current type */
 | 
					        /* generate again current type */
 | 
				
			||||||
        vt = ft;
 | 
					        vt = ft;
 | 
				
			||||||
        vc = fc;
 | 
					        vc = fc;
 | 
				
			||||||
 | 
					    } else if (vstack_ptr[-2] & VT_BITFIELD) {
 | 
				
			||||||
 | 
					        /* bitfield store handling */
 | 
				
			||||||
 | 
					        ft = vstack_ptr[-2];
 | 
				
			||||||
 | 
					        bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
 | 
				
			||||||
 | 
					        bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
 | 
				
			||||||
 | 
					        /* remove bit field info to avoid loops */
 | 
				
			||||||
 | 
					        vstack_ptr[-2] = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* mask and shift source */
 | 
				
			||||||
 | 
					        vpush();
 | 
				
			||||||
 | 
					        vset(VT_CONST, (1 << bit_size) - 1);
 | 
				
			||||||
 | 
					        gen_op('&');
 | 
				
			||||||
 | 
					        vpush();
 | 
				
			||||||
 | 
					        vset(VT_CONST, bit_pos);
 | 
				
			||||||
 | 
					        gen_op(TOK_SHL);
 | 
				
			||||||
 | 
					        vpush();
 | 
				
			||||||
 | 
					        /* load destination, mask and or with source */
 | 
				
			||||||
 | 
					        vt = vstack_ptr[-4];
 | 
				
			||||||
 | 
					        vc = vstack_ptr[-3];
 | 
				
			||||||
 | 
					        vpush();
 | 
				
			||||||
 | 
					        vset(VT_CONST, ~(((1 << bit_size) - 1) << bit_pos));
 | 
				
			||||||
 | 
					        gen_op('&');
 | 
				
			||||||
 | 
					        gen_op('|');
 | 
				
			||||||
 | 
					        /* store result */
 | 
				
			||||||
 | 
					        vstore();
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        r = gv();  /* generate value */
 | 
					        r = gv();  /* generate value */
 | 
				
			||||||
        vpush();
 | 
					        vpush();
 | 
				
			||||||
| 
						 | 
					@ -2302,7 +2360,7 @@ void vstore(void)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* post defines POST/PRE add. c is the token ++ or -- */
 | 
					/* post defines POST/PRE add. c is the token ++ or -- */
 | 
				
			||||||
void inc(post, c)
 | 
					void inc(int post, int c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int r, r1;
 | 
					    int r, r1;
 | 
				
			||||||
    test_lvalue();
 | 
					    test_lvalue();
 | 
				
			||||||
| 
						 | 
					@ -2329,7 +2387,8 @@ void inc(post, c)
 | 
				
			||||||
/* enum/struct/union declaration */
 | 
					/* enum/struct/union declaration */
 | 
				
			||||||
int struct_decl(int u)
 | 
					int struct_decl(int u)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int a, t, b, v, size, align, maxalign, c;
 | 
					    int a, t, b, v, size, align, maxalign, c, offset;
 | 
				
			||||||
 | 
					    int bit_size, bit_pos, bsize, bt, lbit_pos;
 | 
				
			||||||
    Sym *s, *ss, **ps;
 | 
					    Sym *s, *ss, **ps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    a = tok; /* save decl type */
 | 
					    a = tok; /* save decl type */
 | 
				
			||||||
| 
						 | 
					@ -2360,6 +2419,8 @@ int struct_decl(int u)
 | 
				
			||||||
        c = 0;
 | 
					        c = 0;
 | 
				
			||||||
        maxalign = 0;
 | 
					        maxalign = 0;
 | 
				
			||||||
        ps = &s->next;
 | 
					        ps = &s->next;
 | 
				
			||||||
 | 
					        bit_pos = 0;
 | 
				
			||||||
 | 
					        offset = 0;
 | 
				
			||||||
        while (1) {
 | 
					        while (1) {
 | 
				
			||||||
            if (a == TOK_ENUM) {
 | 
					            if (a == TOK_ENUM) {
 | 
				
			||||||
                v = tok;
 | 
					                v = tok;
 | 
				
			||||||
| 
						 | 
					@ -2376,26 +2437,92 @@ int struct_decl(int u)
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                b = ist();
 | 
					                b = ist();
 | 
				
			||||||
                while (1) {
 | 
					                while (1) {
 | 
				
			||||||
                    t = type_decl(&v, b, TYPE_DIRECT);
 | 
					                    bit_size = -1;
 | 
				
			||||||
                    if ((t & VT_BTYPE) == VT_FUNC ||
 | 
					                    v = 0;
 | 
				
			||||||
                        (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
 | 
					                    if (tok != ':') {
 | 
				
			||||||
                        error("invalid type");
 | 
					                        t = type_decl(&v, b, TYPE_DIRECT);
 | 
				
			||||||
                    /* XXX: align & correct type size */
 | 
					                        if ((t & VT_BTYPE) == VT_FUNC ||
 | 
				
			||||||
                    v |= SYM_FIELD;
 | 
					                            (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
 | 
				
			||||||
                    size = type_size(t, &align);
 | 
					                            error("invalid type for '%s'", get_tok_str(v, 0));
 | 
				
			||||||
                    if (a == TOK_STRUCT) {
 | 
					 | 
				
			||||||
                        c = (c + align - 1) & -align;
 | 
					 | 
				
			||||||
                        ss = sym_push(v, t, c);
 | 
					 | 
				
			||||||
                        c += size;
 | 
					 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        ss = sym_push(v, t, 0);
 | 
					                        t = b;
 | 
				
			||||||
                        if (size > c)
 | 
					                    }
 | 
				
			||||||
                            c = size;
 | 
					                    if (tok == ':') {
 | 
				
			||||||
 | 
					                        next();
 | 
				
			||||||
 | 
					                        bit_size = expr_const();
 | 
				
			||||||
 | 
					                        /* XXX: handle v = 0 case for messages */
 | 
				
			||||||
 | 
					                        if (bit_size < 0)
 | 
				
			||||||
 | 
					                            error("negative width in bit-field '%s'", 
 | 
				
			||||||
 | 
					                                  get_tok_str(v, 0));
 | 
				
			||||||
 | 
					                        if (v && bit_size == 0)
 | 
				
			||||||
 | 
					                            error("zero width for bit-field '%s'", 
 | 
				
			||||||
 | 
					                                  get_tok_str(v, 0));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    size = type_size(t, &align);
 | 
				
			||||||
 | 
					                    lbit_pos = 0;
 | 
				
			||||||
 | 
					                    if (bit_size >= 0) {
 | 
				
			||||||
 | 
					                        bt = t & VT_BTYPE;
 | 
				
			||||||
 | 
					                        if (bt != VT_INT && 
 | 
				
			||||||
 | 
					                            bt != VT_BYTE && 
 | 
				
			||||||
 | 
					                            bt != VT_SHORT)
 | 
				
			||||||
 | 
					                            error("bitfields must have scalar type");
 | 
				
			||||||
 | 
					                        bsize = size * 8;
 | 
				
			||||||
 | 
					                        if (bit_size > bsize) {
 | 
				
			||||||
 | 
					                            error("width of '%s' exceeds its type",
 | 
				
			||||||
 | 
					                                  get_tok_str(v, 0));
 | 
				
			||||||
 | 
					                        } else if (bit_size == bsize) {
 | 
				
			||||||
 | 
					                            /* no need for bit fields */
 | 
				
			||||||
 | 
					                            bit_pos = 0;
 | 
				
			||||||
 | 
					                        } else if (bit_size == 0) {
 | 
				
			||||||
 | 
					                            /* XXX: what to do if only padding in a
 | 
				
			||||||
 | 
					                               structure ? */
 | 
				
			||||||
 | 
					                            /* zero size: means to pad */
 | 
				
			||||||
 | 
					                            if (bit_pos > 0)
 | 
				
			||||||
 | 
					                                bit_pos = bsize;
 | 
				
			||||||
 | 
					                        } else {
 | 
				
			||||||
 | 
					                            /* we do not have enough room ? */
 | 
				
			||||||
 | 
					                            if ((bit_pos + bit_size) > bsize)
 | 
				
			||||||
 | 
					                                bit_pos = 0;
 | 
				
			||||||
 | 
					                            lbit_pos = bit_pos;
 | 
				
			||||||
 | 
					                            /* XXX: handle LSB first */
 | 
				
			||||||
 | 
					                            t |= VT_BITFIELD | 
 | 
				
			||||||
 | 
					                                (bit_pos << VT_STRUCT_SHIFT) |
 | 
				
			||||||
 | 
					                                (bit_size << (VT_STRUCT_SHIFT + 6));
 | 
				
			||||||
 | 
					                            bit_pos += bit_size;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        bit_pos = 0;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (v) {
 | 
				
			||||||
 | 
					                        /* add new memory data only if starting
 | 
				
			||||||
 | 
					                           bit field */
 | 
				
			||||||
 | 
					                        if (lbit_pos == 0) {
 | 
				
			||||||
 | 
					                            if (a == TOK_STRUCT) {
 | 
				
			||||||
 | 
					                                c = (c + align - 1) & -align;
 | 
				
			||||||
 | 
					                                offset = c;
 | 
				
			||||||
 | 
					                                c += size;
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                                offset = 0;
 | 
				
			||||||
 | 
					                                if (size > c)
 | 
				
			||||||
 | 
					                                    c = size;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            if (align > maxalign)
 | 
				
			||||||
 | 
					                                maxalign = align;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					                        printf("add field %s offset=%d", 
 | 
				
			||||||
 | 
					                               get_tok_str(v, 0), offset);
 | 
				
			||||||
 | 
					                        if (t & VT_BITFIELD) {
 | 
				
			||||||
 | 
					                            printf(" pos=%d size=%d", 
 | 
				
			||||||
 | 
					                                   (t >> VT_STRUCT_SHIFT) & 0x3f,
 | 
				
			||||||
 | 
					                                   (t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        printf("\n");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					                        ss = sym_push(v | SYM_FIELD, t, offset);
 | 
				
			||||||
 | 
					                        *ps = ss;
 | 
				
			||||||
 | 
					                        ps = &ss->next;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if (align > maxalign)
 | 
					 | 
				
			||||||
                        maxalign = align;
 | 
					 | 
				
			||||||
                    *ps = ss;
 | 
					 | 
				
			||||||
                    ps = &ss->next;
 | 
					 | 
				
			||||||
                    if (tok == ';' || tok == -1)
 | 
					                    if (tok == ';' || tok == -1)
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                    skip(',');
 | 
					                    skip(',');
 | 
				
			||||||
| 
						 | 
					@ -3003,15 +3130,15 @@ int check_assign_types(int t1, int t2)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void uneq()
 | 
					void uneq(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int t;
 | 
					    int t;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    unary();
 | 
					    unary();
 | 
				
			||||||
    if (tok == '=' | 
 | 
					    if (tok == '=' ||
 | 
				
			||||||
        (tok >= TOK_A_MOD & tok <= TOK_A_DIV) |
 | 
					        (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
 | 
				
			||||||
        tok == TOK_A_XOR | tok == TOK_A_OR | 
 | 
					        tok == TOK_A_XOR || tok == TOK_A_OR ||
 | 
				
			||||||
        tok == TOK_A_SHL | tok == TOK_A_SAR) {
 | 
					        tok == TOK_A_SHL || tok == TOK_A_SAR) {
 | 
				
			||||||
        test_lvalue();
 | 
					        test_lvalue();
 | 
				
			||||||
        vpush();
 | 
					        vpush();
 | 
				
			||||||
        t = tok;
 | 
					        t = tok;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue