tcc_relocate: revert to 0.9.24 behavior
[tinycc.git] / tccgen.c
blob6bc89987dd5da5c863226f78e4fa7b0facf42d6e
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 void swap(int *p, int *q)
23 int t;
24 t = *p;
25 *p = *q;
26 *q = t;
29 void vsetc(CType *type, int r, CValue *vc)
31 int v;
33 if (vtop >= vstack + (VSTACK_SIZE - 1))
34 error("memory full");
35 /* cannot let cpu flags if other instruction are generated. Also
36 avoid leaving VT_JMP anywhere except on the top of the stack
37 because it would complicate the code generator. */
38 if (vtop >= vstack) {
39 v = vtop->r & VT_VALMASK;
40 if (v == VT_CMP || (v & ~1) == VT_JMP)
41 gv(RC_INT);
43 vtop++;
44 vtop->type = *type;
45 vtop->r = r;
46 vtop->r2 = VT_CONST;
47 vtop->c = *vc;
50 /* push integer constant */
51 void vpushi(int v)
53 CValue cval;
54 cval.i = v;
55 vsetc(&int_type, VT_CONST, &cval);
58 /* push long long constant */
59 void vpushll(long long v)
61 CValue cval;
62 CType ctype;
63 ctype.t = VT_LLONG;
64 ctype.ref = 0;
65 cval.ull = v;
66 vsetc(&ctype, VT_CONST, &cval);
69 /* Return a static symbol pointing to a section */
70 static Sym *get_sym_ref(CType *type, Section *sec,
71 unsigned long offset, unsigned long size)
73 int v;
74 Sym *sym;
76 v = anon_sym++;
77 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
78 sym->type.ref = type->ref;
79 sym->r = VT_CONST | VT_SYM;
80 put_extern_sym(sym, sec, offset, size);
81 return sym;
84 /* push a reference to a section offset by adding a dummy symbol */
85 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
87 CValue cval;
89 cval.ul = 0;
90 vsetc(type, VT_CONST | VT_SYM, &cval);
91 vtop->sym = get_sym_ref(type, sec, offset, size);
94 /* define a new external reference to a symbol 'v' of type 'u' */
95 static Sym *external_global_sym(int v, CType *type, int r)
97 Sym *s;
99 s = sym_find(v);
100 if (!s) {
101 /* push forward reference */
102 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
103 s->type.ref = type->ref;
104 s->r = r | VT_CONST | VT_SYM;
106 return s;
109 /* define a new external reference to a symbol 'v' of type 'u' */
110 static Sym *external_sym(int v, CType *type, int r)
112 Sym *s;
114 s = sym_find(v);
115 if (!s) {
116 /* push forward reference */
117 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
118 s->type.t |= VT_EXTERN;
119 } else if (s->type.ref == func_old_type.ref) {
120 s->type.ref = type->ref;
121 s->r = r | VT_CONST | VT_SYM;
122 s->type.t |= VT_EXTERN;
123 } else if (!is_compatible_types(&s->type, type)) {
124 error("incompatible types for redefinition of '%s'",
125 get_tok_str(v, NULL));
127 return s;
130 /* push a reference to global symbol v */
131 static void vpush_global_sym(CType *type, int v)
133 Sym *sym;
134 CValue cval;
136 sym = external_global_sym(v, type, 0);
137 cval.ul = 0;
138 vsetc(type, VT_CONST | VT_SYM, &cval);
139 vtop->sym = sym;
142 void vset(CType *type, int r, int v)
144 CValue cval;
146 cval.i = v;
147 vsetc(type, r, &cval);
150 void vseti(int r, int v)
152 CType type;
153 type.t = VT_INT;
154 type.ref = 0;
155 vset(&type, r, v);
158 void vswap(void)
160 SValue tmp;
162 tmp = vtop[0];
163 vtop[0] = vtop[-1];
164 vtop[-1] = tmp;
167 void vpushv(SValue *v)
169 if (vtop >= vstack + (VSTACK_SIZE - 1))
170 error("memory full");
171 vtop++;
172 *vtop = *v;
175 void vdup(void)
177 vpushv(vtop);
180 /* save r to the memory stack, and mark it as being free */
181 void save_reg(int r)
183 int l, saved, size, align;
184 SValue *p, sv;
185 CType *type;
187 /* modify all stack values */
188 saved = 0;
189 l = 0;
190 for(p=vstack;p<=vtop;p++) {
191 if ((p->r & VT_VALMASK) == r ||
192 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
193 /* must save value on stack if not already done */
194 if (!saved) {
195 /* NOTE: must reload 'r' because r might be equal to r2 */
196 r = p->r & VT_VALMASK;
197 /* store register in the stack */
198 type = &p->type;
199 if ((p->r & VT_LVAL) ||
200 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
201 #ifdef TCC_TARGET_X86_64
202 type = &char_pointer_type;
203 #else
204 type = &int_type;
205 #endif
206 size = type_size(type, &align);
207 loc = (loc - size) & -align;
208 sv.type.t = type->t;
209 sv.r = VT_LOCAL | VT_LVAL;
210 sv.c.ul = loc;
211 store(r, &sv);
212 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
213 /* x86 specific: need to pop fp register ST0 if saved */
214 if (r == TREG_ST0) {
215 o(0xd8dd); /* fstp %st(0) */
217 #endif
218 #ifndef TCC_TARGET_X86_64
219 /* special long long case */
220 if ((type->t & VT_BTYPE) == VT_LLONG) {
221 sv.c.ul += 4;
222 store(p->r2, &sv);
224 #endif
225 l = loc;
226 saved = 1;
228 /* mark that stack entry as being saved on the stack */
229 if (p->r & VT_LVAL) {
230 /* also clear the bounded flag because the
231 relocation address of the function was stored in
232 p->c.ul */
233 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
234 } else {
235 p->r = lvalue_type(p->type.t) | VT_LOCAL;
237 p->r2 = VT_CONST;
238 p->c.ul = l;
243 /* find a register of class 'rc2' with at most one reference on stack.
244 * If none, call get_reg(rc) */
245 int get_reg_ex(int rc, int rc2)
247 int r;
248 SValue *p;
250 for(r=0;r<NB_REGS;r++) {
251 if (reg_classes[r] & rc2) {
252 int n;
253 n=0;
254 for(p = vstack; p <= vtop; p++) {
255 if ((p->r & VT_VALMASK) == r ||
256 (p->r2 & VT_VALMASK) == r)
257 n++;
259 if (n <= 1)
260 return r;
263 return get_reg(rc);
266 /* find a free register of class 'rc'. If none, save one register */
267 int get_reg(int rc)
269 int r;
270 SValue *p;
272 /* find a free register */
273 for(r=0;r<NB_REGS;r++) {
274 if (reg_classes[r] & rc) {
275 for(p=vstack;p<=vtop;p++) {
276 if ((p->r & VT_VALMASK) == r ||
277 (p->r2 & VT_VALMASK) == r)
278 goto notfound;
280 return r;
282 notfound: ;
285 /* no register left : free the first one on the stack (VERY
286 IMPORTANT to start from the bottom to ensure that we don't
287 spill registers used in gen_opi()) */
288 for(p=vstack;p<=vtop;p++) {
289 r = p->r & VT_VALMASK;
290 if (r < VT_CONST && (reg_classes[r] & rc))
291 goto save_found;
292 /* also look at second register (if long long) */
293 r = p->r2 & VT_VALMASK;
294 if (r < VT_CONST && (reg_classes[r] & rc)) {
295 save_found:
296 save_reg(r);
297 return r;
300 /* Should never comes here */
301 return -1;
304 /* save registers up to (vtop - n) stack entry */
305 void save_regs(int n)
307 int r;
308 SValue *p, *p1;
309 p1 = vtop - n;
310 for(p = vstack;p <= p1; p++) {
311 r = p->r & VT_VALMASK;
312 if (r < VT_CONST) {
313 save_reg(r);
318 /* move register 's' to 'r', and flush previous value of r to memory
319 if needed */
320 void move_reg(int r, int s)
322 SValue sv;
324 if (r != s) {
325 save_reg(r);
326 sv.type.t = VT_INT;
327 sv.r = s;
328 sv.c.ul = 0;
329 load(r, &sv);
333 /* get address of vtop (vtop MUST BE an lvalue) */
334 void gaddrof(void)
336 vtop->r &= ~VT_LVAL;
337 /* tricky: if saved lvalue, then we can go back to lvalue */
338 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
339 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
342 #ifdef CONFIG_TCC_BCHECK
343 /* generate lvalue bound code */
344 void gbound(void)
346 int lval_type;
347 CType type1;
349 vtop->r &= ~VT_MUSTBOUND;
350 /* if lvalue, then use checking code before dereferencing */
351 if (vtop->r & VT_LVAL) {
352 /* if not VT_BOUNDED value, then make one */
353 if (!(vtop->r & VT_BOUNDED)) {
354 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
355 /* must save type because we must set it to int to get pointer */
356 type1 = vtop->type;
357 vtop->type.t = VT_INT;
358 gaddrof();
359 vpushi(0);
360 gen_bounded_ptr_add();
361 vtop->r |= lval_type;
362 vtop->type = type1;
364 /* then check for dereferencing */
365 gen_bounded_ptr_deref();
368 #endif
370 /* store vtop a register belonging to class 'rc'. lvalues are
371 converted to values. Cannot be used if cannot be converted to
372 register value (such as structures). */
373 int gv(int rc)
375 int r, rc2, bit_pos, bit_size, size, align, i;
377 /* NOTE: get_reg can modify vstack[] */
378 if (vtop->type.t & VT_BITFIELD) {
379 CType type;
380 int bits = 32;
381 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
382 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
383 /* remove bit field info to avoid loops */
384 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
385 /* cast to int to propagate signedness in following ops */
386 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
387 type.t = VT_LLONG;
388 bits = 64;
389 } else
390 type.t = VT_INT;
391 if((vtop->type.t & VT_UNSIGNED) ||
392 (vtop->type.t & VT_BTYPE) == VT_BOOL)
393 type.t |= VT_UNSIGNED;
394 gen_cast(&type);
395 /* generate shifts */
396 vpushi(bits - (bit_pos + bit_size));
397 gen_op(TOK_SHL);
398 vpushi(bits - bit_size);
399 /* NOTE: transformed to SHR if unsigned */
400 gen_op(TOK_SAR);
401 r = gv(rc);
402 } else {
403 if (is_float(vtop->type.t) &&
404 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
405 Sym *sym;
406 int *ptr;
407 unsigned long offset;
408 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
409 CValue check;
410 #endif
412 /* XXX: unify with initializers handling ? */
413 /* CPUs usually cannot use float constants, so we store them
414 generically in data segment */
415 size = type_size(&vtop->type, &align);
416 offset = (data_section->data_offset + align - 1) & -align;
417 data_section->data_offset = offset;
418 /* XXX: not portable yet */
419 #if defined(__i386__) || defined(__x86_64__)
420 /* Zero pad x87 tenbyte long doubles */
421 if (size == LDOUBLE_SIZE)
422 vtop->c.tab[2] &= 0xffff;
423 #endif
424 ptr = section_ptr_add(data_section, size);
425 size = size >> 2;
426 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
427 check.d = 1;
428 if(check.tab[0])
429 for(i=0;i<size;i++)
430 ptr[i] = vtop->c.tab[size-1-i];
431 else
432 #endif
433 for(i=0;i<size;i++)
434 ptr[i] = vtop->c.tab[i];
435 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
436 vtop->r |= VT_LVAL | VT_SYM;
437 vtop->sym = sym;
438 vtop->c.ul = 0;
440 #ifdef CONFIG_TCC_BCHECK
441 if (vtop->r & VT_MUSTBOUND)
442 gbound();
443 #endif
445 r = vtop->r & VT_VALMASK;
446 rc2 = RC_INT;
447 if (rc == RC_IRET)
448 rc2 = RC_LRET;
449 /* need to reload if:
450 - constant
451 - lvalue (need to dereference pointer)
452 - already a register, but not in the right class */
453 if (r >= VT_CONST
454 || (vtop->r & VT_LVAL)
455 || !(reg_classes[r] & rc)
456 #ifndef TCC_TARGET_X86_64
457 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
458 #endif
461 r = get_reg(rc);
462 #ifndef TCC_TARGET_X86_64
463 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
464 int r2;
465 unsigned long long ll;
466 /* two register type load : expand to two words
467 temporarily */
468 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
469 /* load constant */
470 ll = vtop->c.ull;
471 vtop->c.ui = ll; /* first word */
472 load(r, vtop);
473 vtop->r = r; /* save register value */
474 vpushi(ll >> 32); /* second word */
475 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
476 (vtop->r & VT_LVAL)) {
477 /* We do not want to modifier the long long
478 pointer here, so the safest (and less
479 efficient) is to save all the other registers
480 in the stack. XXX: totally inefficient. */
481 save_regs(1);
482 /* load from memory */
483 load(r, vtop);
484 vdup();
485 vtop[-1].r = r; /* save register value */
486 /* increment pointer to get second word */
487 vtop->type.t = VT_INT;
488 gaddrof();
489 vpushi(4);
490 gen_op('+');
491 vtop->r |= VT_LVAL;
492 } else {
493 /* move registers */
494 load(r, vtop);
495 vdup();
496 vtop[-1].r = r; /* save register value */
497 vtop->r = vtop[-1].r2;
499 /* allocate second register */
500 r2 = get_reg(rc2);
501 load(r2, vtop);
502 vpop();
503 /* write second register */
504 vtop->r2 = r2;
505 } else
506 #endif
507 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
508 int t1, t;
509 /* lvalue of scalar type : need to use lvalue type
510 because of possible cast */
511 t = vtop->type.t;
512 t1 = t;
513 /* compute memory access type */
514 if (vtop->r & VT_LVAL_BYTE)
515 t = VT_BYTE;
516 else if (vtop->r & VT_LVAL_SHORT)
517 t = VT_SHORT;
518 if (vtop->r & VT_LVAL_UNSIGNED)
519 t |= VT_UNSIGNED;
520 vtop->type.t = t;
521 load(r, vtop);
522 /* restore wanted type */
523 vtop->type.t = t1;
524 } else {
525 /* one register type load */
526 load(r, vtop);
529 vtop->r = r;
530 #ifdef TCC_TARGET_C67
531 /* uses register pairs for doubles */
532 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
533 vtop->r2 = r+1;
534 #endif
536 return r;
539 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
540 void gv2(int rc1, int rc2)
542 int v;
544 /* generate more generic register first. But VT_JMP or VT_CMP
545 values must be generated first in all cases to avoid possible
546 reload errors */
547 v = vtop[0].r & VT_VALMASK;
548 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
549 vswap();
550 gv(rc1);
551 vswap();
552 gv(rc2);
553 /* test if reload is needed for first register */
554 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
555 vswap();
556 gv(rc1);
557 vswap();
559 } else {
560 gv(rc2);
561 vswap();
562 gv(rc1);
563 vswap();
564 /* test if reload is needed for first register */
565 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
566 gv(rc2);
571 /* wrapper around RC_FRET to return a register by type */
572 int rc_fret(int t)
574 #ifdef TCC_TARGET_X86_64
575 if (t == VT_LDOUBLE) {
576 return RC_ST0;
578 #endif
579 return RC_FRET;
582 /* wrapper around REG_FRET to return a register by type */
583 int reg_fret(int t)
585 #ifdef TCC_TARGET_X86_64
586 if (t == VT_LDOUBLE) {
587 return TREG_ST0;
589 #endif
590 return REG_FRET;
593 /* expand long long on stack in two int registers */
594 void lexpand(void)
596 int u;
598 u = vtop->type.t & VT_UNSIGNED;
599 gv(RC_INT);
600 vdup();
601 vtop[0].r = vtop[-1].r2;
602 vtop[0].r2 = VT_CONST;
603 vtop[-1].r2 = VT_CONST;
604 vtop[0].type.t = VT_INT | u;
605 vtop[-1].type.t = VT_INT | u;
608 #ifdef TCC_TARGET_ARM
609 /* expand long long on stack */
610 void lexpand_nr(void)
612 int u,v;
614 u = vtop->type.t & VT_UNSIGNED;
615 vdup();
616 vtop->r2 = VT_CONST;
617 vtop->type.t = VT_INT | u;
618 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
619 if (v == VT_CONST) {
620 vtop[-1].c.ui = vtop->c.ull;
621 vtop->c.ui = vtop->c.ull >> 32;
622 vtop->r = VT_CONST;
623 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
624 vtop->c.ui += 4;
625 vtop->r = vtop[-1].r;
626 } else if (v > VT_CONST) {
627 vtop--;
628 lexpand();
629 } else
630 vtop->r = vtop[-1].r2;
631 vtop[-1].r2 = VT_CONST;
632 vtop[-1].type.t = VT_INT | u;
634 #endif
636 /* build a long long from two ints */
637 void lbuild(int t)
639 gv2(RC_INT, RC_INT);
640 vtop[-1].r2 = vtop[0].r;
641 vtop[-1].type.t = t;
642 vpop();
645 /* rotate n first stack elements to the bottom
646 I1 ... In -> I2 ... In I1 [top is right]
648 void vrotb(int n)
650 int i;
651 SValue tmp;
653 tmp = vtop[-n + 1];
654 for(i=-n+1;i!=0;i++)
655 vtop[i] = vtop[i+1];
656 vtop[0] = tmp;
659 /* rotate n first stack elements to the top
660 I1 ... In -> In I1 ... I(n-1) [top is right]
662 void vrott(int n)
664 int i;
665 SValue tmp;
667 tmp = vtop[0];
668 for(i = 0;i < n - 1; i++)
669 vtop[-i] = vtop[-i - 1];
670 vtop[-n + 1] = tmp;
673 #ifdef TCC_TARGET_ARM
674 /* like vrott but in other direction
675 In ... I1 -> I(n-1) ... I1 In [top is right]
677 void vnrott(int n)
679 int i;
680 SValue tmp;
682 tmp = vtop[-n + 1];
683 for(i = n - 1; i > 0; i--)
684 vtop[-i] = vtop[-i + 1];
685 vtop[0] = tmp;
687 #endif
689 /* pop stack value */
690 void vpop(void)
692 int v;
693 v = vtop->r & VT_VALMASK;
694 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
695 /* for x86, we need to pop the FP stack */
696 if (v == TREG_ST0 && !nocode_wanted) {
697 o(0xd8dd); /* fstp %st(0) */
698 } else
699 #endif
700 if (v == VT_JMP || v == VT_JMPI) {
701 /* need to put correct jump if && or || without test */
702 gsym(vtop->c.ul);
704 vtop--;
707 /* convert stack entry to register and duplicate its value in another
708 register */
709 void gv_dup(void)
711 int rc, t, r, r1;
712 SValue sv;
714 t = vtop->type.t;
715 if ((t & VT_BTYPE) == VT_LLONG) {
716 lexpand();
717 gv_dup();
718 vswap();
719 vrotb(3);
720 gv_dup();
721 vrotb(4);
722 /* stack: H L L1 H1 */
723 lbuild(t);
724 vrotb(3);
725 vrotb(3);
726 vswap();
727 lbuild(t);
728 vswap();
729 } else {
730 /* duplicate value */
731 rc = RC_INT;
732 sv.type.t = VT_INT;
733 if (is_float(t)) {
734 rc = RC_FLOAT;
735 #ifdef TCC_TARGET_X86_64
736 if ((t & VT_BTYPE) == VT_LDOUBLE) {
737 rc = RC_ST0;
739 #endif
740 sv.type.t = t;
742 r = gv(rc);
743 r1 = get_reg(rc);
744 sv.r = r;
745 sv.c.ul = 0;
746 load(r1, &sv); /* move r to r1 */
747 vdup();
748 /* duplicates value */
749 if (r != r1)
750 vtop->r = r1;
754 #ifndef TCC_TARGET_X86_64
755 /* generate CPU independent (unsigned) long long operations */
756 void gen_opl(int op)
758 int t, a, b, op1, c, i;
759 int func;
760 unsigned short reg_iret = REG_IRET;
761 unsigned short reg_lret = REG_LRET;
762 SValue tmp;
764 switch(op) {
765 case '/':
766 case TOK_PDIV:
767 func = TOK___divdi3;
768 goto gen_func;
769 case TOK_UDIV:
770 func = TOK___udivdi3;
771 goto gen_func;
772 case '%':
773 func = TOK___moddi3;
774 goto gen_mod_func;
775 case TOK_UMOD:
776 func = TOK___umoddi3;
777 gen_mod_func:
778 #ifdef TCC_ARM_EABI
779 reg_iret = TREG_R2;
780 reg_lret = TREG_R3;
781 #endif
782 gen_func:
783 /* call generic long long function */
784 vpush_global_sym(&func_old_type, func);
785 vrott(3);
786 gfunc_call(2);
787 vpushi(0);
788 vtop->r = reg_iret;
789 vtop->r2 = reg_lret;
790 break;
791 case '^':
792 case '&':
793 case '|':
794 case '*':
795 case '+':
796 case '-':
797 t = vtop->type.t;
798 vswap();
799 lexpand();
800 vrotb(3);
801 lexpand();
802 /* stack: L1 H1 L2 H2 */
803 tmp = vtop[0];
804 vtop[0] = vtop[-3];
805 vtop[-3] = tmp;
806 tmp = vtop[-2];
807 vtop[-2] = vtop[-3];
808 vtop[-3] = tmp;
809 vswap();
810 /* stack: H1 H2 L1 L2 */
811 if (op == '*') {
812 vpushv(vtop - 1);
813 vpushv(vtop - 1);
814 gen_op(TOK_UMULL);
815 lexpand();
816 /* stack: H1 H2 L1 L2 ML MH */
817 for(i=0;i<4;i++)
818 vrotb(6);
819 /* stack: ML MH H1 H2 L1 L2 */
820 tmp = vtop[0];
821 vtop[0] = vtop[-2];
822 vtop[-2] = tmp;
823 /* stack: ML MH H1 L2 H2 L1 */
824 gen_op('*');
825 vrotb(3);
826 vrotb(3);
827 gen_op('*');
828 /* stack: ML MH M1 M2 */
829 gen_op('+');
830 gen_op('+');
831 } else if (op == '+' || op == '-') {
832 /* XXX: add non carry method too (for MIPS or alpha) */
833 if (op == '+')
834 op1 = TOK_ADDC1;
835 else
836 op1 = TOK_SUBC1;
837 gen_op(op1);
838 /* stack: H1 H2 (L1 op L2) */
839 vrotb(3);
840 vrotb(3);
841 gen_op(op1 + 1); /* TOK_xxxC2 */
842 } else {
843 gen_op(op);
844 /* stack: H1 H2 (L1 op L2) */
845 vrotb(3);
846 vrotb(3);
847 /* stack: (L1 op L2) H1 H2 */
848 gen_op(op);
849 /* stack: (L1 op L2) (H1 op H2) */
851 /* stack: L H */
852 lbuild(t);
853 break;
854 case TOK_SAR:
855 case TOK_SHR:
856 case TOK_SHL:
857 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
858 t = vtop[-1].type.t;
859 vswap();
860 lexpand();
861 vrotb(3);
862 /* stack: L H shift */
863 c = (int)vtop->c.i;
864 /* constant: simpler */
865 /* NOTE: all comments are for SHL. the other cases are
866 done by swaping words */
867 vpop();
868 if (op != TOK_SHL)
869 vswap();
870 if (c >= 32) {
871 /* stack: L H */
872 vpop();
873 if (c > 32) {
874 vpushi(c - 32);
875 gen_op(op);
877 if (op != TOK_SAR) {
878 vpushi(0);
879 } else {
880 gv_dup();
881 vpushi(31);
882 gen_op(TOK_SAR);
884 vswap();
885 } else {
886 vswap();
887 gv_dup();
888 /* stack: H L L */
889 vpushi(c);
890 gen_op(op);
891 vswap();
892 vpushi(32 - c);
893 if (op == TOK_SHL)
894 gen_op(TOK_SHR);
895 else
896 gen_op(TOK_SHL);
897 vrotb(3);
898 /* stack: L L H */
899 vpushi(c);
900 if (op == TOK_SHL)
901 gen_op(TOK_SHL);
902 else
903 gen_op(TOK_SHR);
904 gen_op('|');
906 if (op != TOK_SHL)
907 vswap();
908 lbuild(t);
909 } else {
910 /* XXX: should provide a faster fallback on x86 ? */
911 switch(op) {
912 case TOK_SAR:
913 func = TOK___ashrdi3;
914 goto gen_func;
915 case TOK_SHR:
916 func = TOK___lshrdi3;
917 goto gen_func;
918 case TOK_SHL:
919 func = TOK___ashldi3;
920 goto gen_func;
923 break;
924 default:
925 /* compare operations */
926 t = vtop->type.t;
927 vswap();
928 lexpand();
929 vrotb(3);
930 lexpand();
931 /* stack: L1 H1 L2 H2 */
932 tmp = vtop[-1];
933 vtop[-1] = vtop[-2];
934 vtop[-2] = tmp;
935 /* stack: L1 L2 H1 H2 */
936 /* compare high */
937 op1 = op;
938 /* when values are equal, we need to compare low words. since
939 the jump is inverted, we invert the test too. */
940 if (op1 == TOK_LT)
941 op1 = TOK_LE;
942 else if (op1 == TOK_GT)
943 op1 = TOK_GE;
944 else if (op1 == TOK_ULT)
945 op1 = TOK_ULE;
946 else if (op1 == TOK_UGT)
947 op1 = TOK_UGE;
948 a = 0;
949 b = 0;
950 gen_op(op1);
951 if (op1 != TOK_NE) {
952 a = gtst(1, 0);
954 if (op != TOK_EQ) {
955 /* generate non equal test */
956 /* XXX: NOT PORTABLE yet */
957 if (a == 0) {
958 b = gtst(0, 0);
959 } else {
960 #if defined(TCC_TARGET_I386)
961 b = psym(0x850f, 0);
962 #elif defined(TCC_TARGET_ARM)
963 b = ind;
964 o(0x1A000000 | encbranch(ind, 0, 1));
965 #elif defined(TCC_TARGET_C67)
966 error("not implemented");
967 #else
968 #error not supported
969 #endif
972 /* compare low. Always unsigned */
973 op1 = op;
974 if (op1 == TOK_LT)
975 op1 = TOK_ULT;
976 else if (op1 == TOK_LE)
977 op1 = TOK_ULE;
978 else if (op1 == TOK_GT)
979 op1 = TOK_UGT;
980 else if (op1 == TOK_GE)
981 op1 = TOK_UGE;
982 gen_op(op1);
983 a = gtst(1, a);
984 gsym(b);
985 vseti(VT_JMPI, a);
986 break;
989 #endif
991 /* handle integer constant optimizations and various machine
992 independent opt */
993 void gen_opic(int op)
995 int c1, c2, t1, t2, n;
996 SValue *v1, *v2;
997 long long l1, l2;
998 typedef unsigned long long U;
1000 v1 = vtop - 1;
1001 v2 = vtop;
1002 t1 = v1->type.t & VT_BTYPE;
1003 t2 = v2->type.t & VT_BTYPE;
1005 if (t1 == VT_LLONG)
1006 l1 = v1->c.ll;
1007 else if (v1->type.t & VT_UNSIGNED)
1008 l1 = v1->c.ui;
1009 else
1010 l1 = v1->c.i;
1012 if (t2 == VT_LLONG)
1013 l2 = v2->c.ll;
1014 else if (v2->type.t & VT_UNSIGNED)
1015 l2 = v2->c.ui;
1016 else
1017 l2 = v2->c.i;
1019 /* currently, we cannot do computations with forward symbols */
1020 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1021 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1022 if (c1 && c2) {
1023 switch(op) {
1024 case '+': l1 += l2; break;
1025 case '-': l1 -= l2; break;
1026 case '&': l1 &= l2; break;
1027 case '^': l1 ^= l2; break;
1028 case '|': l1 |= l2; break;
1029 case '*': l1 *= l2; break;
1031 case TOK_PDIV:
1032 case '/':
1033 case '%':
1034 case TOK_UDIV:
1035 case TOK_UMOD:
1036 /* if division by zero, generate explicit division */
1037 if (l2 == 0) {
1038 if (const_wanted)
1039 error("division by zero in constant");
1040 goto general_case;
1042 switch(op) {
1043 default: l1 /= l2; break;
1044 case '%': l1 %= l2; break;
1045 case TOK_UDIV: l1 = (U)l1 / l2; break;
1046 case TOK_UMOD: l1 = (U)l1 % l2; break;
1048 break;
1049 case TOK_SHL: l1 <<= l2; break;
1050 case TOK_SHR: l1 = (U)l1 >> l2; break;
1051 case TOK_SAR: l1 >>= l2; break;
1052 /* tests */
1053 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1054 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1055 case TOK_EQ: l1 = l1 == l2; break;
1056 case TOK_NE: l1 = l1 != l2; break;
1057 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1058 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1059 case TOK_LT: l1 = l1 < l2; break;
1060 case TOK_GE: l1 = l1 >= l2; break;
1061 case TOK_LE: l1 = l1 <= l2; break;
1062 case TOK_GT: l1 = l1 > l2; break;
1063 /* logical */
1064 case TOK_LAND: l1 = l1 && l2; break;
1065 case TOK_LOR: l1 = l1 || l2; break;
1066 default:
1067 goto general_case;
1069 v1->c.ll = l1;
1070 vtop--;
1071 } else {
1072 /* if commutative ops, put c2 as constant */
1073 if (c1 && (op == '+' || op == '&' || op == '^' ||
1074 op == '|' || op == '*')) {
1075 vswap();
1076 c2 = c1; //c = c1, c1 = c2, c2 = c;
1077 l2 = l1; //l = l1, l1 = l2, l2 = l;
1079 /* Filter out NOP operations like x*1, x-0, x&-1... */
1080 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1081 op == TOK_PDIV) &&
1082 l2 == 1) ||
1083 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1084 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1085 l2 == 0) ||
1086 (op == '&' &&
1087 l2 == -1))) {
1088 /* nothing to do */
1089 vtop--;
1090 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1091 /* try to use shifts instead of muls or divs */
1092 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1093 n = -1;
1094 while (l2) {
1095 l2 >>= 1;
1096 n++;
1098 vtop->c.ll = n;
1099 if (op == '*')
1100 op = TOK_SHL;
1101 else if (op == TOK_PDIV)
1102 op = TOK_SAR;
1103 else
1104 op = TOK_SHR;
1106 goto general_case;
1107 } else if (c2 && (op == '+' || op == '-') &&
1108 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM)
1109 && !(vtop[-1].sym->type.t & VT_IMPORT))
1111 (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1112 /* symbol + constant case */
1113 if (op == '-')
1114 l2 = -l2;
1115 vtop--;
1116 vtop->c.ll += l2;
1117 } else {
1118 general_case:
1119 if (!nocode_wanted) {
1120 /* call low level op generator */
1121 if (t1 == VT_LLONG || t2 == VT_LLONG)
1122 gen_opl(op);
1123 else
1124 gen_opi(op);
1125 } else {
1126 vtop--;
1132 /* generate a floating point operation with constant propagation */
1133 void gen_opif(int op)
1135 int c1, c2;
1136 SValue *v1, *v2;
1137 long double f1, f2;
1139 v1 = vtop - 1;
1140 v2 = vtop;
1141 /* currently, we cannot do computations with forward symbols */
1142 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1143 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1144 if (c1 && c2) {
1145 if (v1->type.t == VT_FLOAT) {
1146 f1 = v1->c.f;
1147 f2 = v2->c.f;
1148 } else if (v1->type.t == VT_DOUBLE) {
1149 f1 = v1->c.d;
1150 f2 = v2->c.d;
1151 } else {
1152 f1 = v1->c.ld;
1153 f2 = v2->c.ld;
1156 /* NOTE: we only do constant propagation if finite number (not
1157 NaN or infinity) (ANSI spec) */
1158 if (!ieee_finite(f1) || !ieee_finite(f2))
1159 goto general_case;
1161 switch(op) {
1162 case '+': f1 += f2; break;
1163 case '-': f1 -= f2; break;
1164 case '*': f1 *= f2; break;
1165 case '/':
1166 if (f2 == 0.0) {
1167 if (const_wanted)
1168 error("division by zero in constant");
1169 goto general_case;
1171 f1 /= f2;
1172 break;
1173 /* XXX: also handles tests ? */
1174 default:
1175 goto general_case;
1177 /* XXX: overflow test ? */
1178 if (v1->type.t == VT_FLOAT) {
1179 v1->c.f = f1;
1180 } else if (v1->type.t == VT_DOUBLE) {
1181 v1->c.d = f1;
1182 } else {
1183 v1->c.ld = f1;
1185 vtop--;
1186 } else {
1187 general_case:
1188 if (!nocode_wanted) {
1189 gen_opf(op);
1190 } else {
1191 vtop--;
1196 static int pointed_size(CType *type)
1198 int align;
1199 return type_size(pointed_type(type), &align);
1202 static inline int is_null_pointer(SValue *p)
1204 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1205 return 0;
1206 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1207 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
1210 static inline int is_integer_btype(int bt)
1212 return (bt == VT_BYTE || bt == VT_SHORT ||
1213 bt == VT_INT || bt == VT_LLONG);
1216 /* check types for comparison or substraction of pointers */
1217 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1219 CType *type1, *type2, tmp_type1, tmp_type2;
1220 int bt1, bt2;
1222 /* null pointers are accepted for all comparisons as gcc */
1223 if (is_null_pointer(p1) || is_null_pointer(p2))
1224 return;
1225 type1 = &p1->type;
1226 type2 = &p2->type;
1227 bt1 = type1->t & VT_BTYPE;
1228 bt2 = type2->t & VT_BTYPE;
1229 /* accept comparison between pointer and integer with a warning */
1230 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1231 if (op != TOK_LOR && op != TOK_LAND )
1232 warning("comparison between pointer and integer");
1233 return;
1236 /* both must be pointers or implicit function pointers */
1237 if (bt1 == VT_PTR) {
1238 type1 = pointed_type(type1);
1239 } else if (bt1 != VT_FUNC)
1240 goto invalid_operands;
1242 if (bt2 == VT_PTR) {
1243 type2 = pointed_type(type2);
1244 } else if (bt2 != VT_FUNC) {
1245 invalid_operands:
1246 error("invalid operands to binary %s", get_tok_str(op, NULL));
1248 if ((type1->t & VT_BTYPE) == VT_VOID ||
1249 (type2->t & VT_BTYPE) == VT_VOID)
1250 return;
1251 tmp_type1 = *type1;
1252 tmp_type2 = *type2;
1253 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1254 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1255 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1256 /* gcc-like error if '-' is used */
1257 if (op == '-')
1258 goto invalid_operands;
1259 else
1260 warning("comparison of distinct pointer types lacks a cast");
1264 /* generic gen_op: handles types problems */
1265 void gen_op(int op)
1267 int u, t1, t2, bt1, bt2, t;
1268 CType type1;
1270 t1 = vtop[-1].type.t;
1271 t2 = vtop[0].type.t;
1272 bt1 = t1 & VT_BTYPE;
1273 bt2 = t2 & VT_BTYPE;
1275 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1276 /* at least one operand is a pointer */
1277 /* relationnal op: must be both pointers */
1278 if (op >= TOK_ULT && op <= TOK_LOR) {
1279 check_comparison_pointer_types(vtop - 1, vtop, op);
1280 /* pointers are handled are unsigned */
1281 #ifdef TCC_TARGET_X86_64
1282 t = VT_LLONG | VT_UNSIGNED;
1283 #else
1284 t = VT_INT | VT_UNSIGNED;
1285 #endif
1286 goto std_op;
1288 /* if both pointers, then it must be the '-' op */
1289 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1290 if (op != '-')
1291 error("cannot use pointers here");
1292 check_comparison_pointer_types(vtop - 1, vtop, op);
1293 /* XXX: check that types are compatible */
1294 u = pointed_size(&vtop[-1].type);
1295 gen_opic(op);
1296 /* set to integer type */
1297 #ifdef TCC_TARGET_X86_64
1298 vtop->type.t = VT_LLONG;
1299 #else
1300 vtop->type.t = VT_INT;
1301 #endif
1302 vpushi(u);
1303 gen_op(TOK_PDIV);
1304 } else {
1305 /* exactly one pointer : must be '+' or '-'. */
1306 if (op != '-' && op != '+')
1307 error("cannot use pointers here");
1308 /* Put pointer as first operand */
1309 if (bt2 == VT_PTR) {
1310 vswap();
1311 swap(&t1, &t2);
1313 type1 = vtop[-1].type;
1314 type1.t &= ~VT_ARRAY;
1315 #ifdef TCC_TARGET_X86_64
1316 vpushll(pointed_size(&vtop[-1].type));
1317 #else
1318 /* XXX: cast to int ? (long long case) */
1319 vpushi(pointed_size(&vtop[-1].type));
1320 #endif
1321 gen_op('*');
1322 #ifdef CONFIG_TCC_BCHECK
1323 /* if evaluating constant expression, no code should be
1324 generated, so no bound check */
1325 if (tcc_state->do_bounds_check && !const_wanted) {
1326 /* if bounded pointers, we generate a special code to
1327 test bounds */
1328 if (op == '-') {
1329 vpushi(0);
1330 vswap();
1331 gen_op('-');
1333 gen_bounded_ptr_add();
1334 } else
1335 #endif
1337 gen_opic(op);
1339 /* put again type if gen_opic() swaped operands */
1340 vtop->type = type1;
1342 } else if (is_float(bt1) || is_float(bt2)) {
1343 /* compute bigger type and do implicit casts */
1344 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1345 t = VT_LDOUBLE;
1346 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1347 t = VT_DOUBLE;
1348 } else {
1349 t = VT_FLOAT;
1351 /* floats can only be used for a few operations */
1352 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1353 (op < TOK_ULT || op > TOK_GT))
1354 error("invalid operands for binary operation");
1355 goto std_op;
1356 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1357 /* cast to biggest op */
1358 t = VT_LLONG;
1359 /* convert to unsigned if it does not fit in a long long */
1360 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1361 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1362 t |= VT_UNSIGNED;
1363 goto std_op;
1364 } else {
1365 /* integer operations */
1366 t = VT_INT;
1367 /* convert to unsigned if it does not fit in an integer */
1368 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1369 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1370 t |= VT_UNSIGNED;
1371 std_op:
1372 /* XXX: currently, some unsigned operations are explicit, so
1373 we modify them here */
1374 if (t & VT_UNSIGNED) {
1375 if (op == TOK_SAR)
1376 op = TOK_SHR;
1377 else if (op == '/')
1378 op = TOK_UDIV;
1379 else if (op == '%')
1380 op = TOK_UMOD;
1381 else if (op == TOK_LT)
1382 op = TOK_ULT;
1383 else if (op == TOK_GT)
1384 op = TOK_UGT;
1385 else if (op == TOK_LE)
1386 op = TOK_ULE;
1387 else if (op == TOK_GE)
1388 op = TOK_UGE;
1390 vswap();
1391 type1.t = t;
1392 gen_cast(&type1);
1393 vswap();
1394 /* special case for shifts and long long: we keep the shift as
1395 an integer */
1396 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1397 type1.t = VT_INT;
1398 gen_cast(&type1);
1399 if (is_float(t))
1400 gen_opif(op);
1401 else
1402 gen_opic(op);
1403 if (op >= TOK_ULT && op <= TOK_GT) {
1404 /* relationnal op: the result is an int */
1405 vtop->type.t = VT_INT;
1406 } else {
1407 vtop->type.t = t;
1412 #ifndef TCC_TARGET_ARM
1413 /* generic itof for unsigned long long case */
1414 void gen_cvt_itof1(int t)
1416 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1417 (VT_LLONG | VT_UNSIGNED)) {
1419 if (t == VT_FLOAT)
1420 vpush_global_sym(&func_old_type, TOK___floatundisf);
1421 #if LDOUBLE_SIZE != 8
1422 else if (t == VT_LDOUBLE)
1423 vpush_global_sym(&func_old_type, TOK___floatundixf);
1424 #endif
1425 else
1426 vpush_global_sym(&func_old_type, TOK___floatundidf);
1427 vrott(2);
1428 gfunc_call(1);
1429 vpushi(0);
1430 vtop->r = reg_fret(t);
1431 } else {
1432 gen_cvt_itof(t);
1435 #endif
1437 /* generic ftoi for unsigned long long case */
1438 void gen_cvt_ftoi1(int t)
1440 int st;
1442 if (t == (VT_LLONG | VT_UNSIGNED)) {
1443 /* not handled natively */
1444 st = vtop->type.t & VT_BTYPE;
1445 if (st == VT_FLOAT)
1446 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1447 #if LDOUBLE_SIZE != 8
1448 else if (st == VT_LDOUBLE)
1449 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1450 #endif
1451 else
1452 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1453 vrott(2);
1454 gfunc_call(1);
1455 vpushi(0);
1456 vtop->r = REG_IRET;
1457 vtop->r2 = REG_LRET;
1458 } else {
1459 gen_cvt_ftoi(t);
1463 /* force char or short cast */
1464 void force_charshort_cast(int t)
1466 int bits, dbt;
1467 dbt = t & VT_BTYPE;
1468 /* XXX: add optimization if lvalue : just change type and offset */
1469 if (dbt == VT_BYTE)
1470 bits = 8;
1471 else
1472 bits = 16;
1473 if (t & VT_UNSIGNED) {
1474 vpushi((1 << bits) - 1);
1475 gen_op('&');
1476 } else {
1477 bits = 32 - bits;
1478 vpushi(bits);
1479 gen_op(TOK_SHL);
1480 /* result must be signed or the SAR is converted to an SHL
1481 This was not the case when "t" was a signed short
1482 and the last value on the stack was an unsigned int */
1483 vtop->type.t &= ~VT_UNSIGNED;
1484 vpushi(bits);
1485 gen_op(TOK_SAR);
1489 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1490 static void gen_cast(CType *type)
1492 int sbt, dbt, sf, df, c, p;
1494 /* special delayed cast for char/short */
1495 /* XXX: in some cases (multiple cascaded casts), it may still
1496 be incorrect */
1497 if (vtop->r & VT_MUSTCAST) {
1498 vtop->r &= ~VT_MUSTCAST;
1499 force_charshort_cast(vtop->type.t);
1502 /* bitfields first get cast to ints */
1503 if (vtop->type.t & VT_BITFIELD) {
1504 gv(RC_INT);
1507 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1508 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1510 if (sbt != dbt) {
1511 sf = is_float(sbt);
1512 df = is_float(dbt);
1513 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1514 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1515 if (c) {
1516 /* constant case: we can do it now */
1517 /* XXX: in ISOC, cannot do it if error in convert */
1518 if (sbt == VT_FLOAT)
1519 vtop->c.ld = vtop->c.f;
1520 else if (sbt == VT_DOUBLE)
1521 vtop->c.ld = vtop->c.d;
1523 if (df) {
1524 if ((sbt & VT_BTYPE) == VT_LLONG) {
1525 if (sbt & VT_UNSIGNED)
1526 vtop->c.ld = vtop->c.ull;
1527 else
1528 vtop->c.ld = vtop->c.ll;
1529 } else if(!sf) {
1530 if (sbt & VT_UNSIGNED)
1531 vtop->c.ld = vtop->c.ui;
1532 else
1533 vtop->c.ld = vtop->c.i;
1536 if (dbt == VT_FLOAT)
1537 vtop->c.f = (float)vtop->c.ld;
1538 else if (dbt == VT_DOUBLE)
1539 vtop->c.d = (double)vtop->c.ld;
1540 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1541 vtop->c.ull = (unsigned long long)vtop->c.ld;
1542 } else if (sf && dbt == VT_BOOL) {
1543 vtop->c.i = (vtop->c.ld != 0);
1544 } else {
1545 if(sf)
1546 vtop->c.ll = (long long)vtop->c.ld;
1547 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1548 vtop->c.ll = vtop->c.ull;
1549 else if (sbt & VT_UNSIGNED)
1550 vtop->c.ll = vtop->c.ui;
1551 #ifdef TCC_TARGET_X86_64
1552 else if (sbt == VT_PTR)
1554 #endif
1555 else if (sbt != VT_LLONG)
1556 vtop->c.ll = vtop->c.i;
1558 if (dbt == (VT_LLONG|VT_UNSIGNED))
1559 vtop->c.ull = vtop->c.ll;
1560 else if (dbt == VT_BOOL)
1561 vtop->c.i = (vtop->c.ll != 0);
1562 else if (dbt != VT_LLONG) {
1563 int s = 0;
1564 if ((dbt & VT_BTYPE) == VT_BYTE)
1565 s = 24;
1566 else if ((dbt & VT_BTYPE) == VT_SHORT)
1567 s = 16;
1569 if(dbt & VT_UNSIGNED)
1570 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1571 else
1572 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1575 } else if (p && dbt == VT_BOOL) {
1576 vtop->r = VT_CONST;
1577 vtop->c.i = 1;
1578 } else if (!nocode_wanted) {
1579 /* non constant case: generate code */
1580 if (sf && df) {
1581 /* convert from fp to fp */
1582 gen_cvt_ftof(dbt);
1583 } else if (df) {
1584 /* convert int to fp */
1585 gen_cvt_itof1(dbt);
1586 } else if (sf) {
1587 /* convert fp to int */
1588 if (dbt == VT_BOOL) {
1589 vpushi(0);
1590 gen_op(TOK_NE);
1591 } else {
1592 /* we handle char/short/etc... with generic code */
1593 if (dbt != (VT_INT | VT_UNSIGNED) &&
1594 dbt != (VT_LLONG | VT_UNSIGNED) &&
1595 dbt != VT_LLONG)
1596 dbt = VT_INT;
1597 gen_cvt_ftoi1(dbt);
1598 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1599 /* additional cast for char/short... */
1600 vtop->type.t = dbt;
1601 gen_cast(type);
1604 #ifndef TCC_TARGET_X86_64
1605 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1606 if ((sbt & VT_BTYPE) != VT_LLONG) {
1607 /* scalar to long long */
1608 /* machine independent conversion */
1609 gv(RC_INT);
1610 /* generate high word */
1611 if (sbt == (VT_INT | VT_UNSIGNED)) {
1612 vpushi(0);
1613 gv(RC_INT);
1614 } else {
1615 if (sbt == VT_PTR) {
1616 /* cast from pointer to int before we apply
1617 shift operation, which pointers don't support*/
1618 gen_cast(&int_type);
1620 gv_dup();
1621 vpushi(31);
1622 gen_op(TOK_SAR);
1624 /* patch second register */
1625 vtop[-1].r2 = vtop->r;
1626 vpop();
1628 #else
1629 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1630 (dbt & VT_BTYPE) == VT_PTR) {
1631 /* XXX: not sure if this is perfect... need more tests */
1632 if ((sbt & VT_BTYPE) != VT_LLONG) {
1633 int r = gv(RC_INT);
1634 if (sbt != (VT_INT | VT_UNSIGNED) &&
1635 sbt != VT_PTR && sbt != VT_FUNC) {
1636 /* x86_64 specific: movslq */
1637 o(0x6348);
1638 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
1641 #endif
1642 } else if (dbt == VT_BOOL) {
1643 /* scalar to bool */
1644 vpushi(0);
1645 gen_op(TOK_NE);
1646 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
1647 (dbt & VT_BTYPE) == VT_SHORT) {
1648 if (sbt == VT_PTR) {
1649 vtop->type.t = VT_INT;
1650 warning("nonportable conversion from pointer to char/short");
1652 force_charshort_cast(dbt);
1653 } else if ((dbt & VT_BTYPE) == VT_INT) {
1654 /* scalar to int */
1655 if (sbt == VT_LLONG) {
1656 /* from long long: just take low order word */
1657 lexpand();
1658 vpop();
1660 /* if lvalue and single word type, nothing to do because
1661 the lvalue already contains the real type size (see
1662 VT_LVAL_xxx constants) */
1665 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
1666 /* if we are casting between pointer types,
1667 we must update the VT_LVAL_xxx size */
1668 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
1669 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
1671 vtop->type = *type;
1674 /* return type size. Put alignment at 'a' */
1675 static int type_size(CType *type, int *a)
1677 Sym *s;
1678 int bt;
1680 bt = type->t & VT_BTYPE;
1681 if (bt == VT_STRUCT) {
1682 /* struct/union */
1683 s = type->ref;
1684 *a = s->r;
1685 return s->c;
1686 } else if (bt == VT_PTR) {
1687 if (type->t & VT_ARRAY) {
1688 int ts;
1690 s = type->ref;
1691 ts = type_size(&s->type, a);
1693 if (ts < 0 && s->c < 0)
1694 ts = -ts;
1696 return ts * s->c;
1697 } else {
1698 *a = PTR_SIZE;
1699 return PTR_SIZE;
1701 } else if (bt == VT_LDOUBLE) {
1702 *a = LDOUBLE_ALIGN;
1703 return LDOUBLE_SIZE;
1704 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
1705 #ifdef TCC_TARGET_I386
1706 #ifdef TCC_TARGET_PE
1707 *a = 8;
1708 #else
1709 *a = 4;
1710 #endif
1711 #elif defined(TCC_TARGET_ARM)
1712 #ifdef TCC_ARM_EABI
1713 *a = 8;
1714 #else
1715 *a = 4;
1716 #endif
1717 #else
1718 *a = 8;
1719 #endif
1720 return 8;
1721 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
1722 *a = 4;
1723 return 4;
1724 } else if (bt == VT_SHORT) {
1725 *a = 2;
1726 return 2;
1727 } else {
1728 /* char, void, function, _Bool */
1729 *a = 1;
1730 return 1;
1734 /* return the pointed type of t */
1735 static inline CType *pointed_type(CType *type)
1737 return &type->ref->type;
1740 /* modify type so that its it is a pointer to type. */
1741 static void mk_pointer(CType *type)
1743 Sym *s;
1744 s = sym_push(SYM_FIELD, type, 0, -1);
1745 type->t = VT_PTR | (type->t & ~VT_TYPE);
1746 type->ref = s;
1749 /* compare function types. OLD functions match any new functions */
1750 static int is_compatible_func(CType *type1, CType *type2)
1752 Sym *s1, *s2;
1754 s1 = type1->ref;
1755 s2 = type2->ref;
1756 if (!is_compatible_types(&s1->type, &s2->type))
1757 return 0;
1758 /* check func_call */
1759 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
1760 return 0;
1761 /* XXX: not complete */
1762 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
1763 return 1;
1764 if (s1->c != s2->c)
1765 return 0;
1766 while (s1 != NULL) {
1767 if (s2 == NULL)
1768 return 0;
1769 if (!is_compatible_parameter_types(&s1->type, &s2->type))
1770 return 0;
1771 s1 = s1->next;
1772 s2 = s2->next;
1774 if (s2)
1775 return 0;
1776 return 1;
1779 /* return true if type1 and type2 are the same. If unqualified is
1780 true, qualifiers on the types are ignored.
1782 - enums are not checked as gcc __builtin_types_compatible_p ()
1784 static int compare_types(CType *type1, CType *type2, int unqualified)
1786 int bt1, t1, t2;
1788 t1 = type1->t & VT_TYPE;
1789 t2 = type2->t & VT_TYPE;
1790 if (unqualified) {
1791 /* strip qualifiers before comparing */
1792 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
1793 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
1795 /* XXX: bitfields ? */
1796 if (t1 != t2)
1797 return 0;
1798 /* test more complicated cases */
1799 bt1 = t1 & VT_BTYPE;
1800 if (bt1 == VT_PTR) {
1801 type1 = pointed_type(type1);
1802 type2 = pointed_type(type2);
1803 return is_compatible_types(type1, type2);
1804 } else if (bt1 == VT_STRUCT) {
1805 return (type1->ref == type2->ref);
1806 } else if (bt1 == VT_FUNC) {
1807 return is_compatible_func(type1, type2);
1808 } else {
1809 return 1;
1813 /* return true if type1 and type2 are exactly the same (including
1814 qualifiers).
1816 static int is_compatible_types(CType *type1, CType *type2)
1818 return compare_types(type1,type2,0);
1821 /* return true if type1 and type2 are the same (ignoring qualifiers).
1823 static int is_compatible_parameter_types(CType *type1, CType *type2)
1825 return compare_types(type1,type2,1);
1828 /* print a type. If 'varstr' is not NULL, then the variable is also
1829 printed in the type */
1830 /* XXX: union */
1831 /* XXX: add array and function pointers */
1832 void type_to_str(char *buf, int buf_size,
1833 CType *type, const char *varstr)
1835 int bt, v, t;
1836 Sym *s, *sa;
1837 char buf1[256];
1838 const char *tstr;
1840 t = type->t & VT_TYPE;
1841 bt = t & VT_BTYPE;
1842 buf[0] = '\0';
1843 if (t & VT_CONSTANT)
1844 pstrcat(buf, buf_size, "const ");
1845 if (t & VT_VOLATILE)
1846 pstrcat(buf, buf_size, "volatile ");
1847 if (t & VT_UNSIGNED)
1848 pstrcat(buf, buf_size, "unsigned ");
1849 switch(bt) {
1850 case VT_VOID:
1851 tstr = "void";
1852 goto add_tstr;
1853 case VT_BOOL:
1854 tstr = "_Bool";
1855 goto add_tstr;
1856 case VT_BYTE:
1857 tstr = "char";
1858 goto add_tstr;
1859 case VT_SHORT:
1860 tstr = "short";
1861 goto add_tstr;
1862 case VT_INT:
1863 tstr = "int";
1864 goto add_tstr;
1865 case VT_LONG:
1866 tstr = "long";
1867 goto add_tstr;
1868 case VT_LLONG:
1869 tstr = "long long";
1870 goto add_tstr;
1871 case VT_FLOAT:
1872 tstr = "float";
1873 goto add_tstr;
1874 case VT_DOUBLE:
1875 tstr = "double";
1876 goto add_tstr;
1877 case VT_LDOUBLE:
1878 tstr = "long double";
1879 add_tstr:
1880 pstrcat(buf, buf_size, tstr);
1881 break;
1882 case VT_ENUM:
1883 case VT_STRUCT:
1884 if (bt == VT_STRUCT)
1885 tstr = "struct ";
1886 else
1887 tstr = "enum ";
1888 pstrcat(buf, buf_size, tstr);
1889 v = type->ref->v & ~SYM_STRUCT;
1890 if (v >= SYM_FIRST_ANOM)
1891 pstrcat(buf, buf_size, "<anonymous>");
1892 else
1893 pstrcat(buf, buf_size, get_tok_str(v, NULL));
1894 break;
1895 case VT_FUNC:
1896 s = type->ref;
1897 type_to_str(buf, buf_size, &s->type, varstr);
1898 pstrcat(buf, buf_size, "(");
1899 sa = s->next;
1900 while (sa != NULL) {
1901 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
1902 pstrcat(buf, buf_size, buf1);
1903 sa = sa->next;
1904 if (sa)
1905 pstrcat(buf, buf_size, ", ");
1907 pstrcat(buf, buf_size, ")");
1908 goto no_var;
1909 case VT_PTR:
1910 s = type->ref;
1911 pstrcpy(buf1, sizeof(buf1), "*");
1912 if (varstr)
1913 pstrcat(buf1, sizeof(buf1), varstr);
1914 type_to_str(buf, buf_size, &s->type, buf1);
1915 goto no_var;
1917 if (varstr) {
1918 pstrcat(buf, buf_size, " ");
1919 pstrcat(buf, buf_size, varstr);
1921 no_var: ;
1924 /* verify type compatibility to store vtop in 'dt' type, and generate
1925 casts if needed. */
1926 static void gen_assign_cast(CType *dt)
1928 CType *st, *type1, *type2, tmp_type1, tmp_type2;
1929 char buf1[256], buf2[256];
1930 int dbt, sbt;
1932 st = &vtop->type; /* source type */
1933 dbt = dt->t & VT_BTYPE;
1934 sbt = st->t & VT_BTYPE;
1935 if (dt->t & VT_CONSTANT)
1936 warning("assignment of read-only location");
1937 switch(dbt) {
1938 case VT_PTR:
1939 /* special cases for pointers */
1940 /* '0' can also be a pointer */
1941 if (is_null_pointer(vtop))
1942 goto type_ok;
1943 /* accept implicit pointer to integer cast with warning */
1944 if (is_integer_btype(sbt)) {
1945 warning("assignment makes pointer from integer without a cast");
1946 goto type_ok;
1948 type1 = pointed_type(dt);
1949 /* a function is implicitely a function pointer */
1950 if (sbt == VT_FUNC) {
1951 if ((type1->t & VT_BTYPE) != VT_VOID &&
1952 !is_compatible_types(pointed_type(dt), st))
1953 warning("assignment from incompatible pointer type");
1954 goto type_ok;
1956 if (sbt != VT_PTR)
1957 goto error;
1958 type2 = pointed_type(st);
1959 if ((type1->t & VT_BTYPE) == VT_VOID ||
1960 (type2->t & VT_BTYPE) == VT_VOID) {
1961 /* void * can match anything */
1962 } else {
1963 /* exact type match, except for unsigned */
1964 tmp_type1 = *type1;
1965 tmp_type2 = *type2;
1966 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1967 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1968 if (!is_compatible_types(&tmp_type1, &tmp_type2))
1969 warning("assignment from incompatible pointer type");
1971 /* check const and volatile */
1972 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
1973 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
1974 warning("assignment discards qualifiers from pointer target type");
1975 break;
1976 case VT_BYTE:
1977 case VT_SHORT:
1978 case VT_INT:
1979 case VT_LLONG:
1980 if (sbt == VT_PTR || sbt == VT_FUNC) {
1981 warning("assignment makes integer from pointer without a cast");
1983 /* XXX: more tests */
1984 break;
1985 case VT_STRUCT:
1986 tmp_type1 = *dt;
1987 tmp_type2 = *st;
1988 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
1989 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
1990 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1991 error:
1992 type_to_str(buf1, sizeof(buf1), st, NULL);
1993 type_to_str(buf2, sizeof(buf2), dt, NULL);
1994 error("cannot cast '%s' to '%s'", buf1, buf2);
1996 break;
1998 type_ok:
1999 gen_cast(dt);
2002 /* store vtop in lvalue pushed on stack */
2003 void vstore(void)
2005 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2007 ft = vtop[-1].type.t;
2008 sbt = vtop->type.t & VT_BTYPE;
2009 dbt = ft & VT_BTYPE;
2010 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2011 (sbt == VT_INT && dbt == VT_SHORT)) {
2012 /* optimize char/short casts */
2013 delayed_cast = VT_MUSTCAST;
2014 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2015 /* XXX: factorize */
2016 if (ft & VT_CONSTANT)
2017 warning("assignment of read-only location");
2018 } else {
2019 delayed_cast = 0;
2020 if (!(ft & VT_BITFIELD))
2021 gen_assign_cast(&vtop[-1].type);
2024 if (sbt == VT_STRUCT) {
2025 /* if structure, only generate pointer */
2026 /* structure assignment : generate memcpy */
2027 /* XXX: optimize if small size */
2028 if (!nocode_wanted) {
2029 size = type_size(&vtop->type, &align);
2031 /* destination */
2032 vswap();
2033 vtop->type.t = VT_PTR;
2034 gaddrof();
2036 /* address of memcpy() */
2037 #ifdef TCC_ARM_EABI
2038 if(!(align & 7))
2039 vpush_global_sym(&func_old_type, TOK_memcpy8);
2040 else if(!(align & 3))
2041 vpush_global_sym(&func_old_type, TOK_memcpy4);
2042 else
2043 #endif
2044 vpush_global_sym(&func_old_type, TOK_memcpy);
2046 vswap();
2047 /* source */
2048 vpushv(vtop - 2);
2049 vtop->type.t = VT_PTR;
2050 gaddrof();
2051 /* type size */
2052 vpushi(size);
2053 gfunc_call(3);
2054 } else {
2055 vswap();
2056 vpop();
2058 /* leave source on stack */
2059 } else if (ft & VT_BITFIELD) {
2060 /* bitfield store handling */
2061 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2062 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2063 /* remove bit field info to avoid loops */
2064 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2066 /* duplicate source into other register */
2067 gv_dup();
2068 vswap();
2069 vrott(3);
2071 if((ft & VT_BTYPE) == VT_BOOL) {
2072 gen_cast(&vtop[-1].type);
2073 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2076 /* duplicate destination */
2077 vdup();
2078 vtop[-1] = vtop[-2];
2080 /* mask and shift source */
2081 if((ft & VT_BTYPE) != VT_BOOL) {
2082 if((ft & VT_BTYPE) == VT_LLONG) {
2083 vpushll((1ULL << bit_size) - 1ULL);
2084 } else {
2085 vpushi((1 << bit_size) - 1);
2087 gen_op('&');
2089 vpushi(bit_pos);
2090 gen_op(TOK_SHL);
2091 /* load destination, mask and or with source */
2092 vswap();
2093 if((ft & VT_BTYPE) == VT_LLONG) {
2094 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2095 } else {
2096 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2098 gen_op('&');
2099 gen_op('|');
2100 /* store result */
2101 vstore();
2103 /* pop off shifted source from "duplicate source..." above */
2104 vpop();
2106 } else {
2107 #ifdef CONFIG_TCC_BCHECK
2108 /* bound check case */
2109 if (vtop[-1].r & VT_MUSTBOUND) {
2110 vswap();
2111 gbound();
2112 vswap();
2114 #endif
2115 if (!nocode_wanted) {
2116 rc = RC_INT;
2117 if (is_float(ft)) {
2118 rc = RC_FLOAT;
2119 #ifdef TCC_TARGET_X86_64
2120 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2121 rc = RC_ST0;
2123 #endif
2125 r = gv(rc); /* generate value */
2126 /* if lvalue was saved on stack, must read it */
2127 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2128 SValue sv;
2129 t = get_reg(RC_INT);
2130 #ifdef TCC_TARGET_X86_64
2131 sv.type.t = VT_PTR;
2132 #else
2133 sv.type.t = VT_INT;
2134 #endif
2135 sv.r = VT_LOCAL | VT_LVAL;
2136 sv.c.ul = vtop[-1].c.ul;
2137 load(t, &sv);
2138 vtop[-1].r = t | VT_LVAL;
2140 store(r, vtop - 1);
2141 #ifndef TCC_TARGET_X86_64
2142 /* two word case handling : store second register at word + 4 */
2143 if ((ft & VT_BTYPE) == VT_LLONG) {
2144 vswap();
2145 /* convert to int to increment easily */
2146 vtop->type.t = VT_INT;
2147 gaddrof();
2148 vpushi(4);
2149 gen_op('+');
2150 vtop->r |= VT_LVAL;
2151 vswap();
2152 /* XXX: it works because r2 is spilled last ! */
2153 store(vtop->r2, vtop - 1);
2155 #endif
2157 vswap();
2158 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2159 vtop->r |= delayed_cast;
2163 /* post defines POST/PRE add. c is the token ++ or -- */
2164 void inc(int post, int c)
2166 test_lvalue();
2167 vdup(); /* save lvalue */
2168 if (post) {
2169 gv_dup(); /* duplicate value */
2170 vrotb(3);
2171 vrotb(3);
2173 /* add constant */
2174 vpushi(c - TOK_MID);
2175 gen_op('+');
2176 vstore(); /* store value */
2177 if (post)
2178 vpop(); /* if post op, return saved value */
2181 /* Parse GNUC __attribute__ extension. Currently, the following
2182 extensions are recognized:
2183 - aligned(n) : set data/function alignment.
2184 - packed : force data alignment to 1
2185 - section(x) : generate data/code in this section.
2186 - unused : currently ignored, but may be used someday.
2187 - regparm(n) : pass function parameters in registers (i386 only)
2189 static void parse_attribute(AttributeDef *ad)
2191 int t, n;
2193 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2194 next();
2195 skip('(');
2196 skip('(');
2197 while (tok != ')') {
2198 if (tok < TOK_IDENT)
2199 expect("attribute name");
2200 t = tok;
2201 next();
2202 switch(t) {
2203 case TOK_SECTION1:
2204 case TOK_SECTION2:
2205 skip('(');
2206 if (tok != TOK_STR)
2207 expect("section name");
2208 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2209 next();
2210 skip(')');
2211 break;
2212 case TOK_ALIGNED1:
2213 case TOK_ALIGNED2:
2214 if (tok == '(') {
2215 next();
2216 n = expr_const();
2217 if (n <= 0 || (n & (n - 1)) != 0)
2218 error("alignment must be a positive power of two");
2219 skip(')');
2220 } else {
2221 n = MAX_ALIGN;
2223 ad->aligned = n;
2224 break;
2225 case TOK_PACKED1:
2226 case TOK_PACKED2:
2227 ad->packed = 1;
2228 break;
2229 case TOK_UNUSED1:
2230 case TOK_UNUSED2:
2231 /* currently, no need to handle it because tcc does not
2232 track unused objects */
2233 break;
2234 case TOK_NORETURN1:
2235 case TOK_NORETURN2:
2236 /* currently, no need to handle it because tcc does not
2237 track unused objects */
2238 break;
2239 case TOK_CDECL1:
2240 case TOK_CDECL2:
2241 case TOK_CDECL3:
2242 ad->func_call = FUNC_CDECL;
2243 break;
2244 case TOK_STDCALL1:
2245 case TOK_STDCALL2:
2246 case TOK_STDCALL3:
2247 ad->func_call = FUNC_STDCALL;
2248 break;
2249 #ifdef TCC_TARGET_I386
2250 case TOK_REGPARM1:
2251 case TOK_REGPARM2:
2252 skip('(');
2253 n = expr_const();
2254 if (n > 3)
2255 n = 3;
2256 else if (n < 0)
2257 n = 0;
2258 if (n > 0)
2259 ad->func_call = FUNC_FASTCALL1 + n - 1;
2260 skip(')');
2261 break;
2262 case TOK_FASTCALL1:
2263 case TOK_FASTCALL2:
2264 case TOK_FASTCALL3:
2265 ad->func_call = FUNC_FASTCALLW;
2266 break;
2267 #endif
2268 case TOK_DLLEXPORT:
2269 ad->func_export = 1;
2270 break;
2271 case TOK_DLLIMPORT:
2272 ad->func_import = 1;
2273 break;
2274 default:
2275 if (tcc_state->warn_unsupported)
2276 warning("'%s' attribute ignored", get_tok_str(t, NULL));
2277 /* skip parameters */
2278 if (tok == '(') {
2279 int parenthesis = 0;
2280 do {
2281 if (tok == '(')
2282 parenthesis++;
2283 else if (tok == ')')
2284 parenthesis--;
2285 next();
2286 } while (parenthesis && tok != -1);
2288 break;
2290 if (tok != ',')
2291 break;
2292 next();
2294 skip(')');
2295 skip(')');
2299 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2300 static void struct_decl(CType *type, int u)
2302 int a, v, size, align, maxalign, c, offset;
2303 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2304 Sym *s, *ss, *ass, **ps;
2305 AttributeDef ad;
2306 CType type1, btype;
2308 a = tok; /* save decl type */
2309 next();
2310 if (tok != '{') {
2311 v = tok;
2312 next();
2313 /* struct already defined ? return it */
2314 if (v < TOK_IDENT)
2315 expect("struct/union/enum name");
2316 s = struct_find(v);
2317 if (s) {
2318 if (s->type.t != a)
2319 error("invalid type");
2320 goto do_decl;
2322 } else {
2323 v = anon_sym++;
2325 type1.t = a;
2326 /* we put an undefined size for struct/union */
2327 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2328 s->r = 0; /* default alignment is zero as gcc */
2329 /* put struct/union/enum name in type */
2330 do_decl:
2331 type->t = u;
2332 type->ref = s;
2334 if (tok == '{') {
2335 next();
2336 if (s->c != -1)
2337 error("struct/union/enum already defined");
2338 /* cannot be empty */
2339 c = 0;
2340 /* non empty enums are not allowed */
2341 if (a == TOK_ENUM) {
2342 for(;;) {
2343 v = tok;
2344 if (v < TOK_UIDENT)
2345 expect("identifier");
2346 next();
2347 if (tok == '=') {
2348 next();
2349 c = expr_const();
2351 /* enum symbols have static storage */
2352 ss = sym_push(v, &int_type, VT_CONST, c);
2353 ss->type.t |= VT_STATIC;
2354 if (tok != ',')
2355 break;
2356 next();
2357 c++;
2358 /* NOTE: we accept a trailing comma */
2359 if (tok == '}')
2360 break;
2362 skip('}');
2363 } else {
2364 maxalign = 1;
2365 ps = &s->next;
2366 prevbt = VT_INT;
2367 bit_pos = 0;
2368 offset = 0;
2369 while (tok != '}') {
2370 parse_btype(&btype, &ad);
2371 while (1) {
2372 bit_size = -1;
2373 v = 0;
2374 type1 = btype;
2375 if (tok != ':') {
2376 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2377 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2378 expect("identifier");
2379 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2380 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2381 error("invalid type for '%s'",
2382 get_tok_str(v, NULL));
2384 if (tok == ':') {
2385 next();
2386 bit_size = expr_const();
2387 /* XXX: handle v = 0 case for messages */
2388 if (bit_size < 0)
2389 error("negative width in bit-field '%s'",
2390 get_tok_str(v, NULL));
2391 if (v && bit_size == 0)
2392 error("zero width for bit-field '%s'",
2393 get_tok_str(v, NULL));
2395 size = type_size(&type1, &align);
2396 if (ad.aligned) {
2397 if (align < ad.aligned)
2398 align = ad.aligned;
2399 } else if (ad.packed) {
2400 align = 1;
2401 } else if (*tcc_state->pack_stack_ptr) {
2402 if (align > *tcc_state->pack_stack_ptr)
2403 align = *tcc_state->pack_stack_ptr;
2405 lbit_pos = 0;
2406 if (bit_size >= 0) {
2407 bt = type1.t & VT_BTYPE;
2408 if (bt != VT_INT &&
2409 bt != VT_BYTE &&
2410 bt != VT_SHORT &&
2411 bt != VT_BOOL &&
2412 bt != VT_ENUM &&
2413 bt != VT_LLONG)
2414 error("bitfields must have scalar type");
2415 bsize = size * 8;
2416 if (bit_size > bsize) {
2417 error("width of '%s' exceeds its type",
2418 get_tok_str(v, NULL));
2419 } else if (bit_size == bsize) {
2420 /* no need for bit fields */
2421 bit_pos = 0;
2422 } else if (bit_size == 0) {
2423 /* XXX: what to do if only padding in a
2424 structure ? */
2425 /* zero size: means to pad */
2426 bit_pos = 0;
2427 } else {
2428 /* we do not have enough room ?
2429 did the type change?
2430 is it a union? */
2431 if ((bit_pos + bit_size) > bsize ||
2432 bt != prevbt || a == TOK_UNION)
2433 bit_pos = 0;
2434 lbit_pos = bit_pos;
2435 /* XXX: handle LSB first */
2436 type1.t |= VT_BITFIELD |
2437 (bit_pos << VT_STRUCT_SHIFT) |
2438 (bit_size << (VT_STRUCT_SHIFT + 6));
2439 bit_pos += bit_size;
2441 prevbt = bt;
2442 } else {
2443 bit_pos = 0;
2445 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2446 /* add new memory data only if starting
2447 bit field */
2448 if (lbit_pos == 0) {
2449 if (a == TOK_STRUCT) {
2450 c = (c + align - 1) & -align;
2451 offset = c;
2452 if (size > 0)
2453 c += size;
2454 } else {
2455 offset = 0;
2456 if (size > c)
2457 c = size;
2459 if (align > maxalign)
2460 maxalign = align;
2462 #if 0
2463 printf("add field %s offset=%d",
2464 get_tok_str(v, NULL), offset);
2465 if (type1.t & VT_BITFIELD) {
2466 printf(" pos=%d size=%d",
2467 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2468 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2470 printf("\n");
2471 #endif
2473 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2474 ass = type1.ref;
2475 while ((ass = ass->next) != NULL) {
2476 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2477 *ps = ss;
2478 ps = &ss->next;
2480 } else if (v) {
2481 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2482 *ps = ss;
2483 ps = &ss->next;
2485 if (tok == ';' || tok == TOK_EOF)
2486 break;
2487 skip(',');
2489 skip(';');
2491 skip('}');
2492 /* store size and alignment */
2493 s->c = (c + maxalign - 1) & -maxalign;
2494 s->r = maxalign;
2499 /* return 0 if no type declaration. otherwise, return the basic type
2500 and skip it.
2502 static int parse_btype(CType *type, AttributeDef *ad)
2504 int t, u, type_found, typespec_found, typedef_found;
2505 Sym *s;
2506 CType type1;
2508 memset(ad, 0, sizeof(AttributeDef));
2509 type_found = 0;
2510 typespec_found = 0;
2511 typedef_found = 0;
2512 t = 0;
2513 while(1) {
2514 switch(tok) {
2515 case TOK_EXTENSION:
2516 /* currently, we really ignore extension */
2517 next();
2518 continue;
2520 /* basic types */
2521 case TOK_CHAR:
2522 u = VT_BYTE;
2523 basic_type:
2524 next();
2525 basic_type1:
2526 if ((t & VT_BTYPE) != 0)
2527 error("too many basic types");
2528 t |= u;
2529 typespec_found = 1;
2530 break;
2531 case TOK_VOID:
2532 u = VT_VOID;
2533 goto basic_type;
2534 case TOK_SHORT:
2535 u = VT_SHORT;
2536 goto basic_type;
2537 case TOK_INT:
2538 next();
2539 typespec_found = 1;
2540 break;
2541 case TOK_LONG:
2542 next();
2543 if ((t & VT_BTYPE) == VT_DOUBLE) {
2544 #ifndef TCC_TARGET_PE
2545 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2546 #endif
2547 } else if ((t & VT_BTYPE) == VT_LONG) {
2548 t = (t & ~VT_BTYPE) | VT_LLONG;
2549 } else {
2550 u = VT_LONG;
2551 goto basic_type1;
2553 break;
2554 case TOK_BOOL:
2555 u = VT_BOOL;
2556 goto basic_type;
2557 case TOK_FLOAT:
2558 u = VT_FLOAT;
2559 goto basic_type;
2560 case TOK_DOUBLE:
2561 next();
2562 if ((t & VT_BTYPE) == VT_LONG) {
2563 #ifdef TCC_TARGET_PE
2564 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2565 #else
2566 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2567 #endif
2568 } else {
2569 u = VT_DOUBLE;
2570 goto basic_type1;
2572 break;
2573 case TOK_ENUM:
2574 struct_decl(&type1, VT_ENUM);
2575 basic_type2:
2576 u = type1.t;
2577 type->ref = type1.ref;
2578 goto basic_type1;
2579 case TOK_STRUCT:
2580 case TOK_UNION:
2581 struct_decl(&type1, VT_STRUCT);
2582 goto basic_type2;
2584 /* type modifiers */
2585 case TOK_CONST1:
2586 case TOK_CONST2:
2587 case TOK_CONST3:
2588 t |= VT_CONSTANT;
2589 next();
2590 break;
2591 case TOK_VOLATILE1:
2592 case TOK_VOLATILE2:
2593 case TOK_VOLATILE3:
2594 t |= VT_VOLATILE;
2595 next();
2596 break;
2597 case TOK_SIGNED1:
2598 case TOK_SIGNED2:
2599 case TOK_SIGNED3:
2600 typespec_found = 1;
2601 t |= VT_SIGNED;
2602 next();
2603 break;
2604 case TOK_REGISTER:
2605 case TOK_AUTO:
2606 case TOK_RESTRICT1:
2607 case TOK_RESTRICT2:
2608 case TOK_RESTRICT3:
2609 next();
2610 break;
2611 case TOK_UNSIGNED:
2612 t |= VT_UNSIGNED;
2613 next();
2614 typespec_found = 1;
2615 break;
2617 /* storage */
2618 case TOK_EXTERN:
2619 t |= VT_EXTERN;
2620 next();
2621 break;
2622 case TOK_STATIC:
2623 t |= VT_STATIC;
2624 next();
2625 break;
2626 case TOK_TYPEDEF:
2627 t |= VT_TYPEDEF;
2628 next();
2629 break;
2630 case TOK_INLINE1:
2631 case TOK_INLINE2:
2632 case TOK_INLINE3:
2633 t |= VT_INLINE;
2634 next();
2635 break;
2637 /* GNUC attribute */
2638 case TOK_ATTRIBUTE1:
2639 case TOK_ATTRIBUTE2:
2640 parse_attribute(ad);
2641 break;
2642 /* GNUC typeof */
2643 case TOK_TYPEOF1:
2644 case TOK_TYPEOF2:
2645 case TOK_TYPEOF3:
2646 next();
2647 parse_expr_type(&type1);
2648 goto basic_type2;
2649 default:
2650 if (typespec_found || typedef_found)
2651 goto the_end;
2652 s = sym_find(tok);
2653 if (!s || !(s->type.t & VT_TYPEDEF))
2654 goto the_end;
2655 typedef_found = 1;
2656 t |= (s->type.t & ~VT_TYPEDEF);
2657 type->ref = s->type.ref;
2658 if (s->r) {
2659 /* get attributes from typedef */
2660 if (0 == ad->aligned)
2661 ad->aligned = FUNC_ALIGN(s->r);
2662 if (0 == ad->func_call)
2663 ad->func_call = FUNC_CALL(s->r);
2664 ad->packed |= FUNC_PACKED(s->r);
2666 next();
2667 typespec_found = 1;
2668 break;
2670 type_found = 1;
2672 the_end:
2673 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
2674 error("signed and unsigned modifier");
2675 if (tcc_state->char_is_unsigned) {
2676 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
2677 t |= VT_UNSIGNED;
2679 t &= ~VT_SIGNED;
2681 /* long is never used as type */
2682 if ((t & VT_BTYPE) == VT_LONG)
2683 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
2684 t = (t & ~VT_BTYPE) | VT_INT;
2685 #else
2686 t = (t & ~VT_BTYPE) | VT_LLONG;
2687 #endif
2688 type->t = t;
2689 return type_found;
2692 /* convert a function parameter type (array to pointer and function to
2693 function pointer) */
2694 static inline void convert_parameter_type(CType *pt)
2696 /* remove const and volatile qualifiers (XXX: const could be used
2697 to indicate a const function parameter */
2698 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
2699 /* array must be transformed to pointer according to ANSI C */
2700 pt->t &= ~VT_ARRAY;
2701 if ((pt->t & VT_BTYPE) == VT_FUNC) {
2702 mk_pointer(pt);
2706 static void post_type(CType *type, AttributeDef *ad)
2708 int n, l, t1, arg_size, align;
2709 Sym **plast, *s, *first;
2710 AttributeDef ad1;
2711 CType pt;
2713 if (tok == '(') {
2714 /* function declaration */
2715 next();
2716 l = 0;
2717 first = NULL;
2718 plast = &first;
2719 arg_size = 0;
2720 if (tok != ')') {
2721 for(;;) {
2722 /* read param name and compute offset */
2723 if (l != FUNC_OLD) {
2724 if (!parse_btype(&pt, &ad1)) {
2725 if (l) {
2726 error("invalid type");
2727 } else {
2728 l = FUNC_OLD;
2729 goto old_proto;
2732 l = FUNC_NEW;
2733 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
2734 break;
2735 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
2736 if ((pt.t & VT_BTYPE) == VT_VOID)
2737 error("parameter declared as void");
2738 arg_size += (type_size(&pt, &align) + 3) & ~3;
2739 } else {
2740 old_proto:
2741 n = tok;
2742 if (n < TOK_UIDENT)
2743 expect("identifier");
2744 pt.t = VT_INT;
2745 next();
2747 convert_parameter_type(&pt);
2748 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
2749 *plast = s;
2750 plast = &s->next;
2751 if (tok == ')')
2752 break;
2753 skip(',');
2754 if (l == FUNC_NEW && tok == TOK_DOTS) {
2755 l = FUNC_ELLIPSIS;
2756 next();
2757 break;
2761 /* if no parameters, then old type prototype */
2762 if (l == 0)
2763 l = FUNC_OLD;
2764 skip(')');
2765 t1 = type->t & VT_STORAGE;
2766 /* NOTE: const is ignored in returned type as it has a special
2767 meaning in gcc / C++ */
2768 type->t &= ~(VT_STORAGE | VT_CONSTANT);
2769 post_type(type, ad);
2770 /* we push a anonymous symbol which will contain the function prototype */
2771 ad->func_args = arg_size;
2772 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
2773 s->next = first;
2774 type->t = t1 | VT_FUNC;
2775 type->ref = s;
2776 } else if (tok == '[') {
2777 /* array definition */
2778 next();
2779 if (tok == TOK_RESTRICT1)
2780 next();
2781 n = -1;
2782 if (tok != ']') {
2783 n = expr_const();
2784 if (n < 0)
2785 error("invalid array size");
2787 skip(']');
2788 /* parse next post type */
2789 t1 = type->t & VT_STORAGE;
2790 type->t &= ~VT_STORAGE;
2791 post_type(type, ad);
2793 /* we push a anonymous symbol which will contain the array
2794 element type */
2795 s = sym_push(SYM_FIELD, type, 0, n);
2796 type->t = t1 | VT_ARRAY | VT_PTR;
2797 type->ref = s;
2801 /* Parse a type declaration (except basic type), and return the type
2802 in 'type'. 'td' is a bitmask indicating which kind of type decl is
2803 expected. 'type' should contain the basic type. 'ad' is the
2804 attribute definition of the basic type. It can be modified by
2805 type_decl().
2807 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
2809 Sym *s;
2810 CType type1, *type2;
2811 int qualifiers;
2813 while (tok == '*') {
2814 qualifiers = 0;
2815 redo:
2816 next();
2817 switch(tok) {
2818 case TOK_CONST1:
2819 case TOK_CONST2:
2820 case TOK_CONST3:
2821 qualifiers |= VT_CONSTANT;
2822 goto redo;
2823 case TOK_VOLATILE1:
2824 case TOK_VOLATILE2:
2825 case TOK_VOLATILE3:
2826 qualifiers |= VT_VOLATILE;
2827 goto redo;
2828 case TOK_RESTRICT1:
2829 case TOK_RESTRICT2:
2830 case TOK_RESTRICT3:
2831 goto redo;
2833 mk_pointer(type);
2834 type->t |= qualifiers;
2837 /* XXX: clarify attribute handling */
2838 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
2839 parse_attribute(ad);
2841 /* recursive type */
2842 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
2843 type1.t = 0; /* XXX: same as int */
2844 if (tok == '(') {
2845 next();
2846 /* XXX: this is not correct to modify 'ad' at this point, but
2847 the syntax is not clear */
2848 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
2849 parse_attribute(ad);
2850 type_decl(&type1, ad, v, td);
2851 skip(')');
2852 } else {
2853 /* type identifier */
2854 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
2855 *v = tok;
2856 next();
2857 } else {
2858 if (!(td & TYPE_ABSTRACT))
2859 expect("identifier");
2860 *v = 0;
2863 post_type(type, ad);
2864 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
2865 parse_attribute(ad);
2866 if (!type1.t)
2867 return;
2868 /* append type at the end of type1 */
2869 type2 = &type1;
2870 for(;;) {
2871 s = type2->ref;
2872 type2 = &s->type;
2873 if (!type2->t) {
2874 *type2 = *type;
2875 break;
2878 *type = type1;
2881 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
2882 static int lvalue_type(int t)
2884 int bt, r;
2885 r = VT_LVAL;
2886 bt = t & VT_BTYPE;
2887 if (bt == VT_BYTE || bt == VT_BOOL)
2888 r |= VT_LVAL_BYTE;
2889 else if (bt == VT_SHORT)
2890 r |= VT_LVAL_SHORT;
2891 else
2892 return r;
2893 if (t & VT_UNSIGNED)
2894 r |= VT_LVAL_UNSIGNED;
2895 return r;
2898 /* indirection with full error checking and bound check */
2899 static void indir(void)
2901 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
2902 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
2903 return;
2904 expect("pointer");
2906 if ((vtop->r & VT_LVAL) && !nocode_wanted)
2907 gv(RC_INT);
2908 vtop->type = *pointed_type(&vtop->type);
2909 /* Arrays and functions are never lvalues */
2910 if (!(vtop->type.t & VT_ARRAY)
2911 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
2912 vtop->r |= lvalue_type(vtop->type.t);
2913 /* if bound checking, the referenced pointer must be checked */
2914 if (tcc_state->do_bounds_check)
2915 vtop->r |= VT_MUSTBOUND;
2919 /* pass a parameter to a function and do type checking and casting */
2920 static void gfunc_param_typed(Sym *func, Sym *arg)
2922 int func_type;
2923 CType type;
2925 func_type = func->c;
2926 if (func_type == FUNC_OLD ||
2927 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
2928 /* default casting : only need to convert float to double */
2929 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
2930 type.t = VT_DOUBLE;
2931 gen_cast(&type);
2933 } else if (arg == NULL) {
2934 error("too many arguments to function");
2935 } else {
2936 type = arg->type;
2937 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
2938 gen_assign_cast(&type);
2942 /* parse an expression of the form '(type)' or '(expr)' and return its
2943 type */
2944 static void parse_expr_type(CType *type)
2946 int n;
2947 AttributeDef ad;
2949 skip('(');
2950 if (parse_btype(type, &ad)) {
2951 type_decl(type, &ad, &n, TYPE_ABSTRACT);
2952 } else {
2953 expr_type(type);
2955 skip(')');
2958 static void parse_type(CType *type)
2960 AttributeDef ad;
2961 int n;
2963 if (!parse_btype(type, &ad)) {
2964 expect("type");
2966 type_decl(type, &ad, &n, TYPE_ABSTRACT);
2969 static void vpush_tokc(int t)
2971 CType type;
2972 type.t = t;
2973 type.ref = 0;
2974 vsetc(&type, VT_CONST, &tokc);
2977 static void unary(void)
2979 int n, t, align, size, r;
2980 CType type;
2981 Sym *s;
2982 AttributeDef ad;
2984 /* XXX: GCC 2.95.3 does not generate a table although it should be
2985 better here */
2986 tok_next:
2987 switch(tok) {
2988 case TOK_EXTENSION:
2989 next();
2990 goto tok_next;
2991 case TOK_CINT:
2992 case TOK_CCHAR:
2993 case TOK_LCHAR:
2994 vpushi(tokc.i);
2995 next();
2996 break;
2997 case TOK_CUINT:
2998 vpush_tokc(VT_INT | VT_UNSIGNED);
2999 next();
3000 break;
3001 case TOK_CLLONG:
3002 vpush_tokc(VT_LLONG);
3003 next();
3004 break;
3005 case TOK_CULLONG:
3006 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3007 next();
3008 break;
3009 case TOK_CFLOAT:
3010 vpush_tokc(VT_FLOAT);
3011 next();
3012 break;
3013 case TOK_CDOUBLE:
3014 vpush_tokc(VT_DOUBLE);
3015 next();
3016 break;
3017 case TOK_CLDOUBLE:
3018 vpush_tokc(VT_LDOUBLE);
3019 next();
3020 break;
3021 case TOK___FUNCTION__:
3022 if (!gnu_ext)
3023 goto tok_identifier;
3024 /* fall thru */
3025 case TOK___FUNC__:
3027 void *ptr;
3028 int len;
3029 /* special function name identifier */
3030 len = strlen(funcname) + 1;
3031 /* generate char[len] type */
3032 type.t = VT_BYTE;
3033 mk_pointer(&type);
3034 type.t |= VT_ARRAY;
3035 type.ref->c = len;
3036 vpush_ref(&type, data_section, data_section->data_offset, len);
3037 ptr = section_ptr_add(data_section, len);
3038 memcpy(ptr, funcname, len);
3039 next();
3041 break;
3042 case TOK_LSTR:
3043 #ifdef TCC_TARGET_PE
3044 t = VT_SHORT | VT_UNSIGNED;
3045 #else
3046 t = VT_INT;
3047 #endif
3048 goto str_init;
3049 case TOK_STR:
3050 /* string parsing */
3051 t = VT_BYTE;
3052 str_init:
3053 if (tcc_state->warn_write_strings)
3054 t |= VT_CONSTANT;
3055 type.t = t;
3056 mk_pointer(&type);
3057 type.t |= VT_ARRAY;
3058 memset(&ad, 0, sizeof(AttributeDef));
3059 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
3060 break;
3061 case '(':
3062 next();
3063 /* cast ? */
3064 if (parse_btype(&type, &ad)) {
3065 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3066 skip(')');
3067 /* check ISOC99 compound literal */
3068 if (tok == '{') {
3069 /* data is allocated locally by default */
3070 if (global_expr)
3071 r = VT_CONST;
3072 else
3073 r = VT_LOCAL;
3074 /* all except arrays are lvalues */
3075 if (!(type.t & VT_ARRAY))
3076 r |= lvalue_type(type.t);
3077 memset(&ad, 0, sizeof(AttributeDef));
3078 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
3079 } else {
3080 unary();
3081 gen_cast(&type);
3083 } else if (tok == '{') {
3084 /* save all registers */
3085 save_regs(0);
3086 /* statement expression : we do not accept break/continue
3087 inside as GCC does */
3088 block(NULL, NULL, NULL, NULL, 0, 1);
3089 skip(')');
3090 } else {
3091 gexpr();
3092 skip(')');
3094 break;
3095 case '*':
3096 next();
3097 unary();
3098 indir();
3099 break;
3100 case '&':
3101 next();
3102 unary();
3103 /* functions names must be treated as function pointers,
3104 except for unary '&' and sizeof. Since we consider that
3105 functions are not lvalues, we only have to handle it
3106 there and in function calls. */
3107 /* arrays can also be used although they are not lvalues */
3108 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3109 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3110 test_lvalue();
3111 mk_pointer(&vtop->type);
3112 gaddrof();
3113 break;
3114 case '!':
3115 next();
3116 unary();
3117 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3118 CType boolean;
3119 boolean.t = VT_BOOL;
3120 gen_cast(&boolean);
3121 vtop->c.i = !vtop->c.i;
3122 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3123 vtop->c.i = vtop->c.i ^ 1;
3124 else {
3125 save_regs(1);
3126 vseti(VT_JMP, gtst(1, 0));
3128 break;
3129 case '~':
3130 next();
3131 unary();
3132 vpushi(-1);
3133 gen_op('^');
3134 break;
3135 case '+':
3136 next();
3137 /* in order to force cast, we add zero */
3138 unary();
3139 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3140 error("pointer not accepted for unary plus");
3141 vpushi(0);
3142 gen_op('+');
3143 break;
3144 case TOK_SIZEOF:
3145 case TOK_ALIGNOF1:
3146 case TOK_ALIGNOF2:
3147 t = tok;
3148 next();
3149 if (tok == '(') {
3150 parse_expr_type(&type);
3151 } else {
3152 unary_type(&type);
3154 size = type_size(&type, &align);
3155 if (t == TOK_SIZEOF) {
3156 if (size < 0)
3157 error("sizeof applied to an incomplete type");
3158 vpushi(size);
3159 } else {
3160 vpushi(align);
3162 vtop->type.t |= VT_UNSIGNED;
3163 break;
3165 case TOK_builtin_types_compatible_p:
3167 CType type1, type2;
3168 next();
3169 skip('(');
3170 parse_type(&type1);
3171 skip(',');
3172 parse_type(&type2);
3173 skip(')');
3174 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3175 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3176 vpushi(is_compatible_types(&type1, &type2));
3178 break;
3179 case TOK_builtin_constant_p:
3181 int saved_nocode_wanted, res;
3182 next();
3183 skip('(');
3184 saved_nocode_wanted = nocode_wanted;
3185 nocode_wanted = 1;
3186 gexpr();
3187 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3188 vpop();
3189 nocode_wanted = saved_nocode_wanted;
3190 skip(')');
3191 vpushi(res);
3193 break;
3194 case TOK_builtin_frame_address:
3196 CType type;
3197 next();
3198 skip('(');
3199 if (tok != TOK_CINT) {
3200 error("__builtin_frame_address only takes integers");
3202 if (tokc.i != 0) {
3203 error("TCC only supports __builtin_frame_address(0)");
3205 next();
3206 skip(')');
3207 type.t = VT_VOID;
3208 mk_pointer(&type);
3209 vset(&type, VT_LOCAL, 0);
3211 break;
3212 #ifdef TCC_TARGET_X86_64
3213 case TOK_builtin_malloc:
3214 tok = TOK_malloc;
3215 goto tok_identifier;
3216 case TOK_builtin_free:
3217 tok = TOK_free;
3218 goto tok_identifier;
3219 #endif
3220 case TOK_INC:
3221 case TOK_DEC:
3222 t = tok;
3223 next();
3224 unary();
3225 inc(0, t);
3226 break;
3227 case '-':
3228 next();
3229 vpushi(0);
3230 unary();
3231 gen_op('-');
3232 break;
3233 case TOK_LAND:
3234 if (!gnu_ext)
3235 goto tok_identifier;
3236 next();
3237 /* allow to take the address of a label */
3238 if (tok < TOK_UIDENT)
3239 expect("label identifier");
3240 s = label_find(tok);
3241 if (!s) {
3242 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3243 } else {
3244 if (s->r == LABEL_DECLARED)
3245 s->r = LABEL_FORWARD;
3247 if (!s->type.t) {
3248 s->type.t = VT_VOID;
3249 mk_pointer(&s->type);
3250 s->type.t |= VT_STATIC;
3252 vset(&s->type, VT_CONST | VT_SYM, 0);
3253 vtop->sym = s;
3254 next();
3255 break;
3256 default:
3257 tok_identifier:
3258 t = tok;
3259 next();
3260 if (t < TOK_UIDENT)
3261 expect("identifier");
3262 s = sym_find(t);
3263 if (!s) {
3264 if (tok != '(')
3265 error("'%s' undeclared", get_tok_str(t, NULL));
3266 /* for simple function calls, we tolerate undeclared
3267 external reference to int() function */
3268 if (tcc_state->warn_implicit_function_declaration)
3269 warning("implicit declaration of function '%s'",
3270 get_tok_str(t, NULL));
3271 s = external_global_sym(t, &func_old_type, 0);
3273 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3274 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3275 /* if referencing an inline function, then we generate a
3276 symbol to it if not already done. It will have the
3277 effect to generate code for it at the end of the
3278 compilation unit. Inline function as always
3279 generated in the text section. */
3280 if (!s->c)
3281 put_extern_sym(s, text_section, 0, 0);
3282 r = VT_SYM | VT_CONST;
3283 } else {
3284 r = s->r;
3286 vset(&s->type, r, s->c);
3287 /* if forward reference, we must point to s */
3288 if (vtop->r & VT_SYM) {
3289 vtop->sym = s;
3290 vtop->c.ul = 0;
3292 break;
3295 /* post operations */
3296 while (1) {
3297 if (tok == TOK_INC || tok == TOK_DEC) {
3298 inc(1, tok);
3299 next();
3300 } else if (tok == '.' || tok == TOK_ARROW) {
3301 int qualifiers;
3302 /* field */
3303 if (tok == TOK_ARROW)
3304 indir();
3305 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3306 test_lvalue();
3307 gaddrof();
3308 next();
3309 /* expect pointer on structure */
3310 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3311 expect("struct or union");
3312 s = vtop->type.ref;
3313 /* find field */
3314 tok |= SYM_FIELD;
3315 while ((s = s->next) != NULL) {
3316 if (s->v == tok)
3317 break;
3319 if (!s)
3320 error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3321 /* add field offset to pointer */
3322 vtop->type = char_pointer_type; /* change type to 'char *' */
3323 vpushi(s->c);
3324 gen_op('+');
3325 /* change type to field type, and set to lvalue */
3326 vtop->type = s->type;
3327 vtop->type.t |= qualifiers;
3328 /* an array is never an lvalue */
3329 if (!(vtop->type.t & VT_ARRAY)) {
3330 vtop->r |= lvalue_type(vtop->type.t);
3331 /* if bound checking, the referenced pointer must be checked */
3332 if (tcc_state->do_bounds_check)
3333 vtop->r |= VT_MUSTBOUND;
3335 next();
3336 } else if (tok == '[') {
3337 next();
3338 gexpr();
3339 gen_op('+');
3340 indir();
3341 skip(']');
3342 } else if (tok == '(') {
3343 SValue ret;
3344 Sym *sa;
3345 int nb_args;
3347 /* function call */
3348 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3349 /* pointer test (no array accepted) */
3350 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3351 vtop->type = *pointed_type(&vtop->type);
3352 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3353 goto error_func;
3354 } else {
3355 error_func:
3356 expect("function pointer");
3358 } else {
3359 vtop->r &= ~VT_LVAL; /* no lvalue */
3361 /* get return type */
3362 s = vtop->type.ref;
3363 next();
3364 sa = s->next; /* first parameter */
3365 nb_args = 0;
3366 ret.r2 = VT_CONST;
3367 /* compute first implicit argument if a structure is returned */
3368 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3369 /* get some space for the returned structure */
3370 size = type_size(&s->type, &align);
3371 loc = (loc - size) & -align;
3372 ret.type = s->type;
3373 ret.r = VT_LOCAL | VT_LVAL;
3374 /* pass it as 'int' to avoid structure arg passing
3375 problems */
3376 vseti(VT_LOCAL, loc);
3377 ret.c = vtop->c;
3378 nb_args++;
3379 } else {
3380 ret.type = s->type;
3381 /* return in register */
3382 if (is_float(ret.type.t)) {
3383 ret.r = reg_fret(ret.type.t);
3384 } else {
3385 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3386 ret.r2 = REG_LRET;
3387 ret.r = REG_IRET;
3389 ret.c.i = 0;
3391 if (tok != ')') {
3392 for(;;) {
3393 expr_eq();
3394 gfunc_param_typed(s, sa);
3395 nb_args++;
3396 if (sa)
3397 sa = sa->next;
3398 if (tok == ')')
3399 break;
3400 skip(',');
3403 if (sa)
3404 error("too few arguments to function");
3405 skip(')');
3406 if (!nocode_wanted) {
3407 gfunc_call(nb_args);
3408 } else {
3409 vtop -= (nb_args + 1);
3411 /* return value */
3412 vsetc(&ret.type, ret.r, &ret.c);
3413 vtop->r2 = ret.r2;
3414 } else {
3415 break;
3420 static void uneq(void)
3422 int t;
3424 unary();
3425 if (tok == '=' ||
3426 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
3427 tok == TOK_A_XOR || tok == TOK_A_OR ||
3428 tok == TOK_A_SHL || tok == TOK_A_SAR) {
3429 test_lvalue();
3430 t = tok;
3431 next();
3432 if (t == '=') {
3433 expr_eq();
3434 } else {
3435 vdup();
3436 expr_eq();
3437 gen_op(t & 0x7f);
3439 vstore();
3443 static void expr_prod(void)
3445 int t;
3447 uneq();
3448 while (tok == '*' || tok == '/' || tok == '%') {
3449 t = tok;
3450 next();
3451 uneq();
3452 gen_op(t);
3456 static void expr_sum(void)
3458 int t;
3460 expr_prod();
3461 while (tok == '+' || tok == '-') {
3462 t = tok;
3463 next();
3464 expr_prod();
3465 gen_op(t);
3469 static void expr_shift(void)
3471 int t;
3473 expr_sum();
3474 while (tok == TOK_SHL || tok == TOK_SAR) {
3475 t = tok;
3476 next();
3477 expr_sum();
3478 gen_op(t);
3482 static void expr_cmp(void)
3484 int t;
3486 expr_shift();
3487 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3488 tok == TOK_ULT || tok == TOK_UGE) {
3489 t = tok;
3490 next();
3491 expr_shift();
3492 gen_op(t);
3496 static void expr_cmpeq(void)
3498 int t;
3500 expr_cmp();
3501 while (tok == TOK_EQ || tok == TOK_NE) {
3502 t = tok;
3503 next();
3504 expr_cmp();
3505 gen_op(t);
3509 static void expr_and(void)
3511 expr_cmpeq();
3512 while (tok == '&') {
3513 next();
3514 expr_cmpeq();
3515 gen_op('&');
3519 static void expr_xor(void)
3521 expr_and();
3522 while (tok == '^') {
3523 next();
3524 expr_and();
3525 gen_op('^');
3529 static void expr_or(void)
3531 expr_xor();
3532 while (tok == '|') {
3533 next();
3534 expr_xor();
3535 gen_op('|');
3539 /* XXX: fix this mess */
3540 static void expr_land_const(void)
3542 expr_or();
3543 while (tok == TOK_LAND) {
3544 next();
3545 expr_or();
3546 gen_op(TOK_LAND);
3550 /* XXX: fix this mess */
3551 static void expr_lor_const(void)
3553 expr_land_const();
3554 while (tok == TOK_LOR) {
3555 next();
3556 expr_land_const();
3557 gen_op(TOK_LOR);
3561 /* only used if non constant */
3562 static void expr_land(void)
3564 int t;
3566 expr_or();
3567 if (tok == TOK_LAND) {
3568 t = 0;
3569 save_regs(1);
3570 for(;;) {
3571 t = gtst(1, t);
3572 if (tok != TOK_LAND) {
3573 vseti(VT_JMPI, t);
3574 break;
3576 next();
3577 expr_or();
3582 static void expr_lor(void)
3584 int t;
3586 expr_land();
3587 if (tok == TOK_LOR) {
3588 t = 0;
3589 save_regs(1);
3590 for(;;) {
3591 t = gtst(0, t);
3592 if (tok != TOK_LOR) {
3593 vseti(VT_JMP, t);
3594 break;
3596 next();
3597 expr_land();
3602 /* XXX: better constant handling */
3603 static void expr_eq(void)
3605 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
3606 SValue sv;
3607 CType type, type1, type2;
3609 if (const_wanted) {
3610 expr_lor_const();
3611 if (tok == '?') {
3612 CType boolean;
3613 int c;
3614 boolean.t = VT_BOOL;
3615 vdup();
3616 gen_cast(&boolean);
3617 c = vtop->c.i;
3618 vpop();
3619 next();
3620 if (tok != ':' || !gnu_ext) {
3621 vpop();
3622 gexpr();
3624 if (!c)
3625 vpop();
3626 skip(':');
3627 expr_eq();
3628 if (c)
3629 vpop();
3631 } else {
3632 expr_lor();
3633 if (tok == '?') {
3634 next();
3635 if (vtop != vstack) {
3636 /* needed to avoid having different registers saved in
3637 each branch */
3638 if (is_float(vtop->type.t)) {
3639 rc = RC_FLOAT;
3640 #ifdef TCC_TARGET_X86_64
3641 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
3642 rc = RC_ST0;
3644 #endif
3646 else
3647 rc = RC_INT;
3648 gv(rc);
3649 save_regs(1);
3651 if (tok == ':' && gnu_ext) {
3652 gv_dup();
3653 tt = gtst(1, 0);
3654 } else {
3655 tt = gtst(1, 0);
3656 gexpr();
3658 type1 = vtop->type;
3659 sv = *vtop; /* save value to handle it later */
3660 vtop--; /* no vpop so that FP stack is not flushed */
3661 skip(':');
3662 u = gjmp(0);
3663 gsym(tt);
3664 expr_eq();
3665 type2 = vtop->type;
3667 t1 = type1.t;
3668 bt1 = t1 & VT_BTYPE;
3669 t2 = type2.t;
3670 bt2 = t2 & VT_BTYPE;
3671 /* cast operands to correct type according to ISOC rules */
3672 if (is_float(bt1) || is_float(bt2)) {
3673 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3674 type.t = VT_LDOUBLE;
3675 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3676 type.t = VT_DOUBLE;
3677 } else {
3678 type.t = VT_FLOAT;
3680 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3681 /* cast to biggest op */
3682 type.t = VT_LLONG;
3683 /* convert to unsigned if it does not fit in a long long */
3684 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
3685 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
3686 type.t |= VT_UNSIGNED;
3687 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
3688 /* XXX: test pointer compatibility */
3689 type = type1;
3690 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
3691 /* XXX: test function pointer compatibility */
3692 type = type1;
3693 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
3694 /* XXX: test structure compatibility */
3695 type = type1;
3696 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
3697 /* NOTE: as an extension, we accept void on only one side */
3698 type.t = VT_VOID;
3699 } else {
3700 /* integer operations */
3701 type.t = VT_INT;
3702 /* convert to unsigned if it does not fit in an integer */
3703 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
3704 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
3705 type.t |= VT_UNSIGNED;
3708 /* now we convert second operand */
3709 gen_cast(&type);
3710 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
3711 gaddrof();
3712 rc = RC_INT;
3713 if (is_float(type.t)) {
3714 rc = RC_FLOAT;
3715 #ifdef TCC_TARGET_X86_64
3716 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
3717 rc = RC_ST0;
3719 #endif
3720 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
3721 /* for long longs, we use fixed registers to avoid having
3722 to handle a complicated move */
3723 rc = RC_IRET;
3726 r2 = gv(rc);
3727 /* this is horrible, but we must also convert first
3728 operand */
3729 tt = gjmp(0);
3730 gsym(u);
3731 /* put again first value and cast it */
3732 *vtop = sv;
3733 gen_cast(&type);
3734 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
3735 gaddrof();
3736 r1 = gv(rc);
3737 move_reg(r2, r1);
3738 vtop->r = r2;
3739 gsym(tt);
3744 static void gexpr(void)
3746 while (1) {
3747 expr_eq();
3748 if (tok != ',')
3749 break;
3750 vpop();
3751 next();
3755 /* parse an expression and return its type without any side effect. */
3756 static void expr_type(CType *type)
3758 int saved_nocode_wanted;
3760 saved_nocode_wanted = nocode_wanted;
3761 nocode_wanted = 1;
3762 gexpr();
3763 *type = vtop->type;
3764 vpop();
3765 nocode_wanted = saved_nocode_wanted;
3768 /* parse a unary expression and return its type without any side
3769 effect. */
3770 static void unary_type(CType *type)
3772 int a;
3774 a = nocode_wanted;
3775 nocode_wanted = 1;
3776 unary();
3777 *type = vtop->type;
3778 vpop();
3779 nocode_wanted = a;
3782 /* parse a constant expression and return value in vtop. */
3783 static void expr_const1(void)
3785 int a;
3786 a = const_wanted;
3787 const_wanted = 1;
3788 expr_eq();
3789 const_wanted = a;
3792 /* parse an integer constant and return its value. */
3793 static int expr_const(void)
3795 int c;
3796 expr_const1();
3797 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
3798 expect("constant expression");
3799 c = vtop->c.i;
3800 vpop();
3801 return c;
3804 /* return the label token if current token is a label, otherwise
3805 return zero */
3806 static int is_label(void)
3808 int last_tok;
3810 /* fast test first */
3811 if (tok < TOK_UIDENT)
3812 return 0;
3813 /* no need to save tokc because tok is an identifier */
3814 last_tok = tok;
3815 next();
3816 if (tok == ':') {
3817 next();
3818 return last_tok;
3819 } else {
3820 unget_tok(last_tok);
3821 return 0;
3825 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
3826 int case_reg, int is_expr)
3828 int a, b, c, d;
3829 Sym *s;
3831 /* generate line number info */
3832 if (tcc_state->do_debug &&
3833 (last_line_num != file->line_num || last_ind != ind)) {
3834 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
3835 last_ind = ind;
3836 last_line_num = file->line_num;
3839 if (is_expr) {
3840 /* default return value is (void) */
3841 vpushi(0);
3842 vtop->type.t = VT_VOID;
3845 if (tok == TOK_IF) {
3846 /* if test */
3847 next();
3848 skip('(');
3849 gexpr();
3850 skip(')');
3851 a = gtst(1, 0);
3852 block(bsym, csym, case_sym, def_sym, case_reg, 0);
3853 c = tok;
3854 if (c == TOK_ELSE) {
3855 next();
3856 d = gjmp(0);
3857 gsym(a);
3858 block(bsym, csym, case_sym, def_sym, case_reg, 0);
3859 gsym(d); /* patch else jmp */
3860 } else
3861 gsym(a);
3862 } else if (tok == TOK_WHILE) {
3863 next();
3864 d = ind;
3865 skip('(');
3866 gexpr();
3867 skip(')');
3868 a = gtst(1, 0);
3869 b = 0;
3870 block(&a, &b, case_sym, def_sym, case_reg, 0);
3871 gjmp_addr(d);
3872 gsym(a);
3873 gsym_addr(b, d);
3874 } else if (tok == '{') {
3875 Sym *llabel;
3877 next();
3878 /* record local declaration stack position */
3879 s = local_stack;
3880 llabel = local_label_stack;
3881 /* handle local labels declarations */
3882 if (tok == TOK_LABEL) {
3883 next();
3884 for(;;) {
3885 if (tok < TOK_UIDENT)
3886 expect("label identifier");
3887 label_push(&local_label_stack, tok, LABEL_DECLARED);
3888 next();
3889 if (tok == ',') {
3890 next();
3891 } else {
3892 skip(';');
3893 break;
3897 while (tok != '}') {
3898 decl(VT_LOCAL);
3899 if (tok != '}') {
3900 if (is_expr)
3901 vpop();
3902 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
3905 /* pop locally defined labels */
3906 label_pop(&local_label_stack, llabel);
3907 /* pop locally defined symbols */
3908 if(is_expr) {
3909 /* XXX: this solution makes only valgrind happy...
3910 triggered by gcc.c-torture/execute/20000917-1.c */
3911 Sym *p;
3912 switch(vtop->type.t & VT_BTYPE) {
3913 case VT_PTR:
3914 case VT_STRUCT:
3915 case VT_ENUM:
3916 case VT_FUNC:
3917 for(p=vtop->type.ref;p;p=p->prev)
3918 if(p->prev==s)
3919 error("unsupported expression type");
3922 sym_pop(&local_stack, s);
3923 next();
3924 } else if (tok == TOK_RETURN) {
3925 next();
3926 if (tok != ';') {
3927 gexpr();
3928 gen_assign_cast(&func_vt);
3929 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
3930 CType type;
3931 /* if returning structure, must copy it to implicit
3932 first pointer arg location */
3933 #ifdef TCC_ARM_EABI
3934 int align, size;
3935 size = type_size(&func_vt,&align);
3936 if(size <= 4)
3938 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
3939 && (align & 3))
3941 int addr;
3942 loc = (loc - size) & -4;
3943 addr = loc;
3944 type = func_vt;
3945 vset(&type, VT_LOCAL | VT_LVAL, addr);
3946 vswap();
3947 vstore();
3948 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
3950 vtop->type = int_type;
3951 gv(RC_IRET);
3952 } else {
3953 #endif
3954 type = func_vt;
3955 mk_pointer(&type);
3956 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
3957 indir();
3958 vswap();
3959 /* copy structure value to pointer */
3960 vstore();
3961 #ifdef TCC_ARM_EABI
3963 #endif
3964 } else if (is_float(func_vt.t)) {
3965 gv(rc_fret(func_vt.t));
3966 } else {
3967 gv(RC_IRET);
3969 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
3971 skip(';');
3972 rsym = gjmp(rsym); /* jmp */
3973 } else if (tok == TOK_BREAK) {
3974 /* compute jump */
3975 if (!bsym)
3976 error("cannot break");
3977 *bsym = gjmp(*bsym);
3978 next();
3979 skip(';');
3980 } else if (tok == TOK_CONTINUE) {
3981 /* compute jump */
3982 if (!csym)
3983 error("cannot continue");
3984 *csym = gjmp(*csym);
3985 next();
3986 skip(';');
3987 } else if (tok == TOK_FOR) {
3988 int e;
3989 next();
3990 skip('(');
3991 if (tok != ';') {
3992 gexpr();
3993 vpop();
3995 skip(';');
3996 d = ind;
3997 c = ind;
3998 a = 0;
3999 b = 0;
4000 if (tok != ';') {
4001 gexpr();
4002 a = gtst(1, 0);
4004 skip(';');
4005 if (tok != ')') {
4006 e = gjmp(0);
4007 c = ind;
4008 gexpr();
4009 vpop();
4010 gjmp_addr(d);
4011 gsym(e);
4013 skip(')');
4014 block(&a, &b, case_sym, def_sym, case_reg, 0);
4015 gjmp_addr(c);
4016 gsym(a);
4017 gsym_addr(b, c);
4018 } else
4019 if (tok == TOK_DO) {
4020 next();
4021 a = 0;
4022 b = 0;
4023 d = ind;
4024 block(&a, &b, case_sym, def_sym, case_reg, 0);
4025 skip(TOK_WHILE);
4026 skip('(');
4027 gsym(b);
4028 gexpr();
4029 c = gtst(0, 0);
4030 gsym_addr(c, d);
4031 skip(')');
4032 gsym(a);
4033 skip(';');
4034 } else
4035 if (tok == TOK_SWITCH) {
4036 next();
4037 skip('(');
4038 gexpr();
4039 /* XXX: other types than integer */
4040 case_reg = gv(RC_INT);
4041 vpop();
4042 skip(')');
4043 a = 0;
4044 b = gjmp(0); /* jump to first case */
4045 c = 0;
4046 block(&a, csym, &b, &c, case_reg, 0);
4047 /* if no default, jmp after switch */
4048 if (c == 0)
4049 c = ind;
4050 /* default label */
4051 gsym_addr(b, c);
4052 /* break label */
4053 gsym(a);
4054 } else
4055 if (tok == TOK_CASE) {
4056 int v1, v2;
4057 if (!case_sym)
4058 expect("switch");
4059 next();
4060 v1 = expr_const();
4061 v2 = v1;
4062 if (gnu_ext && tok == TOK_DOTS) {
4063 next();
4064 v2 = expr_const();
4065 if (v2 < v1)
4066 warning("empty case range");
4068 /* since a case is like a label, we must skip it with a jmp */
4069 b = gjmp(0);
4070 gsym(*case_sym);
4071 vseti(case_reg, 0);
4072 vpushi(v1);
4073 if (v1 == v2) {
4074 gen_op(TOK_EQ);
4075 *case_sym = gtst(1, 0);
4076 } else {
4077 gen_op(TOK_GE);
4078 *case_sym = gtst(1, 0);
4079 vseti(case_reg, 0);
4080 vpushi(v2);
4081 gen_op(TOK_LE);
4082 *case_sym = gtst(1, *case_sym);
4084 gsym(b);
4085 skip(':');
4086 is_expr = 0;
4087 goto block_after_label;
4088 } else
4089 if (tok == TOK_DEFAULT) {
4090 next();
4091 skip(':');
4092 if (!def_sym)
4093 expect("switch");
4094 if (*def_sym)
4095 error("too many 'default'");
4096 *def_sym = ind;
4097 is_expr = 0;
4098 goto block_after_label;
4099 } else
4100 if (tok == TOK_GOTO) {
4101 next();
4102 if (tok == '*' && gnu_ext) {
4103 /* computed goto */
4104 next();
4105 gexpr();
4106 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4107 expect("pointer");
4108 ggoto();
4109 } else if (tok >= TOK_UIDENT) {
4110 s = label_find(tok);
4111 /* put forward definition if needed */
4112 if (!s) {
4113 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4114 } else {
4115 if (s->r == LABEL_DECLARED)
4116 s->r = LABEL_FORWARD;
4118 /* label already defined */
4119 if (s->r & LABEL_FORWARD)
4120 s->jnext = gjmp(s->jnext);
4121 else
4122 gjmp_addr(s->jnext);
4123 next();
4124 } else {
4125 expect("label identifier");
4127 skip(';');
4128 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4129 asm_instr();
4130 } else {
4131 b = is_label();
4132 if (b) {
4133 /* label case */
4134 s = label_find(b);
4135 if (s) {
4136 if (s->r == LABEL_DEFINED)
4137 error("duplicate label '%s'", get_tok_str(s->v, NULL));
4138 gsym(s->jnext);
4139 s->r = LABEL_DEFINED;
4140 } else {
4141 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4143 s->jnext = ind;
4144 /* we accept this, but it is a mistake */
4145 block_after_label:
4146 if (tok == '}') {
4147 warning("deprecated use of label at end of compound statement");
4148 } else {
4149 if (is_expr)
4150 vpop();
4151 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4153 } else {
4154 /* expression case */
4155 if (tok != ';') {
4156 if (is_expr) {
4157 vpop();
4158 gexpr();
4159 } else {
4160 gexpr();
4161 vpop();
4164 skip(';');
4169 /* t is the array or struct type. c is the array or struct
4170 address. cur_index/cur_field is the pointer to the current
4171 value. 'size_only' is true if only size info is needed (only used
4172 in arrays) */
4173 static void decl_designator(CType *type, Section *sec, unsigned long c,
4174 int *cur_index, Sym **cur_field,
4175 int size_only)
4177 Sym *s, *f;
4178 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4179 CType type1;
4181 notfirst = 0;
4182 elem_size = 0;
4183 nb_elems = 1;
4184 if (gnu_ext && (l = is_label()) != 0)
4185 goto struct_field;
4186 while (tok == '[' || tok == '.') {
4187 if (tok == '[') {
4188 if (!(type->t & VT_ARRAY))
4189 expect("array type");
4190 s = type->ref;
4191 next();
4192 index = expr_const();
4193 if (index < 0 || (s->c >= 0 && index >= s->c))
4194 expect("invalid index");
4195 if (tok == TOK_DOTS && gnu_ext) {
4196 next();
4197 index_last = expr_const();
4198 if (index_last < 0 ||
4199 (s->c >= 0 && index_last >= s->c) ||
4200 index_last < index)
4201 expect("invalid index");
4202 } else {
4203 index_last = index;
4205 skip(']');
4206 if (!notfirst)
4207 *cur_index = index_last;
4208 type = pointed_type(type);
4209 elem_size = type_size(type, &align);
4210 c += index * elem_size;
4211 /* NOTE: we only support ranges for last designator */
4212 nb_elems = index_last - index + 1;
4213 if (nb_elems != 1) {
4214 notfirst = 1;
4215 break;
4217 } else {
4218 next();
4219 l = tok;
4220 next();
4221 struct_field:
4222 if ((type->t & VT_BTYPE) != VT_STRUCT)
4223 expect("struct/union type");
4224 s = type->ref;
4225 l |= SYM_FIELD;
4226 f = s->next;
4227 while (f) {
4228 if (f->v == l)
4229 break;
4230 f = f->next;
4232 if (!f)
4233 expect("field");
4234 if (!notfirst)
4235 *cur_field = f;
4236 /* XXX: fix this mess by using explicit storage field */
4237 type1 = f->type;
4238 type1.t |= (type->t & ~VT_TYPE);
4239 type = &type1;
4240 c += f->c;
4242 notfirst = 1;
4244 if (notfirst) {
4245 if (tok == '=') {
4246 next();
4247 } else {
4248 if (!gnu_ext)
4249 expect("=");
4251 } else {
4252 if (type->t & VT_ARRAY) {
4253 index = *cur_index;
4254 type = pointed_type(type);
4255 c += index * type_size(type, &align);
4256 } else {
4257 f = *cur_field;
4258 if (!f)
4259 error("too many field init");
4260 /* XXX: fix this mess by using explicit storage field */
4261 type1 = f->type;
4262 type1.t |= (type->t & ~VT_TYPE);
4263 type = &type1;
4264 c += f->c;
4267 decl_initializer(type, sec, c, 0, size_only);
4269 /* XXX: make it more general */
4270 if (!size_only && nb_elems > 1) {
4271 unsigned long c_end;
4272 uint8_t *src, *dst;
4273 int i;
4275 if (!sec)
4276 error("range init not supported yet for dynamic storage");
4277 c_end = c + nb_elems * elem_size;
4278 if (c_end > sec->data_allocated)
4279 section_realloc(sec, c_end);
4280 src = sec->data + c;
4281 dst = src;
4282 for(i = 1; i < nb_elems; i++) {
4283 dst += elem_size;
4284 memcpy(dst, src, elem_size);
4289 #define EXPR_VAL 0
4290 #define EXPR_CONST 1
4291 #define EXPR_ANY 2
4293 /* store a value or an expression directly in global data or in local array */
4294 static void init_putv(CType *type, Section *sec, unsigned long c,
4295 int v, int expr_type)
4297 int saved_global_expr, bt, bit_pos, bit_size;
4298 void *ptr;
4299 unsigned long long bit_mask;
4300 CType dtype;
4302 switch(expr_type) {
4303 case EXPR_VAL:
4304 vpushi(v);
4305 break;
4306 case EXPR_CONST:
4307 /* compound literals must be allocated globally in this case */
4308 saved_global_expr = global_expr;
4309 global_expr = 1;
4310 expr_const1();
4311 global_expr = saved_global_expr;
4312 /* NOTE: symbols are accepted */
4313 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4314 error("initializer element is not constant");
4315 break;
4316 case EXPR_ANY:
4317 expr_eq();
4318 break;
4321 dtype = *type;
4322 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4324 if (sec) {
4325 /* XXX: not portable */
4326 /* XXX: generate error if incorrect relocation */
4327 gen_assign_cast(&dtype);
4328 bt = type->t & VT_BTYPE;
4329 /* we'll write at most 12 bytes */
4330 if (c + 12 > sec->data_allocated) {
4331 section_realloc(sec, c + 12);
4333 ptr = sec->data + c;
4334 /* XXX: make code faster ? */
4335 if (!(type->t & VT_BITFIELD)) {
4336 bit_pos = 0;
4337 bit_size = 32;
4338 bit_mask = -1LL;
4339 } else {
4340 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4341 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4342 bit_mask = (1LL << bit_size) - 1;
4344 if ((vtop->r & VT_SYM) &&
4345 (bt == VT_BYTE ||
4346 bt == VT_SHORT ||
4347 bt == VT_DOUBLE ||
4348 bt == VT_LDOUBLE ||
4349 bt == VT_LLONG ||
4350 (bt == VT_INT && bit_size != 32)))
4351 error("initializer element is not computable at load time");
4352 switch(bt) {
4353 case VT_BOOL:
4354 vtop->c.i = (vtop->c.i != 0);
4355 case VT_BYTE:
4356 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4357 break;
4358 case VT_SHORT:
4359 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4360 break;
4361 case VT_DOUBLE:
4362 *(double *)ptr = vtop->c.d;
4363 break;
4364 case VT_LDOUBLE:
4365 *(long double *)ptr = vtop->c.ld;
4366 break;
4367 case VT_LLONG:
4368 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4369 break;
4370 default:
4371 if (vtop->r & VT_SYM) {
4372 greloc(sec, vtop->sym, c, R_DATA_PTR);
4374 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4375 break;
4377 vtop--;
4378 } else {
4379 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4380 vswap();
4381 vstore();
4382 vpop();
4386 /* put zeros for variable based init */
4387 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4389 if (sec) {
4390 /* nothing to do because globals are already set to zero */
4391 } else {
4392 vpush_global_sym(&func_old_type, TOK_memset);
4393 vseti(VT_LOCAL, c);
4394 vpushi(0);
4395 vpushi(size);
4396 gfunc_call(3);
4400 /* 't' contains the type and storage info. 'c' is the offset of the
4401 object in section 'sec'. If 'sec' is NULL, it means stack based
4402 allocation. 'first' is true if array '{' must be read (multi
4403 dimension implicit array init handling). 'size_only' is true if
4404 size only evaluation is wanted (only for arrays). */
4405 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4406 int first, int size_only)
4408 int index, array_length, n, no_oblock, nb, parlevel, i;
4409 int size1, align1, expr_type;
4410 Sym *s, *f;
4411 CType *t1;
4413 if (type->t & VT_ARRAY) {
4414 s = type->ref;
4415 n = s->c;
4416 array_length = 0;
4417 t1 = pointed_type(type);
4418 size1 = type_size(t1, &align1);
4420 no_oblock = 1;
4421 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4422 tok == '{') {
4423 skip('{');
4424 no_oblock = 0;
4427 /* only parse strings here if correct type (otherwise: handle
4428 them as ((w)char *) expressions */
4429 if ((tok == TOK_LSTR &&
4430 #ifdef TCC_TARGET_PE
4431 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
4432 #else
4433 (t1->t & VT_BTYPE) == VT_INT
4434 #endif
4435 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
4436 while (tok == TOK_STR || tok == TOK_LSTR) {
4437 int cstr_len, ch;
4438 CString *cstr;
4440 cstr = tokc.cstr;
4441 /* compute maximum number of chars wanted */
4442 if (tok == TOK_STR)
4443 cstr_len = cstr->size;
4444 else
4445 cstr_len = cstr->size / sizeof(nwchar_t);
4446 cstr_len--;
4447 nb = cstr_len;
4448 if (n >= 0 && nb > (n - array_length))
4449 nb = n - array_length;
4450 if (!size_only) {
4451 if (cstr_len > nb)
4452 warning("initializer-string for array is too long");
4453 /* in order to go faster for common case (char
4454 string in global variable, we handle it
4455 specifically */
4456 if (sec && tok == TOK_STR && size1 == 1) {
4457 memcpy(sec->data + c + array_length, cstr->data, nb);
4458 } else {
4459 for(i=0;i<nb;i++) {
4460 if (tok == TOK_STR)
4461 ch = ((unsigned char *)cstr->data)[i];
4462 else
4463 ch = ((nwchar_t *)cstr->data)[i];
4464 init_putv(t1, sec, c + (array_length + i) * size1,
4465 ch, EXPR_VAL);
4469 array_length += nb;
4470 next();
4472 /* only add trailing zero if enough storage (no
4473 warning in this case since it is standard) */
4474 if (n < 0 || array_length < n) {
4475 if (!size_only) {
4476 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
4478 array_length++;
4480 } else {
4481 index = 0;
4482 while (tok != '}') {
4483 decl_designator(type, sec, c, &index, NULL, size_only);
4484 if (n >= 0 && index >= n)
4485 error("index too large");
4486 /* must put zero in holes (note that doing it that way
4487 ensures that it even works with designators) */
4488 if (!size_only && array_length < index) {
4489 init_putz(t1, sec, c + array_length * size1,
4490 (index - array_length) * size1);
4492 index++;
4493 if (index > array_length)
4494 array_length = index;
4495 /* special test for multi dimensional arrays (may not
4496 be strictly correct if designators are used at the
4497 same time) */
4498 if (index >= n && no_oblock)
4499 break;
4500 if (tok == '}')
4501 break;
4502 skip(',');
4505 if (!no_oblock)
4506 skip('}');
4507 /* put zeros at the end */
4508 if (!size_only && n >= 0 && array_length < n) {
4509 init_putz(t1, sec, c + array_length * size1,
4510 (n - array_length) * size1);
4512 /* patch type size if needed */
4513 if (n < 0)
4514 s->c = array_length;
4515 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
4516 (sec || !first || tok == '{')) {
4517 int par_count;
4519 /* NOTE: the previous test is a specific case for automatic
4520 struct/union init */
4521 /* XXX: union needs only one init */
4523 /* XXX: this test is incorrect for local initializers
4524 beginning with ( without {. It would be much more difficult
4525 to do it correctly (ideally, the expression parser should
4526 be used in all cases) */
4527 par_count = 0;
4528 if (tok == '(') {
4529 AttributeDef ad1;
4530 CType type1;
4531 next();
4532 while (tok == '(') {
4533 par_count++;
4534 next();
4536 if (!parse_btype(&type1, &ad1))
4537 expect("cast");
4538 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
4539 #if 0
4540 if (!is_assignable_types(type, &type1))
4541 error("invalid type for cast");
4542 #endif
4543 skip(')');
4545 no_oblock = 1;
4546 if (first || tok == '{') {
4547 skip('{');
4548 no_oblock = 0;
4550 s = type->ref;
4551 f = s->next;
4552 array_length = 0;
4553 index = 0;
4554 n = s->c;
4555 while (tok != '}') {
4556 decl_designator(type, sec, c, NULL, &f, size_only);
4557 index = f->c;
4558 if (!size_only && array_length < index) {
4559 init_putz(type, sec, c + array_length,
4560 index - array_length);
4562 index = index + type_size(&f->type, &align1);
4563 if (index > array_length)
4564 array_length = index;
4566 /* gr: skip fields from same union - ugly. */
4567 while (f->next) {
4568 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
4569 /* test for same offset */
4570 if (f->next->c != f->c)
4571 break;
4572 /* if yes, test for bitfield shift */
4573 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
4574 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4575 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4576 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
4577 if (bit_pos_1 != bit_pos_2)
4578 break;
4580 f = f->next;
4583 f = f->next;
4584 if (no_oblock && f == NULL)
4585 break;
4586 if (tok == '}')
4587 break;
4588 skip(',');
4590 /* put zeros at the end */
4591 if (!size_only && array_length < n) {
4592 init_putz(type, sec, c + array_length,
4593 n - array_length);
4595 if (!no_oblock)
4596 skip('}');
4597 while (par_count) {
4598 skip(')');
4599 par_count--;
4601 } else if (tok == '{') {
4602 next();
4603 decl_initializer(type, sec, c, first, size_only);
4604 skip('}');
4605 } else if (size_only) {
4606 /* just skip expression */
4607 parlevel = 0;
4608 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
4609 tok != -1) {
4610 if (tok == '(')
4611 parlevel++;
4612 else if (tok == ')')
4613 parlevel--;
4614 next();
4616 } else {
4617 /* currently, we always use constant expression for globals
4618 (may change for scripting case) */
4619 expr_type = EXPR_CONST;
4620 if (!sec)
4621 expr_type = EXPR_ANY;
4622 init_putv(type, sec, c, 0, expr_type);
4626 /* parse an initializer for type 't' if 'has_init' is non zero, and
4627 allocate space in local or global data space ('r' is either
4628 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
4629 variable 'v' of scope 'scope' is declared before initializers are
4630 parsed. If 'v' is zero, then a reference to the new object is put
4631 in the value stack. If 'has_init' is 2, a special parsing is done
4632 to handle string constants. */
4633 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
4634 int has_init, int v, int scope)
4636 int size, align, addr, data_offset;
4637 int level;
4638 ParseState saved_parse_state = {0};
4639 TokenString init_str;
4640 Section *sec;
4642 size = type_size(type, &align);
4643 /* If unknown size, we must evaluate it before
4644 evaluating initializers because
4645 initializers can generate global data too
4646 (e.g. string pointers or ISOC99 compound
4647 literals). It also simplifies local
4648 initializers handling */
4649 tok_str_new(&init_str);
4650 if (size < 0) {
4651 if (!has_init)
4652 error("unknown type size");
4653 /* get all init string */
4654 if (has_init == 2) {
4655 /* only get strings */
4656 while (tok == TOK_STR || tok == TOK_LSTR) {
4657 tok_str_add_tok(&init_str);
4658 next();
4660 } else {
4661 level = 0;
4662 while (level > 0 || (tok != ',' && tok != ';')) {
4663 if (tok < 0)
4664 error("unexpected end of file in initializer");
4665 tok_str_add_tok(&init_str);
4666 if (tok == '{')
4667 level++;
4668 else if (tok == '}') {
4669 level--;
4670 if (level <= 0) {
4671 next();
4672 break;
4675 next();
4678 tok_str_add(&init_str, -1);
4679 tok_str_add(&init_str, 0);
4681 /* compute size */
4682 save_parse_state(&saved_parse_state);
4684 macro_ptr = init_str.str;
4685 next();
4686 decl_initializer(type, NULL, 0, 1, 1);
4687 /* prepare second initializer parsing */
4688 macro_ptr = init_str.str;
4689 next();
4691 /* if still unknown size, error */
4692 size = type_size(type, &align);
4693 if (size < 0)
4694 error("unknown type size");
4696 /* take into account specified alignment if bigger */
4697 if (ad->aligned) {
4698 if (ad->aligned > align)
4699 align = ad->aligned;
4700 } else if (ad->packed) {
4701 align = 1;
4703 if ((r & VT_VALMASK) == VT_LOCAL) {
4704 sec = NULL;
4705 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY))
4706 loc--;
4707 loc = (loc - size) & -align;
4708 addr = loc;
4709 /* handles bounds */
4710 /* XXX: currently, since we do only one pass, we cannot track
4711 '&' operators, so we add only arrays */
4712 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
4713 unsigned long *bounds_ptr;
4714 /* add padding between regions */
4715 loc--;
4716 /* then add local bound info */
4717 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
4718 bounds_ptr[0] = addr;
4719 bounds_ptr[1] = size;
4721 if (v) {
4722 /* local variable */
4723 sym_push(v, type, r, addr);
4724 } else {
4725 /* push local reference */
4726 vset(type, r, addr);
4728 } else {
4729 Sym *sym;
4731 sym = NULL;
4732 if (v && scope == VT_CONST) {
4733 /* see if the symbol was already defined */
4734 sym = sym_find(v);
4735 if (sym) {
4736 if (!is_compatible_types(&sym->type, type))
4737 error("incompatible types for redefinition of '%s'",
4738 get_tok_str(v, NULL));
4739 if (sym->type.t & VT_EXTERN) {
4740 /* if the variable is extern, it was not allocated */
4741 sym->type.t &= ~VT_EXTERN;
4742 /* set array size if it was ommited in extern
4743 declaration */
4744 if ((sym->type.t & VT_ARRAY) &&
4745 sym->type.ref->c < 0 &&
4746 type->ref->c >= 0)
4747 sym->type.ref->c = type->ref->c;
4748 } else {
4749 /* we accept several definitions of the same
4750 global variable. this is tricky, because we
4751 must play with the SHN_COMMON type of the symbol */
4752 /* XXX: should check if the variable was already
4753 initialized. It is incorrect to initialized it
4754 twice */
4755 /* no init data, we won't add more to the symbol */
4756 if (!has_init)
4757 goto no_alloc;
4762 /* allocate symbol in corresponding section */
4763 sec = ad->section;
4764 if (!sec) {
4765 if (has_init)
4766 sec = data_section;
4767 else if (tcc_state->nocommon)
4768 sec = bss_section;
4770 if (sec) {
4771 data_offset = sec->data_offset;
4772 data_offset = (data_offset + align - 1) & -align;
4773 addr = data_offset;
4774 /* very important to increment global pointer at this time
4775 because initializers themselves can create new initializers */
4776 data_offset += size;
4777 /* add padding if bound check */
4778 if (tcc_state->do_bounds_check)
4779 data_offset++;
4780 sec->data_offset = data_offset;
4781 /* allocate section space to put the data */
4782 if (sec->sh_type != SHT_NOBITS &&
4783 data_offset > sec->data_allocated)
4784 section_realloc(sec, data_offset);
4785 /* align section if needed */
4786 if (align > sec->sh_addralign)
4787 sec->sh_addralign = align;
4788 } else {
4789 addr = 0; /* avoid warning */
4792 if (v) {
4793 if (scope != VT_CONST || !sym) {
4794 sym = sym_push(v, type, r | VT_SYM, 0);
4796 /* update symbol definition */
4797 if (sec) {
4798 put_extern_sym(sym, sec, addr, size);
4799 } else {
4800 ElfW(Sym) *esym;
4801 /* put a common area */
4802 put_extern_sym(sym, NULL, align, size);
4803 /* XXX: find a nicer way */
4804 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
4805 esym->st_shndx = SHN_COMMON;
4807 } else {
4808 CValue cval;
4810 /* push global reference */
4811 sym = get_sym_ref(type, sec, addr, size);
4812 cval.ul = 0;
4813 vsetc(type, VT_CONST | VT_SYM, &cval);
4814 vtop->sym = sym;
4817 /* handles bounds now because the symbol must be defined
4818 before for the relocation */
4819 if (tcc_state->do_bounds_check) {
4820 unsigned long *bounds_ptr;
4822 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
4823 /* then add global bound info */
4824 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
4825 bounds_ptr[0] = 0; /* relocated */
4826 bounds_ptr[1] = size;
4829 if (has_init) {
4830 decl_initializer(type, sec, addr, 1, 0);
4831 /* restore parse state if needed */
4832 if (init_str.str) {
4833 tok_str_free(init_str.str);
4834 restore_parse_state(&saved_parse_state);
4837 no_alloc: ;
4840 void put_func_debug(Sym *sym)
4842 char buf[512];
4844 /* stabs info */
4845 /* XXX: we put here a dummy type */
4846 snprintf(buf, sizeof(buf), "%s:%c1",
4847 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
4848 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
4849 cur_text_section, sym->c);
4850 /* //gr gdb wants a line at the function */
4851 put_stabn(N_SLINE, 0, file->line_num, 0);
4852 last_ind = 0;
4853 last_line_num = 0;
4856 /* parse an old style function declaration list */
4857 /* XXX: check multiple parameter */
4858 static void func_decl_list(Sym *func_sym)
4860 AttributeDef ad;
4861 int v;
4862 Sym *s;
4863 CType btype, type;
4865 /* parse each declaration */
4866 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
4867 if (!parse_btype(&btype, &ad))
4868 expect("declaration list");
4869 if (((btype.t & VT_BTYPE) == VT_ENUM ||
4870 (btype.t & VT_BTYPE) == VT_STRUCT) &&
4871 tok == ';') {
4872 /* we accept no variable after */
4873 } else {
4874 for(;;) {
4875 type = btype;
4876 type_decl(&type, &ad, &v, TYPE_DIRECT);
4877 /* find parameter in function parameter list */
4878 s = func_sym->next;
4879 while (s != NULL) {
4880 if ((s->v & ~SYM_FIELD) == v)
4881 goto found;
4882 s = s->next;
4884 error("declaration for parameter '%s' but no such parameter",
4885 get_tok_str(v, NULL));
4886 found:
4887 /* check that no storage specifier except 'register' was given */
4888 if (type.t & VT_STORAGE)
4889 error("storage class specified for '%s'", get_tok_str(v, NULL));
4890 convert_parameter_type(&type);
4891 /* we can add the type (NOTE: it could be local to the function) */
4892 s->type = type;
4893 /* accept other parameters */
4894 if (tok == ',')
4895 next();
4896 else
4897 break;
4900 skip(';');
4904 /* parse a function defined by symbol 'sym' and generate its code in
4905 'cur_text_section' */
4906 static void gen_function(Sym *sym)
4908 int saved_nocode_wanted = nocode_wanted;
4909 nocode_wanted = 0;
4910 ind = cur_text_section->data_offset;
4911 /* NOTE: we patch the symbol size later */
4912 put_extern_sym(sym, cur_text_section, ind, 0);
4913 funcname = get_tok_str(sym->v, NULL);
4914 func_ind = ind;
4915 /* put debug symbol */
4916 if (tcc_state->do_debug)
4917 put_func_debug(sym);
4918 /* push a dummy symbol to enable local sym storage */
4919 sym_push2(&local_stack, SYM_FIELD, 0, 0);
4920 gfunc_prolog(&sym->type);
4921 rsym = 0;
4922 block(NULL, NULL, NULL, NULL, 0, 0);
4923 gsym(rsym);
4924 gfunc_epilog();
4925 cur_text_section->data_offset = ind;
4926 label_pop(&global_label_stack, NULL);
4927 sym_pop(&local_stack, NULL); /* reset local stack */
4928 /* end of function */
4929 /* patch symbol size */
4930 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
4931 ind - func_ind;
4932 if (tcc_state->do_debug) {
4933 put_stabn(N_FUN, 0, 0, ind - func_ind);
4935 /* It's better to crash than to generate wrong code */
4936 cur_text_section = NULL;
4937 funcname = ""; /* for safety */
4938 func_vt.t = VT_VOID; /* for safety */
4939 ind = 0; /* for safety */
4940 nocode_wanted = saved_nocode_wanted;
4943 static void gen_inline_functions(void)
4945 Sym *sym;
4946 int *str, inline_generated, i;
4947 struct InlineFunc *fn;
4949 /* iterate while inline function are referenced */
4950 for(;;) {
4951 inline_generated = 0;
4952 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
4953 fn = tcc_state->inline_fns[i];
4954 sym = fn->sym;
4955 if (sym && sym->c) {
4956 /* the function was used: generate its code and
4957 convert it to a normal function */
4958 str = fn->token_str;
4959 fn->sym = NULL;
4960 if (file)
4961 strcpy(file->filename, fn->filename);
4962 sym->r = VT_SYM | VT_CONST;
4963 sym->type.t &= ~VT_INLINE;
4965 macro_ptr = str;
4966 next();
4967 cur_text_section = text_section;
4968 gen_function(sym);
4969 macro_ptr = NULL; /* fail safe */
4971 inline_generated = 1;
4974 if (!inline_generated)
4975 break;
4977 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
4978 fn = tcc_state->inline_fns[i];
4979 str = fn->token_str;
4980 tok_str_free(str);
4982 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
4985 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
4986 static void decl(int l)
4988 int v, has_init, r;
4989 CType type, btype;
4990 Sym *sym;
4991 AttributeDef ad;
4993 while (1) {
4994 if (!parse_btype(&btype, &ad)) {
4995 /* skip redundant ';' */
4996 /* XXX: find more elegant solution */
4997 if (tok == ';') {
4998 next();
4999 continue;
5001 if (l == VT_CONST &&
5002 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5003 /* global asm block */
5004 asm_global_instr();
5005 continue;
5007 /* special test for old K&R protos without explicit int
5008 type. Only accepted when defining global data */
5009 if (l == VT_LOCAL || tok < TOK_DEFINE)
5010 break;
5011 btype.t = VT_INT;
5013 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5014 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5015 tok == ';') {
5016 /* we accept no variable after */
5017 next();
5018 continue;
5020 while (1) { /* iterate thru each declaration */
5021 type = btype;
5022 type_decl(&type, &ad, &v, TYPE_DIRECT);
5023 #if 0
5025 char buf[500];
5026 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5027 printf("type = '%s'\n", buf);
5029 #endif
5030 if ((type.t & VT_BTYPE) == VT_FUNC) {
5031 /* if old style function prototype, we accept a
5032 declaration list */
5033 sym = type.ref;
5034 if (sym->c == FUNC_OLD)
5035 func_decl_list(sym);
5038 if (tok == '{') {
5039 if (l == VT_LOCAL)
5040 error("cannot use local functions");
5041 if ((type.t & VT_BTYPE) != VT_FUNC)
5042 expect("function definition");
5044 /* reject abstract declarators in function definition */
5045 sym = type.ref;
5046 while ((sym = sym->next) != NULL)
5047 if (!(sym->v & ~SYM_FIELD))
5048 expect("identifier");
5050 /* XXX: cannot do better now: convert extern line to static inline */
5051 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5052 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5054 sym = sym_find(v);
5055 if (sym) {
5056 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5057 goto func_error1;
5059 r = sym->type.ref->r;
5060 /* use func_call from prototype if not defined */
5061 if (FUNC_CALL(r) != FUNC_CDECL
5062 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5063 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5065 /* use export from prototype */
5066 if (FUNC_EXPORT(r))
5067 FUNC_EXPORT(type.ref->r) = 1;
5069 /* use static from prototype */
5070 if (sym->type.t & VT_STATIC)
5071 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5073 if (!is_compatible_types(&sym->type, &type)) {
5074 func_error1:
5075 error("incompatible types for redefinition of '%s'",
5076 get_tok_str(v, NULL));
5078 /* if symbol is already defined, then put complete type */
5079 sym->type = type;
5080 } else {
5081 /* put function symbol */
5082 sym = global_identifier_push(v, type.t, 0);
5083 sym->type.ref = type.ref;
5086 /* static inline functions are just recorded as a kind
5087 of macro. Their code will be emitted at the end of
5088 the compilation unit only if they are used */
5089 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5090 (VT_INLINE | VT_STATIC)) {
5091 TokenString func_str;
5092 int block_level;
5093 struct InlineFunc *fn;
5094 const char *filename;
5096 tok_str_new(&func_str);
5098 block_level = 0;
5099 for(;;) {
5100 int t;
5101 if (tok == TOK_EOF)
5102 error("unexpected end of file");
5103 tok_str_add_tok(&func_str);
5104 t = tok;
5105 next();
5106 if (t == '{') {
5107 block_level++;
5108 } else if (t == '}') {
5109 block_level--;
5110 if (block_level == 0)
5111 break;
5114 tok_str_add(&func_str, -1);
5115 tok_str_add(&func_str, 0);
5116 filename = file ? file->filename : "";
5117 fn = tcc_malloc(sizeof *fn + strlen(filename));
5118 strcpy(fn->filename, filename);
5119 fn->sym = sym;
5120 fn->token_str = func_str.str;
5121 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5123 } else {
5124 /* compute text section */
5125 cur_text_section = ad.section;
5126 if (!cur_text_section)
5127 cur_text_section = text_section;
5128 sym->r = VT_SYM | VT_CONST;
5129 gen_function(sym);
5131 break;
5132 } else {
5133 if (btype.t & VT_TYPEDEF) {
5134 /* save typedefed type */
5135 /* XXX: test storage specifiers ? */
5136 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5137 sym->type.t |= VT_TYPEDEF;
5138 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
5139 /* external function definition */
5140 /* specific case for func_call attribute */
5141 type.ref->r = INT_ATTR(&ad);
5142 external_sym(v, &type, 0);
5143 } else {
5144 /* not lvalue if array */
5145 r = 0;
5146 if (!(type.t & VT_ARRAY))
5147 r |= lvalue_type(type.t);
5148 has_init = (tok == '=');
5149 if ((btype.t & VT_EXTERN) ||
5150 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5151 !has_init && l == VT_CONST && type.ref->c < 0)) {
5152 /* external variable */
5153 /* NOTE: as GCC, uninitialized global static
5154 arrays of null size are considered as
5155 extern */
5156 #ifdef TCC_TARGET_PE
5157 if (ad.func_import)
5158 type.t |= VT_IMPORT;
5159 #endif
5160 external_sym(v, &type, r);
5161 } else {
5162 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5163 if (type.t & VT_STATIC)
5164 r |= VT_CONST;
5165 else
5166 r |= l;
5167 if (has_init)
5168 next();
5169 #ifdef TCC_TARGET_PE
5170 if (ad.func_export)
5171 type.t |= VT_EXPORT;
5172 #endif
5173 decl_initializer_alloc(&type, &ad, r,
5174 has_init, v, l);
5177 if (tok != ',') {
5178 skip(';');
5179 break;
5181 next();