win32: treat long double as double
[tinycc.git] / tccgen.c
blob65db0ac87c5e444282154e88d1993762658cd809
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 cval.ull = v;
65 vsetc(&ctype, VT_CONST, &cval);
68 /* Return a static symbol pointing to a section */
69 static Sym *get_sym_ref(CType *type, Section *sec,
70 unsigned long offset, unsigned long size)
72 int v;
73 Sym *sym;
75 v = anon_sym++;
76 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
77 sym->type.ref = type->ref;
78 sym->r = VT_CONST | VT_SYM;
79 put_extern_sym(sym, sec, offset, size);
80 return sym;
83 /* push a reference to a section offset by adding a dummy symbol */
84 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
86 CValue cval;
88 cval.ul = 0;
89 vsetc(type, VT_CONST | VT_SYM, &cval);
90 vtop->sym = get_sym_ref(type, sec, offset, size);
93 /* define a new external reference to a symbol 'v' of type 'u' */
94 static Sym *external_global_sym(int v, CType *type, int r)
96 Sym *s;
98 s = sym_find(v);
99 if (!s) {
100 /* push forward reference */
101 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
102 s->type.ref = type->ref;
103 s->r = r | VT_CONST | VT_SYM;
105 return s;
108 /* define a new external reference to a symbol 'v' of type 'u' */
109 static Sym *external_sym(int v, CType *type, int r)
111 Sym *s;
113 s = sym_find(v);
114 if (!s) {
115 /* push forward reference */
116 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
117 s->type.t |= VT_EXTERN;
118 } else if (s->type.ref == func_old_type.ref) {
119 s->type.ref = type->ref;
120 s->r = r | VT_CONST | VT_SYM;
121 s->type.t |= VT_EXTERN;
122 } else if (!is_compatible_types(&s->type, type)) {
123 error("incompatible types for redefinition of '%s'",
124 get_tok_str(v, NULL));
126 return s;
129 /* push a reference to global symbol v */
130 static void vpush_global_sym(CType *type, int v)
132 Sym *sym;
133 CValue cval;
135 sym = external_global_sym(v, type, 0);
136 cval.ul = 0;
137 vsetc(type, VT_CONST | VT_SYM, &cval);
138 vtop->sym = sym;
141 void vset(CType *type, int r, int v)
143 CValue cval;
145 cval.i = v;
146 vsetc(type, r, &cval);
149 void vseti(int r, int v)
151 CType type;
152 type.t = VT_INT;
153 vset(&type, r, v);
156 void vswap(void)
158 SValue tmp;
160 tmp = vtop[0];
161 vtop[0] = vtop[-1];
162 vtop[-1] = tmp;
165 void vpushv(SValue *v)
167 if (vtop >= vstack + (VSTACK_SIZE - 1))
168 error("memory full");
169 vtop++;
170 *vtop = *v;
173 void vdup(void)
175 vpushv(vtop);
178 /* save r to the memory stack, and mark it as being free */
179 void save_reg(int r)
181 int l, saved, size, align;
182 SValue *p, sv;
183 CType *type;
185 /* modify all stack values */
186 saved = 0;
187 l = 0;
188 for(p=vstack;p<=vtop;p++) {
189 if ((p->r & VT_VALMASK) == r ||
190 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
191 /* must save value on stack if not already done */
192 if (!saved) {
193 /* NOTE: must reload 'r' because r might be equal to r2 */
194 r = p->r & VT_VALMASK;
195 /* store register in the stack */
196 type = &p->type;
197 if ((p->r & VT_LVAL) ||
198 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
199 #ifdef TCC_TARGET_X86_64
200 type = &char_pointer_type;
201 #else
202 type = &int_type;
203 #endif
204 size = type_size(type, &align);
205 loc = (loc - size) & -align;
206 sv.type.t = type->t;
207 sv.r = VT_LOCAL | VT_LVAL;
208 sv.c.ul = loc;
209 store(r, &sv);
210 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
211 /* x86 specific: need to pop fp register ST0 if saved */
212 if (r == TREG_ST0) {
213 o(0xd8dd); /* fstp %st(0) */
215 #endif
216 #ifndef TCC_TARGET_X86_64
217 /* special long long case */
218 if ((type->t & VT_BTYPE) == VT_LLONG) {
219 sv.c.ul += 4;
220 store(p->r2, &sv);
222 #endif
223 l = loc;
224 saved = 1;
226 /* mark that stack entry as being saved on the stack */
227 if (p->r & VT_LVAL) {
228 /* also clear the bounded flag because the
229 relocation address of the function was stored in
230 p->c.ul */
231 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
232 } else {
233 p->r = lvalue_type(p->type.t) | VT_LOCAL;
235 p->r2 = VT_CONST;
236 p->c.ul = l;
241 /* find a register of class 'rc2' with at most one reference on stack.
242 * If none, call get_reg(rc) */
243 int get_reg_ex(int rc, int rc2)
245 int r;
246 SValue *p;
248 for(r=0;r<NB_REGS;r++) {
249 if (reg_classes[r] & rc2) {
250 int n;
251 n=0;
252 for(p = vstack; p <= vtop; p++) {
253 if ((p->r & VT_VALMASK) == r ||
254 (p->r2 & VT_VALMASK) == r)
255 n++;
257 if (n <= 1)
258 return r;
261 return get_reg(rc);
264 /* find a free register of class 'rc'. If none, save one register */
265 int get_reg(int rc)
267 int r;
268 SValue *p;
270 /* find a free register */
271 for(r=0;r<NB_REGS;r++) {
272 if (reg_classes[r] & rc) {
273 for(p=vstack;p<=vtop;p++) {
274 if ((p->r & VT_VALMASK) == r ||
275 (p->r2 & VT_VALMASK) == r)
276 goto notfound;
278 return r;
280 notfound: ;
283 /* no register left : free the first one on the stack (VERY
284 IMPORTANT to start from the bottom to ensure that we don't
285 spill registers used in gen_opi()) */
286 for(p=vstack;p<=vtop;p++) {
287 r = p->r & VT_VALMASK;
288 if (r < VT_CONST && (reg_classes[r] & rc))
289 goto save_found;
290 /* also look at second register (if long long) */
291 r = p->r2 & VT_VALMASK;
292 if (r < VT_CONST && (reg_classes[r] & rc)) {
293 save_found:
294 save_reg(r);
295 return r;
298 /* Should never comes here */
299 return -1;
302 /* save registers up to (vtop - n) stack entry */
303 void save_regs(int n)
305 int r;
306 SValue *p, *p1;
307 p1 = vtop - n;
308 for(p = vstack;p <= p1; p++) {
309 r = p->r & VT_VALMASK;
310 if (r < VT_CONST) {
311 save_reg(r);
316 /* move register 's' to 'r', and flush previous value of r to memory
317 if needed */
318 void move_reg(int r, int s)
320 SValue sv;
322 if (r != s) {
323 save_reg(r);
324 sv.type.t = VT_INT;
325 sv.r = s;
326 sv.c.ul = 0;
327 load(r, &sv);
331 /* get address of vtop (vtop MUST BE an lvalue) */
332 void gaddrof(void)
334 vtop->r &= ~VT_LVAL;
335 /* tricky: if saved lvalue, then we can go back to lvalue */
336 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
337 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
340 #ifdef CONFIG_TCC_BCHECK
341 /* generate lvalue bound code */
342 void gbound(void)
344 int lval_type;
345 CType type1;
347 vtop->r &= ~VT_MUSTBOUND;
348 /* if lvalue, then use checking code before dereferencing */
349 if (vtop->r & VT_LVAL) {
350 /* if not VT_BOUNDED value, then make one */
351 if (!(vtop->r & VT_BOUNDED)) {
352 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
353 /* must save type because we must set it to int to get pointer */
354 type1 = vtop->type;
355 vtop->type.t = VT_INT;
356 gaddrof();
357 vpushi(0);
358 gen_bounded_ptr_add();
359 vtop->r |= lval_type;
360 vtop->type = type1;
362 /* then check for dereferencing */
363 gen_bounded_ptr_deref();
366 #endif
368 /* store vtop a register belonging to class 'rc'. lvalues are
369 converted to values. Cannot be used if cannot be converted to
370 register value (such as structures). */
371 int gv(int rc)
373 int r, rc2, bit_pos, bit_size, size, align, i;
375 /* NOTE: get_reg can modify vstack[] */
376 if (vtop->type.t & VT_BITFIELD) {
377 CType type;
378 int bits = 32;
379 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
380 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
381 /* remove bit field info to avoid loops */
382 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
383 /* cast to int to propagate signedness in following ops */
384 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
385 type.t = VT_LLONG;
386 bits = 64;
387 } else
388 type.t = VT_INT;
389 if((vtop->type.t & VT_UNSIGNED) ||
390 (vtop->type.t & VT_BTYPE) == VT_BOOL)
391 type.t |= VT_UNSIGNED;
392 gen_cast(&type);
393 /* generate shifts */
394 vpushi(bits - (bit_pos + bit_size));
395 gen_op(TOK_SHL);
396 vpushi(bits - bit_size);
397 /* NOTE: transformed to SHR if unsigned */
398 gen_op(TOK_SAR);
399 r = gv(rc);
400 } else {
401 if (is_float(vtop->type.t) &&
402 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
403 Sym *sym;
404 int *ptr;
405 unsigned long offset;
406 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
407 CValue check;
408 #endif
410 /* XXX: unify with initializers handling ? */
411 /* CPUs usually cannot use float constants, so we store them
412 generically in data segment */
413 size = type_size(&vtop->type, &align);
414 offset = (data_section->data_offset + align - 1) & -align;
415 data_section->data_offset = offset;
416 /* XXX: not portable yet */
417 #if defined(__i386__) || defined(__x86_64__)
418 /* Zero pad x87 tenbyte long doubles */
419 if (size == LDOUBLE_SIZE)
420 vtop->c.tab[2] &= 0xffff;
421 #endif
422 ptr = section_ptr_add(data_section, size);
423 size = size >> 2;
424 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
425 check.d = 1;
426 if(check.tab[0])
427 for(i=0;i<size;i++)
428 ptr[i] = vtop->c.tab[size-1-i];
429 else
430 #endif
431 for(i=0;i<size;i++)
432 ptr[i] = vtop->c.tab[i];
433 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
434 vtop->r |= VT_LVAL | VT_SYM;
435 vtop->sym = sym;
436 vtop->c.ul = 0;
438 #ifdef CONFIG_TCC_BCHECK
439 if (vtop->r & VT_MUSTBOUND)
440 gbound();
441 #endif
443 r = vtop->r & VT_VALMASK;
444 rc2 = RC_INT;
445 if (rc == RC_IRET)
446 rc2 = RC_LRET;
447 /* need to reload if:
448 - constant
449 - lvalue (need to dereference pointer)
450 - already a register, but not in the right class */
451 if (r >= VT_CONST ||
452 (vtop->r & VT_LVAL) ||
453 !(reg_classes[r] & rc) ||
454 ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
455 !(reg_classes[vtop->r2] & rc2))) {
456 r = get_reg(rc);
457 #ifndef TCC_TARGET_X86_64
458 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
459 int r2;
460 unsigned long long ll;
461 /* two register type load : expand to two words
462 temporarily */
463 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
464 /* load constant */
465 ll = vtop->c.ull;
466 vtop->c.ui = ll; /* first word */
467 load(r, vtop);
468 vtop->r = r; /* save register value */
469 vpushi(ll >> 32); /* second word */
470 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
471 (vtop->r & VT_LVAL)) {
472 /* We do not want to modifier the long long
473 pointer here, so the safest (and less
474 efficient) is to save all the other registers
475 in the stack. XXX: totally inefficient. */
476 save_regs(1);
477 /* load from memory */
478 load(r, vtop);
479 vdup();
480 vtop[-1].r = r; /* save register value */
481 /* increment pointer to get second word */
482 vtop->type.t = VT_INT;
483 gaddrof();
484 vpushi(4);
485 gen_op('+');
486 vtop->r |= VT_LVAL;
487 } else {
488 /* move registers */
489 load(r, vtop);
490 vdup();
491 vtop[-1].r = r; /* save register value */
492 vtop->r = vtop[-1].r2;
494 /* allocate second register */
495 r2 = get_reg(rc2);
496 load(r2, vtop);
497 vpop();
498 /* write second register */
499 vtop->r2 = r2;
500 } else
501 #endif
502 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
503 int t1, t;
504 /* lvalue of scalar type : need to use lvalue type
505 because of possible cast */
506 t = vtop->type.t;
507 t1 = t;
508 /* compute memory access type */
509 if (vtop->r & VT_LVAL_BYTE)
510 t = VT_BYTE;
511 else if (vtop->r & VT_LVAL_SHORT)
512 t = VT_SHORT;
513 if (vtop->r & VT_LVAL_UNSIGNED)
514 t |= VT_UNSIGNED;
515 vtop->type.t = t;
516 load(r, vtop);
517 /* restore wanted type */
518 vtop->type.t = t1;
519 } else {
520 /* one register type load */
521 load(r, vtop);
524 vtop->r = r;
525 #ifdef TCC_TARGET_C67
526 /* uses register pairs for doubles */
527 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
528 vtop->r2 = r+1;
529 #endif
531 return r;
534 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
535 void gv2(int rc1, int rc2)
537 int v;
539 /* generate more generic register first. But VT_JMP or VT_CMP
540 values must be generated first in all cases to avoid possible
541 reload errors */
542 v = vtop[0].r & VT_VALMASK;
543 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
544 vswap();
545 gv(rc1);
546 vswap();
547 gv(rc2);
548 /* test if reload is needed for first register */
549 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
550 vswap();
551 gv(rc1);
552 vswap();
554 } else {
555 gv(rc2);
556 vswap();
557 gv(rc1);
558 vswap();
559 /* test if reload is needed for first register */
560 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
561 gv(rc2);
566 /* wrapper around RC_FRET to return a register by type */
567 int rc_fret(int t)
569 #ifdef TCC_TARGET_X86_64
570 if (t == VT_LDOUBLE) {
571 return RC_ST0;
573 #endif
574 return RC_FRET;
577 /* wrapper around REG_FRET to return a register by type */
578 int reg_fret(int t)
580 #ifdef TCC_TARGET_X86_64
581 if (t == VT_LDOUBLE) {
582 return TREG_ST0;
584 #endif
585 return REG_FRET;
588 /* expand long long on stack in two int registers */
589 void lexpand(void)
591 int u;
593 u = vtop->type.t & VT_UNSIGNED;
594 gv(RC_INT);
595 vdup();
596 vtop[0].r = vtop[-1].r2;
597 vtop[0].r2 = VT_CONST;
598 vtop[-1].r2 = VT_CONST;
599 vtop[0].type.t = VT_INT | u;
600 vtop[-1].type.t = VT_INT | u;
603 #ifdef TCC_TARGET_ARM
604 /* expand long long on stack */
605 void lexpand_nr(void)
607 int u,v;
609 u = vtop->type.t & VT_UNSIGNED;
610 vdup();
611 vtop->r2 = VT_CONST;
612 vtop->type.t = VT_INT | u;
613 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
614 if (v == VT_CONST) {
615 vtop[-1].c.ui = vtop->c.ull;
616 vtop->c.ui = vtop->c.ull >> 32;
617 vtop->r = VT_CONST;
618 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
619 vtop->c.ui += 4;
620 vtop->r = vtop[-1].r;
621 } else if (v > VT_CONST) {
622 vtop--;
623 lexpand();
624 } else
625 vtop->r = vtop[-1].r2;
626 vtop[-1].r2 = VT_CONST;
627 vtop[-1].type.t = VT_INT | u;
629 #endif
631 /* build a long long from two ints */
632 void lbuild(int t)
634 gv2(RC_INT, RC_INT);
635 vtop[-1].r2 = vtop[0].r;
636 vtop[-1].type.t = t;
637 vpop();
640 /* rotate n first stack elements to the bottom
641 I1 ... In -> I2 ... In I1 [top is right]
643 void vrotb(int n)
645 int i;
646 SValue tmp;
648 tmp = vtop[-n + 1];
649 for(i=-n+1;i!=0;i++)
650 vtop[i] = vtop[i+1];
651 vtop[0] = tmp;
654 /* rotate n first stack elements to the top
655 I1 ... In -> In I1 ... I(n-1) [top is right]
657 void vrott(int n)
659 int i;
660 SValue tmp;
662 tmp = vtop[0];
663 for(i = 0;i < n - 1; i++)
664 vtop[-i] = vtop[-i - 1];
665 vtop[-n + 1] = tmp;
668 #ifdef TCC_TARGET_ARM
669 /* like vrott but in other direction
670 In ... I1 -> I(n-1) ... I1 In [top is right]
672 void vnrott(int n)
674 int i;
675 SValue tmp;
677 tmp = vtop[-n + 1];
678 for(i = n - 1; i > 0; i--)
679 vtop[-i] = vtop[-i + 1];
680 vtop[0] = tmp;
682 #endif
684 /* pop stack value */
685 void vpop(void)
687 int v;
688 v = vtop->r & VT_VALMASK;
689 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
690 /* for x86, we need to pop the FP stack */
691 if (v == TREG_ST0 && !nocode_wanted) {
692 o(0xd8dd); /* fstp %st(0) */
693 } else
694 #endif
695 if (v == VT_JMP || v == VT_JMPI) {
696 /* need to put correct jump if && or || without test */
697 gsym(vtop->c.ul);
699 vtop--;
702 /* convert stack entry to register and duplicate its value in another
703 register */
704 void gv_dup(void)
706 int rc, t, r, r1;
707 SValue sv;
709 t = vtop->type.t;
710 if ((t & VT_BTYPE) == VT_LLONG) {
711 lexpand();
712 gv_dup();
713 vswap();
714 vrotb(3);
715 gv_dup();
716 vrotb(4);
717 /* stack: H L L1 H1 */
718 lbuild(t);
719 vrotb(3);
720 vrotb(3);
721 vswap();
722 lbuild(t);
723 vswap();
724 } else {
725 /* duplicate value */
726 rc = RC_INT;
727 sv.type.t = VT_INT;
728 if (is_float(t)) {
729 rc = RC_FLOAT;
730 #ifdef TCC_TARGET_X86_64
731 if ((t & VT_BTYPE) == VT_LDOUBLE) {
732 rc = RC_ST0;
734 #endif
735 sv.type.t = t;
737 r = gv(rc);
738 r1 = get_reg(rc);
739 sv.r = r;
740 sv.c.ul = 0;
741 load(r1, &sv); /* move r to r1 */
742 vdup();
743 /* duplicates value */
744 if (r != r1)
745 vtop->r = r1;
749 #ifndef TCC_TARGET_X86_64
750 /* generate CPU independent (unsigned) long long operations */
751 void gen_opl(int op)
753 int t, a, b, op1, c, i;
754 int func;
755 unsigned short reg_iret = REG_IRET;
756 unsigned short reg_lret = REG_LRET;
757 SValue tmp;
759 switch(op) {
760 case '/':
761 case TOK_PDIV:
762 func = TOK___divdi3;
763 goto gen_func;
764 case TOK_UDIV:
765 func = TOK___udivdi3;
766 goto gen_func;
767 case '%':
768 func = TOK___moddi3;
769 goto gen_mod_func;
770 case TOK_UMOD:
771 func = TOK___umoddi3;
772 gen_mod_func:
773 #ifdef TCC_ARM_EABI
774 reg_iret = TREG_R2;
775 reg_lret = TREG_R3;
776 #endif
777 gen_func:
778 /* call generic long long function */
779 vpush_global_sym(&func_old_type, func);
780 vrott(3);
781 gfunc_call(2);
782 vpushi(0);
783 vtop->r = reg_iret;
784 vtop->r2 = reg_lret;
785 break;
786 case '^':
787 case '&':
788 case '|':
789 case '*':
790 case '+':
791 case '-':
792 t = vtop->type.t;
793 vswap();
794 lexpand();
795 vrotb(3);
796 lexpand();
797 /* stack: L1 H1 L2 H2 */
798 tmp = vtop[0];
799 vtop[0] = vtop[-3];
800 vtop[-3] = tmp;
801 tmp = vtop[-2];
802 vtop[-2] = vtop[-3];
803 vtop[-3] = tmp;
804 vswap();
805 /* stack: H1 H2 L1 L2 */
806 if (op == '*') {
807 vpushv(vtop - 1);
808 vpushv(vtop - 1);
809 gen_op(TOK_UMULL);
810 lexpand();
811 /* stack: H1 H2 L1 L2 ML MH */
812 for(i=0;i<4;i++)
813 vrotb(6);
814 /* stack: ML MH H1 H2 L1 L2 */
815 tmp = vtop[0];
816 vtop[0] = vtop[-2];
817 vtop[-2] = tmp;
818 /* stack: ML MH H1 L2 H2 L1 */
819 gen_op('*');
820 vrotb(3);
821 vrotb(3);
822 gen_op('*');
823 /* stack: ML MH M1 M2 */
824 gen_op('+');
825 gen_op('+');
826 } else if (op == '+' || op == '-') {
827 /* XXX: add non carry method too (for MIPS or alpha) */
828 if (op == '+')
829 op1 = TOK_ADDC1;
830 else
831 op1 = TOK_SUBC1;
832 gen_op(op1);
833 /* stack: H1 H2 (L1 op L2) */
834 vrotb(3);
835 vrotb(3);
836 gen_op(op1 + 1); /* TOK_xxxC2 */
837 } else {
838 gen_op(op);
839 /* stack: H1 H2 (L1 op L2) */
840 vrotb(3);
841 vrotb(3);
842 /* stack: (L1 op L2) H1 H2 */
843 gen_op(op);
844 /* stack: (L1 op L2) (H1 op H2) */
846 /* stack: L H */
847 lbuild(t);
848 break;
849 case TOK_SAR:
850 case TOK_SHR:
851 case TOK_SHL:
852 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
853 t = vtop[-1].type.t;
854 vswap();
855 lexpand();
856 vrotb(3);
857 /* stack: L H shift */
858 c = (int)vtop->c.i;
859 /* constant: simpler */
860 /* NOTE: all comments are for SHL. the other cases are
861 done by swaping words */
862 vpop();
863 if (op != TOK_SHL)
864 vswap();
865 if (c >= 32) {
866 /* stack: L H */
867 vpop();
868 if (c > 32) {
869 vpushi(c - 32);
870 gen_op(op);
872 if (op != TOK_SAR) {
873 vpushi(0);
874 } else {
875 gv_dup();
876 vpushi(31);
877 gen_op(TOK_SAR);
879 vswap();
880 } else {
881 vswap();
882 gv_dup();
883 /* stack: H L L */
884 vpushi(c);
885 gen_op(op);
886 vswap();
887 vpushi(32 - c);
888 if (op == TOK_SHL)
889 gen_op(TOK_SHR);
890 else
891 gen_op(TOK_SHL);
892 vrotb(3);
893 /* stack: L L H */
894 vpushi(c);
895 if (op == TOK_SHL)
896 gen_op(TOK_SHL);
897 else
898 gen_op(TOK_SHR);
899 gen_op('|');
901 if (op != TOK_SHL)
902 vswap();
903 lbuild(t);
904 } else {
905 /* XXX: should provide a faster fallback on x86 ? */
906 switch(op) {
907 case TOK_SAR:
908 func = TOK___ashrdi3;
909 goto gen_func;
910 case TOK_SHR:
911 func = TOK___lshrdi3;
912 goto gen_func;
913 case TOK_SHL:
914 func = TOK___ashldi3;
915 goto gen_func;
918 break;
919 default:
920 /* compare operations */
921 t = vtop->type.t;
922 vswap();
923 lexpand();
924 vrotb(3);
925 lexpand();
926 /* stack: L1 H1 L2 H2 */
927 tmp = vtop[-1];
928 vtop[-1] = vtop[-2];
929 vtop[-2] = tmp;
930 /* stack: L1 L2 H1 H2 */
931 /* compare high */
932 op1 = op;
933 /* when values are equal, we need to compare low words. since
934 the jump is inverted, we invert the test too. */
935 if (op1 == TOK_LT)
936 op1 = TOK_LE;
937 else if (op1 == TOK_GT)
938 op1 = TOK_GE;
939 else if (op1 == TOK_ULT)
940 op1 = TOK_ULE;
941 else if (op1 == TOK_UGT)
942 op1 = TOK_UGE;
943 a = 0;
944 b = 0;
945 gen_op(op1);
946 if (op1 != TOK_NE) {
947 a = gtst(1, 0);
949 if (op != TOK_EQ) {
950 /* generate non equal test */
951 /* XXX: NOT PORTABLE yet */
952 if (a == 0) {
953 b = gtst(0, 0);
954 } else {
955 #if defined(TCC_TARGET_I386)
956 b = psym(0x850f, 0);
957 #elif defined(TCC_TARGET_ARM)
958 b = ind;
959 o(0x1A000000 | encbranch(ind, 0, 1));
960 #elif defined(TCC_TARGET_C67)
961 error("not implemented");
962 #else
963 #error not supported
964 #endif
967 /* compare low. Always unsigned */
968 op1 = op;
969 if (op1 == TOK_LT)
970 op1 = TOK_ULT;
971 else if (op1 == TOK_LE)
972 op1 = TOK_ULE;
973 else if (op1 == TOK_GT)
974 op1 = TOK_UGT;
975 else if (op1 == TOK_GE)
976 op1 = TOK_UGE;
977 gen_op(op1);
978 a = gtst(1, a);
979 gsym(b);
980 vseti(VT_JMPI, a);
981 break;
984 #endif
986 /* handle integer constant optimizations and various machine
987 independent opt */
988 void gen_opic(int op)
990 int c1, c2, t1, t2, n;
991 SValue *v1, *v2;
992 long long l1, l2;
993 typedef unsigned long long U;
995 v1 = vtop - 1;
996 v2 = vtop;
997 t1 = v1->type.t & VT_BTYPE;
998 t2 = v2->type.t & VT_BTYPE;
1000 if (t1 == VT_LLONG)
1001 l1 = v1->c.ll;
1002 else if (v1->type.t & VT_UNSIGNED)
1003 l1 = v1->c.ui;
1004 else
1005 l1 = v1->c.i;
1007 if (t2 == VT_LLONG)
1008 l2 = v2->c.ll;
1009 else if (v2->type.t & VT_UNSIGNED)
1010 l2 = v2->c.ui;
1011 else
1012 l2 = v2->c.i;
1014 /* currently, we cannot do computations with forward symbols */
1015 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1016 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1017 if (c1 && c2) {
1018 switch(op) {
1019 case '+': l1 += l2; break;
1020 case '-': l1 -= l2; break;
1021 case '&': l1 &= l2; break;
1022 case '^': l1 ^= l2; break;
1023 case '|': l1 |= l2; break;
1024 case '*': l1 *= l2; break;
1026 case TOK_PDIV:
1027 case '/':
1028 case '%':
1029 case TOK_UDIV:
1030 case TOK_UMOD:
1031 /* if division by zero, generate explicit division */
1032 if (l2 == 0) {
1033 if (const_wanted)
1034 error("division by zero in constant");
1035 goto general_case;
1037 switch(op) {
1038 default: l1 /= l2; break;
1039 case '%': l1 %= l2; break;
1040 case TOK_UDIV: l1 = (U)l1 / l2; break;
1041 case TOK_UMOD: l1 = (U)l1 % l2; break;
1043 break;
1044 case TOK_SHL: l1 <<= l2; break;
1045 case TOK_SHR: l1 = (U)l1 >> l2; break;
1046 case TOK_SAR: l1 >>= l2; break;
1047 /* tests */
1048 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1049 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1050 case TOK_EQ: l1 = l1 == l2; break;
1051 case TOK_NE: l1 = l1 != l2; break;
1052 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1053 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1054 case TOK_LT: l1 = l1 < l2; break;
1055 case TOK_GE: l1 = l1 >= l2; break;
1056 case TOK_LE: l1 = l1 <= l2; break;
1057 case TOK_GT: l1 = l1 > l2; break;
1058 /* logical */
1059 case TOK_LAND: l1 = l1 && l2; break;
1060 case TOK_LOR: l1 = l1 || l2; break;
1061 default:
1062 goto general_case;
1064 v1->c.ll = l1;
1065 vtop--;
1066 } else {
1067 /* if commutative ops, put c2 as constant */
1068 if (c1 && (op == '+' || op == '&' || op == '^' ||
1069 op == '|' || op == '*')) {
1070 vswap();
1071 c2 = c1; //c = c1, c1 = c2, c2 = c;
1072 l2 = l1; //l = l1, l1 = l2, l2 = l;
1074 /* Filter out NOP operations like x*1, x-0, x&-1... */
1075 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1076 op == TOK_PDIV) &&
1077 l2 == 1) ||
1078 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1079 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1080 l2 == 0) ||
1081 (op == '&' &&
1082 l2 == -1))) {
1083 /* nothing to do */
1084 vtop--;
1085 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1086 /* try to use shifts instead of muls or divs */
1087 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1088 n = -1;
1089 while (l2) {
1090 l2 >>= 1;
1091 n++;
1093 vtop->c.ll = n;
1094 if (op == '*')
1095 op = TOK_SHL;
1096 else if (op == TOK_PDIV)
1097 op = TOK_SAR;
1098 else
1099 op = TOK_SHR;
1101 goto general_case;
1102 } else if (c2 && (op == '+' || op == '-') &&
1103 ((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
1104 (VT_CONST | VT_SYM) ||
1105 (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1106 /* symbol + constant case */
1107 if (op == '-')
1108 l2 = -l2;
1109 vtop--;
1110 vtop->c.ll += l2;
1111 } else {
1112 general_case:
1113 if (!nocode_wanted) {
1114 /* call low level op generator */
1115 if (t1 == VT_LLONG || t2 == VT_LLONG)
1116 gen_opl(op);
1117 else
1118 gen_opi(op);
1119 } else {
1120 vtop--;
1126 /* generate a floating point operation with constant propagation */
1127 void gen_opif(int op)
1129 int c1, c2;
1130 SValue *v1, *v2;
1131 long double f1, f2;
1133 v1 = vtop - 1;
1134 v2 = vtop;
1135 /* currently, we cannot do computations with forward symbols */
1136 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1137 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1138 if (c1 && c2) {
1139 if (v1->type.t == VT_FLOAT) {
1140 f1 = v1->c.f;
1141 f2 = v2->c.f;
1142 } else if (v1->type.t == VT_DOUBLE) {
1143 f1 = v1->c.d;
1144 f2 = v2->c.d;
1145 } else {
1146 f1 = v1->c.ld;
1147 f2 = v2->c.ld;
1150 /* NOTE: we only do constant propagation if finite number (not
1151 NaN or infinity) (ANSI spec) */
1152 if (!ieee_finite(f1) || !ieee_finite(f2))
1153 goto general_case;
1155 switch(op) {
1156 case '+': f1 += f2; break;
1157 case '-': f1 -= f2; break;
1158 case '*': f1 *= f2; break;
1159 case '/':
1160 if (f2 == 0.0) {
1161 if (const_wanted)
1162 error("division by zero in constant");
1163 goto general_case;
1165 f1 /= f2;
1166 break;
1167 /* XXX: also handles tests ? */
1168 default:
1169 goto general_case;
1171 /* XXX: overflow test ? */
1172 if (v1->type.t == VT_FLOAT) {
1173 v1->c.f = f1;
1174 } else if (v1->type.t == VT_DOUBLE) {
1175 v1->c.d = f1;
1176 } else {
1177 v1->c.ld = f1;
1179 vtop--;
1180 } else {
1181 general_case:
1182 if (!nocode_wanted) {
1183 gen_opf(op);
1184 } else {
1185 vtop--;
1190 static int pointed_size(CType *type)
1192 int align;
1193 return type_size(pointed_type(type), &align);
1196 static inline int is_null_pointer(SValue *p)
1198 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1199 return 0;
1200 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1201 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
1204 static inline int is_integer_btype(int bt)
1206 return (bt == VT_BYTE || bt == VT_SHORT ||
1207 bt == VT_INT || bt == VT_LLONG);
1210 /* check types for comparison or substraction of pointers */
1211 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1213 CType *type1, *type2, tmp_type1, tmp_type2;
1214 int bt1, bt2;
1216 /* null pointers are accepted for all comparisons as gcc */
1217 if (is_null_pointer(p1) || is_null_pointer(p2))
1218 return;
1219 type1 = &p1->type;
1220 type2 = &p2->type;
1221 bt1 = type1->t & VT_BTYPE;
1222 bt2 = type2->t & VT_BTYPE;
1223 /* accept comparison between pointer and integer with a warning */
1224 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1225 if (op != TOK_LOR && op != TOK_LAND )
1226 warning("comparison between pointer and integer");
1227 return;
1230 /* both must be pointers or implicit function pointers */
1231 if (bt1 == VT_PTR) {
1232 type1 = pointed_type(type1);
1233 } else if (bt1 != VT_FUNC)
1234 goto invalid_operands;
1236 if (bt2 == VT_PTR) {
1237 type2 = pointed_type(type2);
1238 } else if (bt2 != VT_FUNC) {
1239 invalid_operands:
1240 error("invalid operands to binary %s", get_tok_str(op, NULL));
1242 if ((type1->t & VT_BTYPE) == VT_VOID ||
1243 (type2->t & VT_BTYPE) == VT_VOID)
1244 return;
1245 tmp_type1 = *type1;
1246 tmp_type2 = *type2;
1247 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1248 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1249 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1250 /* gcc-like error if '-' is used */
1251 if (op == '-')
1252 goto invalid_operands;
1253 else
1254 warning("comparison of distinct pointer types lacks a cast");
1258 /* generic gen_op: handles types problems */
1259 void gen_op(int op)
1261 int u, t1, t2, bt1, bt2, t;
1262 CType type1;
1264 t1 = vtop[-1].type.t;
1265 t2 = vtop[0].type.t;
1266 bt1 = t1 & VT_BTYPE;
1267 bt2 = t2 & VT_BTYPE;
1269 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1270 /* at least one operand is a pointer */
1271 /* relationnal op: must be both pointers */
1272 if (op >= TOK_ULT && op <= TOK_LOR) {
1273 check_comparison_pointer_types(vtop - 1, vtop, op);
1274 /* pointers are handled are unsigned */
1275 #ifdef TCC_TARGET_X86_64
1276 t = VT_LLONG | VT_UNSIGNED;
1277 #else
1278 t = VT_INT | VT_UNSIGNED;
1279 #endif
1280 goto std_op;
1282 /* if both pointers, then it must be the '-' op */
1283 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1284 if (op != '-')
1285 error("cannot use pointers here");
1286 check_comparison_pointer_types(vtop - 1, vtop, op);
1287 /* XXX: check that types are compatible */
1288 u = pointed_size(&vtop[-1].type);
1289 gen_opic(op);
1290 /* set to integer type */
1291 #ifdef TCC_TARGET_X86_64
1292 vtop->type.t = VT_LLONG;
1293 #else
1294 vtop->type.t = VT_INT;
1295 #endif
1296 vpushi(u);
1297 gen_op(TOK_PDIV);
1298 } else {
1299 /* exactly one pointer : must be '+' or '-'. */
1300 if (op != '-' && op != '+')
1301 error("cannot use pointers here");
1302 /* Put pointer as first operand */
1303 if (bt2 == VT_PTR) {
1304 vswap();
1305 swap(&t1, &t2);
1307 type1 = vtop[-1].type;
1308 #ifdef TCC_TARGET_X86_64
1309 vpushll(pointed_size(&vtop[-1].type));
1310 #else
1311 /* XXX: cast to int ? (long long case) */
1312 vpushi(pointed_size(&vtop[-1].type));
1313 #endif
1314 gen_op('*');
1315 #ifdef CONFIG_TCC_BCHECK
1316 /* if evaluating constant expression, no code should be
1317 generated, so no bound check */
1318 if (tcc_state->do_bounds_check && !const_wanted) {
1319 /* if bounded pointers, we generate a special code to
1320 test bounds */
1321 if (op == '-') {
1322 vpushi(0);
1323 vswap();
1324 gen_op('-');
1326 gen_bounded_ptr_add();
1327 } else
1328 #endif
1330 gen_opic(op);
1332 /* put again type if gen_opic() swaped operands */
1333 vtop->type = type1;
1335 } else if (is_float(bt1) || is_float(bt2)) {
1336 /* compute bigger type and do implicit casts */
1337 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1338 t = VT_LDOUBLE;
1339 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1340 t = VT_DOUBLE;
1341 } else {
1342 t = VT_FLOAT;
1344 /* floats can only be used for a few operations */
1345 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1346 (op < TOK_ULT || op > TOK_GT))
1347 error("invalid operands for binary operation");
1348 goto std_op;
1349 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1350 /* cast to biggest op */
1351 t = VT_LLONG;
1352 /* convert to unsigned if it does not fit in a long long */
1353 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1354 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1355 t |= VT_UNSIGNED;
1356 goto std_op;
1357 } else {
1358 /* integer operations */
1359 t = VT_INT;
1360 /* convert to unsigned if it does not fit in an integer */
1361 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1362 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1363 t |= VT_UNSIGNED;
1364 std_op:
1365 /* XXX: currently, some unsigned operations are explicit, so
1366 we modify them here */
1367 if (t & VT_UNSIGNED) {
1368 if (op == TOK_SAR)
1369 op = TOK_SHR;
1370 else if (op == '/')
1371 op = TOK_UDIV;
1372 else if (op == '%')
1373 op = TOK_UMOD;
1374 else if (op == TOK_LT)
1375 op = TOK_ULT;
1376 else if (op == TOK_GT)
1377 op = TOK_UGT;
1378 else if (op == TOK_LE)
1379 op = TOK_ULE;
1380 else if (op == TOK_GE)
1381 op = TOK_UGE;
1383 vswap();
1384 type1.t = t;
1385 gen_cast(&type1);
1386 vswap();
1387 /* special case for shifts and long long: we keep the shift as
1388 an integer */
1389 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1390 type1.t = VT_INT;
1391 gen_cast(&type1);
1392 if (is_float(t))
1393 gen_opif(op);
1394 else
1395 gen_opic(op);
1396 if (op >= TOK_ULT && op <= TOK_GT) {
1397 /* relationnal op: the result is an int */
1398 vtop->type.t = VT_INT;
1399 } else {
1400 vtop->type.t = t;
1405 #ifndef TCC_TARGET_ARM
1406 /* generic itof for unsigned long long case */
1407 void gen_cvt_itof1(int t)
1409 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1410 (VT_LLONG | VT_UNSIGNED)) {
1412 if (t == VT_FLOAT)
1413 vpush_global_sym(&func_old_type, TOK___floatundisf);
1414 #if LDOUBLE_SIZE != 8
1415 else if (t == VT_LDOUBLE)
1416 vpush_global_sym(&func_old_type, TOK___floatundixf);
1417 #endif
1418 else
1419 vpush_global_sym(&func_old_type, TOK___floatundidf);
1420 vrott(2);
1421 gfunc_call(1);
1422 vpushi(0);
1423 vtop->r = reg_fret(t);
1424 } else {
1425 gen_cvt_itof(t);
1428 #endif
1430 /* generic ftoi for unsigned long long case */
1431 void gen_cvt_ftoi1(int t)
1433 int st;
1435 if (t == (VT_LLONG | VT_UNSIGNED)) {
1436 /* not handled natively */
1437 st = vtop->type.t & VT_BTYPE;
1438 if (st == VT_FLOAT)
1439 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1440 #if LDOUBLE_SIZE != 8
1441 else if (st == VT_LDOUBLE)
1442 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1443 #endif
1444 else
1445 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1446 vrott(2);
1447 gfunc_call(1);
1448 vpushi(0);
1449 vtop->r = REG_IRET;
1450 vtop->r2 = REG_LRET;
1451 } else {
1452 gen_cvt_ftoi(t);
1456 /* force char or short cast */
1457 void force_charshort_cast(int t)
1459 int bits, dbt;
1460 dbt = t & VT_BTYPE;
1461 /* XXX: add optimization if lvalue : just change type and offset */
1462 if (dbt == VT_BYTE)
1463 bits = 8;
1464 else
1465 bits = 16;
1466 if (t & VT_UNSIGNED) {
1467 vpushi((1 << bits) - 1);
1468 gen_op('&');
1469 } else {
1470 bits = 32 - bits;
1471 vpushi(bits);
1472 gen_op(TOK_SHL);
1473 /* result must be signed or the SAR is converted to an SHL
1474 This was not the case when "t" was a signed short
1475 and the last value on the stack was an unsigned int */
1476 vtop->type.t &= ~VT_UNSIGNED;
1477 vpushi(bits);
1478 gen_op(TOK_SAR);
1482 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1483 static void gen_cast(CType *type)
1485 int sbt, dbt, sf, df, c, p;
1487 /* special delayed cast for char/short */
1488 /* XXX: in some cases (multiple cascaded casts), it may still
1489 be incorrect */
1490 if (vtop->r & VT_MUSTCAST) {
1491 vtop->r &= ~VT_MUSTCAST;
1492 force_charshort_cast(vtop->type.t);
1495 /* bitfields first get cast to ints */
1496 if (vtop->type.t & VT_BITFIELD) {
1497 gv(RC_INT);
1500 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1501 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1503 if (sbt != dbt) {
1504 sf = is_float(sbt);
1505 df = is_float(dbt);
1506 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1507 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1508 if (c) {
1509 /* constant case: we can do it now */
1510 /* XXX: in ISOC, cannot do it if error in convert */
1511 if (sbt == VT_FLOAT)
1512 vtop->c.ld = vtop->c.f;
1513 else if (sbt == VT_DOUBLE)
1514 vtop->c.ld = vtop->c.d;
1516 if (df) {
1517 if ((sbt & VT_BTYPE) == VT_LLONG) {
1518 if (sbt & VT_UNSIGNED)
1519 vtop->c.ld = vtop->c.ull;
1520 else
1521 vtop->c.ld = vtop->c.ll;
1522 } else if(!sf) {
1523 if (sbt & VT_UNSIGNED)
1524 vtop->c.ld = vtop->c.ui;
1525 else
1526 vtop->c.ld = vtop->c.i;
1529 if (dbt == VT_FLOAT)
1530 vtop->c.f = (float)vtop->c.ld;
1531 else if (dbt == VT_DOUBLE)
1532 vtop->c.d = (double)vtop->c.ld;
1533 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1534 vtop->c.ull = (unsigned long long)vtop->c.ld;
1535 } else if (sf && dbt == VT_BOOL) {
1536 vtop->c.i = (vtop->c.ld != 0);
1537 } else {
1538 if(sf)
1539 vtop->c.ll = (long long)vtop->c.ld;
1540 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1541 vtop->c.ll = vtop->c.ull;
1542 else if (sbt & VT_UNSIGNED)
1543 vtop->c.ll = vtop->c.ui;
1544 else if (sbt != VT_LLONG)
1545 vtop->c.ll = vtop->c.i;
1547 if (dbt == (VT_LLONG|VT_UNSIGNED))
1548 vtop->c.ull = vtop->c.ll;
1549 else if (dbt == VT_BOOL)
1550 vtop->c.i = (vtop->c.ll != 0);
1551 else if (dbt != VT_LLONG) {
1552 int s = 0;
1553 if ((dbt & VT_BTYPE) == VT_BYTE)
1554 s = 24;
1555 else if ((dbt & VT_BTYPE) == VT_SHORT)
1556 s = 16;
1558 if(dbt & VT_UNSIGNED)
1559 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1560 else
1561 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1564 } else if (p && dbt == VT_BOOL) {
1565 vtop->r = VT_CONST;
1566 vtop->c.i = 1;
1567 } else if (!nocode_wanted) {
1568 /* non constant case: generate code */
1569 if (sf && df) {
1570 /* convert from fp to fp */
1571 gen_cvt_ftof(dbt);
1572 } else if (df) {
1573 /* convert int to fp */
1574 gen_cvt_itof1(dbt);
1575 } else if (sf) {
1576 /* convert fp to int */
1577 if (dbt == VT_BOOL) {
1578 vpushi(0);
1579 gen_op(TOK_NE);
1580 } else {
1581 /* we handle char/short/etc... with generic code */
1582 if (dbt != (VT_INT | VT_UNSIGNED) &&
1583 dbt != (VT_LLONG | VT_UNSIGNED) &&
1584 dbt != VT_LLONG)
1585 dbt = VT_INT;
1586 gen_cvt_ftoi1(dbt);
1587 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1588 /* additional cast for char/short... */
1589 vtop->type.t = dbt;
1590 gen_cast(type);
1593 #ifndef TCC_TARGET_X86_64
1594 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1595 if ((sbt & VT_BTYPE) != VT_LLONG) {
1596 /* scalar to long long */
1597 /* machine independent conversion */
1598 gv(RC_INT);
1599 /* generate high word */
1600 if (sbt == (VT_INT | VT_UNSIGNED)) {
1601 vpushi(0);
1602 gv(RC_INT);
1603 } else {
1604 if (sbt == VT_PTR) {
1605 /* cast from pointer to int before we apply
1606 shift operation, which pointers don't support*/
1607 gen_cast(&int_type);
1609 gv_dup();
1610 vpushi(31);
1611 gen_op(TOK_SAR);
1613 /* patch second register */
1614 vtop[-1].r2 = vtop->r;
1615 vpop();
1617 #else
1618 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1619 (dbt & VT_BTYPE) == VT_PTR) {
1620 /* XXX: not sure if this is perfect... need more tests */
1621 if ((sbt & VT_BTYPE) != VT_LLONG) {
1622 int r = gv(RC_INT);
1623 if (sbt != (VT_INT | VT_UNSIGNED) &&
1624 sbt != VT_PTR && sbt != VT_FUNC) {
1625 /* x86_64 specific: movslq */
1626 o(0x6348);
1627 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
1630 #endif
1631 } else if (dbt == VT_BOOL) {
1632 /* scalar to bool */
1633 vpushi(0);
1634 gen_op(TOK_NE);
1635 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
1636 (dbt & VT_BTYPE) == VT_SHORT) {
1637 if (sbt == VT_PTR) {
1638 vtop->type.t = VT_INT;
1639 warning("nonportable conversion from pointer to char/short");
1641 force_charshort_cast(dbt);
1642 } else if ((dbt & VT_BTYPE) == VT_INT) {
1643 /* scalar to int */
1644 if (sbt == VT_LLONG) {
1645 /* from long long: just take low order word */
1646 lexpand();
1647 vpop();
1649 /* if lvalue and single word type, nothing to do because
1650 the lvalue already contains the real type size (see
1651 VT_LVAL_xxx constants) */
1654 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
1655 /* if we are casting between pointer types,
1656 we must update the VT_LVAL_xxx size */
1657 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
1658 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
1660 vtop->type = *type;
1663 /* return type size. Put alignment at 'a' */
1664 static int type_size(CType *type, int *a)
1666 Sym *s;
1667 int bt;
1669 bt = type->t & VT_BTYPE;
1670 if (bt == VT_STRUCT) {
1671 /* struct/union */
1672 s = type->ref;
1673 *a = s->r;
1674 return s->c;
1675 } else if (bt == VT_PTR) {
1676 if (type->t & VT_ARRAY) {
1677 int ts;
1679 s = type->ref;
1680 ts = type_size(&s->type, a);
1682 if (ts < 0 && s->c < 0)
1683 ts = -ts;
1685 return ts * s->c;
1686 } else {
1687 *a = PTR_SIZE;
1688 return PTR_SIZE;
1690 } else if (bt == VT_LDOUBLE) {
1691 *a = LDOUBLE_ALIGN;
1692 return LDOUBLE_SIZE;
1693 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
1694 #ifdef TCC_TARGET_I386
1695 #ifdef TCC_TARGET_PE
1696 *a = 8;
1697 #else
1698 *a = 4;
1699 #endif
1700 #elif defined(TCC_TARGET_ARM)
1701 #ifdef TCC_ARM_EABI
1702 *a = 8;
1703 #else
1704 *a = 4;
1705 #endif
1706 #else
1707 *a = 8;
1708 #endif
1709 return 8;
1710 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
1711 *a = 4;
1712 return 4;
1713 } else if (bt == VT_SHORT) {
1714 *a = 2;
1715 return 2;
1716 } else {
1717 /* char, void, function, _Bool */
1718 *a = 1;
1719 return 1;
1723 /* return the pointed type of t */
1724 static inline CType *pointed_type(CType *type)
1726 return &type->ref->type;
1729 /* modify type so that its it is a pointer to type. */
1730 static void mk_pointer(CType *type)
1732 Sym *s;
1733 s = sym_push(SYM_FIELD, type, 0, -1);
1734 type->t = VT_PTR | (type->t & ~VT_TYPE);
1735 type->ref = s;
1738 /* compare function types. OLD functions match any new functions */
1739 static int is_compatible_func(CType *type1, CType *type2)
1741 Sym *s1, *s2;
1743 s1 = type1->ref;
1744 s2 = type2->ref;
1745 if (!is_compatible_types(&s1->type, &s2->type))
1746 return 0;
1747 /* check func_call */
1748 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
1749 return 0;
1750 /* XXX: not complete */
1751 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
1752 return 1;
1753 if (s1->c != s2->c)
1754 return 0;
1755 while (s1 != NULL) {
1756 if (s2 == NULL)
1757 return 0;
1758 if (!is_compatible_parameter_types(&s1->type, &s2->type))
1759 return 0;
1760 s1 = s1->next;
1761 s2 = s2->next;
1763 if (s2)
1764 return 0;
1765 return 1;
1768 /* return true if type1 and type2 are the same. If unqualified is
1769 true, qualifiers on the types are ignored.
1771 - enums are not checked as gcc __builtin_types_compatible_p ()
1773 static int compare_types(CType *type1, CType *type2, int unqualified)
1775 int bt1, t1, t2;
1777 t1 = type1->t & VT_TYPE;
1778 t2 = type2->t & VT_TYPE;
1779 if (unqualified) {
1780 /* strip qualifiers before comparing */
1781 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
1782 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
1784 /* XXX: bitfields ? */
1785 if (t1 != t2)
1786 return 0;
1787 /* test more complicated cases */
1788 bt1 = t1 & VT_BTYPE;
1789 if (bt1 == VT_PTR) {
1790 type1 = pointed_type(type1);
1791 type2 = pointed_type(type2);
1792 return is_compatible_types(type1, type2);
1793 } else if (bt1 == VT_STRUCT) {
1794 return (type1->ref == type2->ref);
1795 } else if (bt1 == VT_FUNC) {
1796 return is_compatible_func(type1, type2);
1797 } else {
1798 return 1;
1802 /* return true if type1 and type2 are exactly the same (including
1803 qualifiers).
1805 static int is_compatible_types(CType *type1, CType *type2)
1807 return compare_types(type1,type2,0);
1810 /* return true if type1 and type2 are the same (ignoring qualifiers).
1812 static int is_compatible_parameter_types(CType *type1, CType *type2)
1814 return compare_types(type1,type2,1);
1817 /* print a type. If 'varstr' is not NULL, then the variable is also
1818 printed in the type */
1819 /* XXX: union */
1820 /* XXX: add array and function pointers */
1821 void type_to_str(char *buf, int buf_size,
1822 CType *type, const char *varstr)
1824 int bt, v, t;
1825 Sym *s, *sa;
1826 char buf1[256];
1827 const char *tstr;
1829 t = type->t & VT_TYPE;
1830 bt = t & VT_BTYPE;
1831 buf[0] = '\0';
1832 if (t & VT_CONSTANT)
1833 pstrcat(buf, buf_size, "const ");
1834 if (t & VT_VOLATILE)
1835 pstrcat(buf, buf_size, "volatile ");
1836 if (t & VT_UNSIGNED)
1837 pstrcat(buf, buf_size, "unsigned ");
1838 switch(bt) {
1839 case VT_VOID:
1840 tstr = "void";
1841 goto add_tstr;
1842 case VT_BOOL:
1843 tstr = "_Bool";
1844 goto add_tstr;
1845 case VT_BYTE:
1846 tstr = "char";
1847 goto add_tstr;
1848 case VT_SHORT:
1849 tstr = "short";
1850 goto add_tstr;
1851 case VT_INT:
1852 tstr = "int";
1853 goto add_tstr;
1854 case VT_LONG:
1855 tstr = "long";
1856 goto add_tstr;
1857 case VT_LLONG:
1858 tstr = "long long";
1859 goto add_tstr;
1860 case VT_FLOAT:
1861 tstr = "float";
1862 goto add_tstr;
1863 case VT_DOUBLE:
1864 tstr = "double";
1865 goto add_tstr;
1866 case VT_LDOUBLE:
1867 tstr = "long double";
1868 add_tstr:
1869 pstrcat(buf, buf_size, tstr);
1870 break;
1871 case VT_ENUM:
1872 case VT_STRUCT:
1873 if (bt == VT_STRUCT)
1874 tstr = "struct ";
1875 else
1876 tstr = "enum ";
1877 pstrcat(buf, buf_size, tstr);
1878 v = type->ref->v & ~SYM_STRUCT;
1879 if (v >= SYM_FIRST_ANOM)
1880 pstrcat(buf, buf_size, "<anonymous>");
1881 else
1882 pstrcat(buf, buf_size, get_tok_str(v, NULL));
1883 break;
1884 case VT_FUNC:
1885 s = type->ref;
1886 type_to_str(buf, buf_size, &s->type, varstr);
1887 pstrcat(buf, buf_size, "(");
1888 sa = s->next;
1889 while (sa != NULL) {
1890 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
1891 pstrcat(buf, buf_size, buf1);
1892 sa = sa->next;
1893 if (sa)
1894 pstrcat(buf, buf_size, ", ");
1896 pstrcat(buf, buf_size, ")");
1897 goto no_var;
1898 case VT_PTR:
1899 s = type->ref;
1900 pstrcpy(buf1, sizeof(buf1), "*");
1901 if (varstr)
1902 pstrcat(buf1, sizeof(buf1), varstr);
1903 type_to_str(buf, buf_size, &s->type, buf1);
1904 goto no_var;
1906 if (varstr) {
1907 pstrcat(buf, buf_size, " ");
1908 pstrcat(buf, buf_size, varstr);
1910 no_var: ;
1913 /* verify type compatibility to store vtop in 'dt' type, and generate
1914 casts if needed. */
1915 static void gen_assign_cast(CType *dt)
1917 CType *st, *type1, *type2, tmp_type1, tmp_type2;
1918 char buf1[256], buf2[256];
1919 int dbt, sbt;
1921 st = &vtop->type; /* source type */
1922 dbt = dt->t & VT_BTYPE;
1923 sbt = st->t & VT_BTYPE;
1924 if (dt->t & VT_CONSTANT)
1925 warning("assignment of read-only location");
1926 switch(dbt) {
1927 case VT_PTR:
1928 /* special cases for pointers */
1929 /* '0' can also be a pointer */
1930 if (is_null_pointer(vtop))
1931 goto type_ok;
1932 /* accept implicit pointer to integer cast with warning */
1933 if (is_integer_btype(sbt)) {
1934 warning("assignment makes pointer from integer without a cast");
1935 goto type_ok;
1937 type1 = pointed_type(dt);
1938 /* a function is implicitely a function pointer */
1939 if (sbt == VT_FUNC) {
1940 if ((type1->t & VT_BTYPE) != VT_VOID &&
1941 !is_compatible_types(pointed_type(dt), st))
1942 warning("assignment from incompatible pointer type");
1943 goto type_ok;
1945 if (sbt != VT_PTR)
1946 goto error;
1947 type2 = pointed_type(st);
1948 if ((type1->t & VT_BTYPE) == VT_VOID ||
1949 (type2->t & VT_BTYPE) == VT_VOID) {
1950 /* void * can match anything */
1951 } else {
1952 /* exact type match, except for unsigned */
1953 tmp_type1 = *type1;
1954 tmp_type2 = *type2;
1955 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1956 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1957 if (!is_compatible_types(&tmp_type1, &tmp_type2))
1958 warning("assignment from incompatible pointer type");
1960 /* check const and volatile */
1961 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
1962 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
1963 warning("assignment discards qualifiers from pointer target type");
1964 break;
1965 case VT_BYTE:
1966 case VT_SHORT:
1967 case VT_INT:
1968 case VT_LLONG:
1969 if (sbt == VT_PTR || sbt == VT_FUNC) {
1970 warning("assignment makes integer from pointer without a cast");
1972 /* XXX: more tests */
1973 break;
1974 case VT_STRUCT:
1975 tmp_type1 = *dt;
1976 tmp_type2 = *st;
1977 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
1978 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
1979 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1980 error:
1981 type_to_str(buf1, sizeof(buf1), st, NULL);
1982 type_to_str(buf2, sizeof(buf2), dt, NULL);
1983 error("cannot cast '%s' to '%s'", buf1, buf2);
1985 break;
1987 type_ok:
1988 gen_cast(dt);
1991 /* store vtop in lvalue pushed on stack */
1992 void vstore(void)
1994 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
1996 ft = vtop[-1].type.t;
1997 sbt = vtop->type.t & VT_BTYPE;
1998 dbt = ft & VT_BTYPE;
1999 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2000 (sbt == VT_INT && dbt == VT_SHORT)) {
2001 /* optimize char/short casts */
2002 delayed_cast = VT_MUSTCAST;
2003 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2004 /* XXX: factorize */
2005 if (ft & VT_CONSTANT)
2006 warning("assignment of read-only location");
2007 } else {
2008 delayed_cast = 0;
2009 if (!(ft & VT_BITFIELD))
2010 gen_assign_cast(&vtop[-1].type);
2013 if (sbt == VT_STRUCT) {
2014 /* if structure, only generate pointer */
2015 /* structure assignment : generate memcpy */
2016 /* XXX: optimize if small size */
2017 if (!nocode_wanted) {
2018 size = type_size(&vtop->type, &align);
2020 #ifdef TCC_ARM_EABI
2021 if(!(align & 7))
2022 vpush_global_sym(&func_old_type, TOK_memcpy8);
2023 else if(!(align & 3))
2024 vpush_global_sym(&func_old_type, TOK_memcpy4);
2025 else
2026 #endif
2027 vpush_global_sym(&func_old_type, TOK_memcpy);
2029 /* destination */
2030 vpushv(vtop - 2);
2031 vtop->type.t = VT_PTR;
2032 gaddrof();
2033 /* source */
2034 vpushv(vtop - 2);
2035 vtop->type.t = VT_PTR;
2036 gaddrof();
2037 /* type size */
2038 vpushi(size);
2039 gfunc_call(3);
2041 vswap();
2042 vpop();
2043 } else {
2044 vswap();
2045 vpop();
2047 /* leave source on stack */
2048 } else if (ft & VT_BITFIELD) {
2049 /* bitfield store handling */
2050 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2051 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2052 /* remove bit field info to avoid loops */
2053 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2055 /* duplicate source into other register */
2056 gv_dup();
2057 vswap();
2058 vrott(3);
2060 if((ft & VT_BTYPE) == VT_BOOL) {
2061 gen_cast(&vtop[-1].type);
2062 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2065 /* duplicate destination */
2066 vdup();
2067 vtop[-1] = vtop[-2];
2069 /* mask and shift source */
2070 if((ft & VT_BTYPE) != VT_BOOL) {
2071 if((ft & VT_BTYPE) == VT_LLONG) {
2072 vpushll((1ULL << bit_size) - 1ULL);
2073 } else {
2074 vpushi((1 << bit_size) - 1);
2076 gen_op('&');
2078 vpushi(bit_pos);
2079 gen_op(TOK_SHL);
2080 /* load destination, mask and or with source */
2081 vswap();
2082 if((ft & VT_BTYPE) == VT_LLONG) {
2083 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2084 } else {
2085 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2087 gen_op('&');
2088 gen_op('|');
2089 /* store result */
2090 vstore();
2092 /* pop off shifted source from "duplicate source..." above */
2093 vpop();
2095 } else {
2096 #ifdef CONFIG_TCC_BCHECK
2097 /* bound check case */
2098 if (vtop[-1].r & VT_MUSTBOUND) {
2099 vswap();
2100 gbound();
2101 vswap();
2103 #endif
2104 if (!nocode_wanted) {
2105 rc = RC_INT;
2106 if (is_float(ft)) {
2107 rc = RC_FLOAT;
2108 #ifdef TCC_TARGET_X86_64
2109 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2110 rc = RC_ST0;
2112 #endif
2114 r = gv(rc); /* generate value */
2115 /* if lvalue was saved on stack, must read it */
2116 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2117 SValue sv;
2118 t = get_reg(RC_INT);
2119 #ifdef TCC_TARGET_X86_64
2120 sv.type.t = VT_PTR;
2121 #else
2122 sv.type.t = VT_INT;
2123 #endif
2124 sv.r = VT_LOCAL | VT_LVAL;
2125 sv.c.ul = vtop[-1].c.ul;
2126 load(t, &sv);
2127 vtop[-1].r = t | VT_LVAL;
2129 store(r, vtop - 1);
2130 #ifndef TCC_TARGET_X86_64
2131 /* two word case handling : store second register at word + 4 */
2132 if ((ft & VT_BTYPE) == VT_LLONG) {
2133 vswap();
2134 /* convert to int to increment easily */
2135 vtop->type.t = VT_INT;
2136 gaddrof();
2137 vpushi(4);
2138 gen_op('+');
2139 vtop->r |= VT_LVAL;
2140 vswap();
2141 /* XXX: it works because r2 is spilled last ! */
2142 store(vtop->r2, vtop - 1);
2144 #endif
2146 vswap();
2147 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2148 vtop->r |= delayed_cast;
2152 /* post defines POST/PRE add. c is the token ++ or -- */
2153 void inc(int post, int c)
2155 test_lvalue();
2156 vdup(); /* save lvalue */
2157 if (post) {
2158 gv_dup(); /* duplicate value */
2159 vrotb(3);
2160 vrotb(3);
2162 /* add constant */
2163 vpushi(c - TOK_MID);
2164 gen_op('+');
2165 vstore(); /* store value */
2166 if (post)
2167 vpop(); /* if post op, return saved value */
2170 /* Parse GNUC __attribute__ extension. Currently, the following
2171 extensions are recognized:
2172 - aligned(n) : set data/function alignment.
2173 - packed : force data alignment to 1
2174 - section(x) : generate data/code in this section.
2175 - unused : currently ignored, but may be used someday.
2176 - regparm(n) : pass function parameters in registers (i386 only)
2178 static void parse_attribute(AttributeDef *ad)
2180 int t, n;
2182 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2183 next();
2184 skip('(');
2185 skip('(');
2186 while (tok != ')') {
2187 if (tok < TOK_IDENT)
2188 expect("attribute name");
2189 t = tok;
2190 next();
2191 switch(t) {
2192 case TOK_SECTION1:
2193 case TOK_SECTION2:
2194 skip('(');
2195 if (tok != TOK_STR)
2196 expect("section name");
2197 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2198 next();
2199 skip(')');
2200 break;
2201 case TOK_ALIGNED1:
2202 case TOK_ALIGNED2:
2203 if (tok == '(') {
2204 next();
2205 n = expr_const();
2206 if (n <= 0 || (n & (n - 1)) != 0)
2207 error("alignment must be a positive power of two");
2208 skip(')');
2209 } else {
2210 n = MAX_ALIGN;
2212 ad->aligned = n;
2213 break;
2214 case TOK_PACKED1:
2215 case TOK_PACKED2:
2216 ad->packed = 1;
2217 break;
2218 case TOK_UNUSED1:
2219 case TOK_UNUSED2:
2220 /* currently, no need to handle it because tcc does not
2221 track unused objects */
2222 break;
2223 case TOK_NORETURN1:
2224 case TOK_NORETURN2:
2225 /* currently, no need to handle it because tcc does not
2226 track unused objects */
2227 break;
2228 case TOK_CDECL1:
2229 case TOK_CDECL2:
2230 case TOK_CDECL3:
2231 FUNC_CALL(ad->func_attr) = FUNC_CDECL;
2232 break;
2233 case TOK_STDCALL1:
2234 case TOK_STDCALL2:
2235 case TOK_STDCALL3:
2236 FUNC_CALL(ad->func_attr) = FUNC_STDCALL;
2237 break;
2238 #ifdef TCC_TARGET_I386
2239 case TOK_REGPARM1:
2240 case TOK_REGPARM2:
2241 skip('(');
2242 n = expr_const();
2243 if (n > 3)
2244 n = 3;
2245 else if (n < 0)
2246 n = 0;
2247 if (n > 0)
2248 FUNC_CALL(ad->func_attr) = FUNC_FASTCALL1 + n - 1;
2249 skip(')');
2250 break;
2251 case TOK_FASTCALL1:
2252 case TOK_FASTCALL2:
2253 case TOK_FASTCALL3:
2254 FUNC_CALL(ad->func_attr) = FUNC_FASTCALLW;
2255 break;
2256 #endif
2257 case TOK_DLLEXPORT:
2258 FUNC_EXPORT(ad->func_attr) = 1;
2259 break;
2260 default:
2261 if (tcc_state->warn_unsupported)
2262 warning("'%s' attribute ignored", get_tok_str(t, NULL));
2263 /* skip parameters */
2264 if (tok == '(') {
2265 int parenthesis = 0;
2266 do {
2267 if (tok == '(')
2268 parenthesis++;
2269 else if (tok == ')')
2270 parenthesis--;
2271 next();
2272 } while (parenthesis && tok != -1);
2274 break;
2276 if (tok != ',')
2277 break;
2278 next();
2280 skip(')');
2281 skip(')');
2285 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2286 static void struct_decl(CType *type, int u)
2288 int a, v, size, align, maxalign, c, offset;
2289 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2290 Sym *s, *ss, *ass, **ps;
2291 AttributeDef ad;
2292 CType type1, btype;
2294 a = tok; /* save decl type */
2295 next();
2296 if (tok != '{') {
2297 v = tok;
2298 next();
2299 /* struct already defined ? return it */
2300 if (v < TOK_IDENT)
2301 expect("struct/union/enum name");
2302 s = struct_find(v);
2303 if (s) {
2304 if (s->type.t != a)
2305 error("invalid type");
2306 goto do_decl;
2308 } else {
2309 v = anon_sym++;
2311 type1.t = a;
2312 /* we put an undefined size for struct/union */
2313 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2314 s->r = 0; /* default alignment is zero as gcc */
2315 /* put struct/union/enum name in type */
2316 do_decl:
2317 type->t = u;
2318 type->ref = s;
2320 if (tok == '{') {
2321 next();
2322 if (s->c != -1)
2323 error("struct/union/enum already defined");
2324 /* cannot be empty */
2325 c = 0;
2326 /* non empty enums are not allowed */
2327 if (a == TOK_ENUM) {
2328 for(;;) {
2329 v = tok;
2330 if (v < TOK_UIDENT)
2331 expect("identifier");
2332 next();
2333 if (tok == '=') {
2334 next();
2335 c = expr_const();
2337 /* enum symbols have static storage */
2338 ss = sym_push(v, &int_type, VT_CONST, c);
2339 ss->type.t |= VT_STATIC;
2340 if (tok != ',')
2341 break;
2342 next();
2343 c++;
2344 /* NOTE: we accept a trailing comma */
2345 if (tok == '}')
2346 break;
2348 skip('}');
2349 } else {
2350 maxalign = 1;
2351 ps = &s->next;
2352 prevbt = VT_INT;
2353 bit_pos = 0;
2354 offset = 0;
2355 while (tok != '}') {
2356 parse_btype(&btype, &ad);
2357 while (1) {
2358 bit_size = -1;
2359 v = 0;
2360 type1 = btype;
2361 if (tok != ':') {
2362 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2363 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2364 expect("identifier");
2365 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2366 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2367 error("invalid type for '%s'",
2368 get_tok_str(v, NULL));
2370 if (tok == ':') {
2371 next();
2372 bit_size = expr_const();
2373 /* XXX: handle v = 0 case for messages */
2374 if (bit_size < 0)
2375 error("negative width in bit-field '%s'",
2376 get_tok_str(v, NULL));
2377 if (v && bit_size == 0)
2378 error("zero width for bit-field '%s'",
2379 get_tok_str(v, NULL));
2381 size = type_size(&type1, &align);
2382 if (ad.aligned) {
2383 if (align < ad.aligned)
2384 align = ad.aligned;
2385 } else if (ad.packed) {
2386 align = 1;
2387 } else if (*tcc_state->pack_stack_ptr) {
2388 if (align > *tcc_state->pack_stack_ptr)
2389 align = *tcc_state->pack_stack_ptr;
2391 lbit_pos = 0;
2392 if (bit_size >= 0) {
2393 bt = type1.t & VT_BTYPE;
2394 if (bt != VT_INT &&
2395 bt != VT_BYTE &&
2396 bt != VT_SHORT &&
2397 bt != VT_BOOL &&
2398 bt != VT_ENUM &&
2399 bt != VT_LLONG)
2400 error("bitfields must have scalar type");
2401 bsize = size * 8;
2402 if (bit_size > bsize) {
2403 error("width of '%s' exceeds its type",
2404 get_tok_str(v, NULL));
2405 } else if (bit_size == bsize) {
2406 /* no need for bit fields */
2407 bit_pos = 0;
2408 } else if (bit_size == 0) {
2409 /* XXX: what to do if only padding in a
2410 structure ? */
2411 /* zero size: means to pad */
2412 bit_pos = 0;
2413 } else {
2414 /* we do not have enough room ?
2415 did the type change?
2416 is it a union? */
2417 if ((bit_pos + bit_size) > bsize ||
2418 bt != prevbt || a == TOK_UNION)
2419 bit_pos = 0;
2420 lbit_pos = bit_pos;
2421 /* XXX: handle LSB first */
2422 type1.t |= VT_BITFIELD |
2423 (bit_pos << VT_STRUCT_SHIFT) |
2424 (bit_size << (VT_STRUCT_SHIFT + 6));
2425 bit_pos += bit_size;
2427 prevbt = bt;
2428 } else {
2429 bit_pos = 0;
2431 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2432 /* add new memory data only if starting
2433 bit field */
2434 if (lbit_pos == 0) {
2435 if (a == TOK_STRUCT) {
2436 c = (c + align - 1) & -align;
2437 offset = c;
2438 if (size > 0)
2439 c += size;
2440 } else {
2441 offset = 0;
2442 if (size > c)
2443 c = size;
2445 if (align > maxalign)
2446 maxalign = align;
2448 #if 0
2449 printf("add field %s offset=%d",
2450 get_tok_str(v, NULL), offset);
2451 if (type1.t & VT_BITFIELD) {
2452 printf(" pos=%d size=%d",
2453 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2454 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2456 printf("\n");
2457 #endif
2459 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2460 ass = type1.ref;
2461 while ((ass = ass->next) != NULL) {
2462 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2463 *ps = ss;
2464 ps = &ss->next;
2466 } else if (v) {
2467 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2468 *ps = ss;
2469 ps = &ss->next;
2471 if (tok == ';' || tok == TOK_EOF)
2472 break;
2473 skip(',');
2475 skip(';');
2477 skip('}');
2478 /* store size and alignment */
2479 s->c = (c + maxalign - 1) & -maxalign;
2480 s->r = maxalign;
2485 /* return 0 if no type declaration. otherwise, return the basic type
2486 and skip it.
2488 static int parse_btype(CType *type, AttributeDef *ad)
2490 int t, u, type_found, typespec_found, typedef_found;
2491 Sym *s;
2492 CType type1;
2494 memset(ad, 0, sizeof(AttributeDef));
2495 type_found = 0;
2496 typespec_found = 0;
2497 typedef_found = 0;
2498 t = 0;
2499 while(1) {
2500 switch(tok) {
2501 case TOK_EXTENSION:
2502 /* currently, we really ignore extension */
2503 next();
2504 continue;
2506 /* basic types */
2507 case TOK_CHAR:
2508 u = VT_BYTE;
2509 basic_type:
2510 next();
2511 basic_type1:
2512 if ((t & VT_BTYPE) != 0)
2513 error("too many basic types");
2514 t |= u;
2515 typespec_found = 1;
2516 break;
2517 case TOK_VOID:
2518 u = VT_VOID;
2519 goto basic_type;
2520 case TOK_SHORT:
2521 u = VT_SHORT;
2522 goto basic_type;
2523 case TOK_INT:
2524 next();
2525 typespec_found = 1;
2526 break;
2527 case TOK_LONG:
2528 next();
2529 if ((t & VT_BTYPE) == VT_DOUBLE) {
2530 #ifndef TCC_TARGET_PE
2531 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2532 #endif
2533 } else if ((t & VT_BTYPE) == VT_LONG) {
2534 t = (t & ~VT_BTYPE) | VT_LLONG;
2535 } else {
2536 u = VT_LONG;
2537 goto basic_type1;
2539 break;
2540 case TOK_BOOL:
2541 u = VT_BOOL;
2542 goto basic_type;
2543 case TOK_FLOAT:
2544 u = VT_FLOAT;
2545 goto basic_type;
2546 case TOK_DOUBLE:
2547 next();
2548 if ((t & VT_BTYPE) == VT_LONG) {
2549 #ifdef TCC_TARGET_PE
2550 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2551 #else
2552 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2553 #endif
2554 } else {
2555 u = VT_DOUBLE;
2556 goto basic_type1;
2558 break;
2559 case TOK_ENUM:
2560 struct_decl(&type1, VT_ENUM);
2561 basic_type2:
2562 u = type1.t;
2563 type->ref = type1.ref;
2564 goto basic_type1;
2565 case TOK_STRUCT:
2566 case TOK_UNION:
2567 struct_decl(&type1, VT_STRUCT);
2568 goto basic_type2;
2570 /* type modifiers */
2571 case TOK_CONST1:
2572 case TOK_CONST2:
2573 case TOK_CONST3:
2574 t |= VT_CONSTANT;
2575 next();
2576 break;
2577 case TOK_VOLATILE1:
2578 case TOK_VOLATILE2:
2579 case TOK_VOLATILE3:
2580 t |= VT_VOLATILE;
2581 next();
2582 break;
2583 case TOK_SIGNED1:
2584 case TOK_SIGNED2:
2585 case TOK_SIGNED3:
2586 typespec_found = 1;
2587 t |= VT_SIGNED;
2588 next();
2589 break;
2590 case TOK_REGISTER:
2591 case TOK_AUTO:
2592 case TOK_RESTRICT1:
2593 case TOK_RESTRICT2:
2594 case TOK_RESTRICT3:
2595 next();
2596 break;
2597 case TOK_UNSIGNED:
2598 t |= VT_UNSIGNED;
2599 next();
2600 typespec_found = 1;
2601 break;
2603 /* storage */
2604 case TOK_EXTERN:
2605 t |= VT_EXTERN;
2606 next();
2607 break;
2608 case TOK_STATIC:
2609 t |= VT_STATIC;
2610 next();
2611 break;
2612 case TOK_TYPEDEF:
2613 t |= VT_TYPEDEF;
2614 next();
2615 break;
2616 case TOK_INLINE1:
2617 case TOK_INLINE2:
2618 case TOK_INLINE3:
2619 t |= VT_INLINE;
2620 next();
2621 break;
2623 /* GNUC attribute */
2624 case TOK_ATTRIBUTE1:
2625 case TOK_ATTRIBUTE2:
2626 parse_attribute(ad);
2627 break;
2628 /* GNUC typeof */
2629 case TOK_TYPEOF1:
2630 case TOK_TYPEOF2:
2631 case TOK_TYPEOF3:
2632 next();
2633 parse_expr_type(&type1);
2634 goto basic_type2;
2635 default:
2636 if (typespec_found || typedef_found)
2637 goto the_end;
2638 s = sym_find(tok);
2639 if (!s || !(s->type.t & VT_TYPEDEF))
2640 goto the_end;
2641 typedef_found = 1;
2642 t |= (s->type.t & ~VT_TYPEDEF);
2643 type->ref = s->type.ref;
2644 next();
2645 typespec_found = 1;
2646 break;
2648 type_found = 1;
2650 the_end:
2651 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
2652 error("signed and unsigned modifier");
2653 if (tcc_state->char_is_unsigned) {
2654 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
2655 t |= VT_UNSIGNED;
2657 t &= ~VT_SIGNED;
2659 /* long is never used as type */
2660 if ((t & VT_BTYPE) == VT_LONG)
2661 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
2662 t = (t & ~VT_BTYPE) | VT_INT;
2663 #else
2664 t = (t & ~VT_BTYPE) | VT_LLONG;
2665 #endif
2666 type->t = t;
2667 return type_found;
2670 /* convert a function parameter type (array to pointer and function to
2671 function pointer) */
2672 static inline void convert_parameter_type(CType *pt)
2674 /* remove const and volatile qualifiers (XXX: const could be used
2675 to indicate a const function parameter */
2676 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
2677 /* array must be transformed to pointer according to ANSI C */
2678 pt->t &= ~VT_ARRAY;
2679 if ((pt->t & VT_BTYPE) == VT_FUNC) {
2680 mk_pointer(pt);
2684 static void post_type(CType *type, AttributeDef *ad)
2686 int n, l, t1, arg_size, align;
2687 Sym **plast, *s, *first;
2688 AttributeDef ad1;
2689 CType pt;
2691 if (tok == '(') {
2692 /* function declaration */
2693 next();
2694 l = 0;
2695 first = NULL;
2696 plast = &first;
2697 arg_size = 0;
2698 if (tok != ')') {
2699 for(;;) {
2700 /* read param name and compute offset */
2701 if (l != FUNC_OLD) {
2702 if (!parse_btype(&pt, &ad1)) {
2703 if (l) {
2704 error("invalid type");
2705 } else {
2706 l = FUNC_OLD;
2707 goto old_proto;
2710 l = FUNC_NEW;
2711 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
2712 break;
2713 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
2714 if ((pt.t & VT_BTYPE) == VT_VOID)
2715 error("parameter declared as void");
2716 arg_size += (type_size(&pt, &align) + 3) & ~3;
2717 } else {
2718 old_proto:
2719 n = tok;
2720 if (n < TOK_UIDENT)
2721 expect("identifier");
2722 pt.t = VT_INT;
2723 next();
2725 convert_parameter_type(&pt);
2726 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
2727 *plast = s;
2728 plast = &s->next;
2729 if (tok == ')')
2730 break;
2731 skip(',');
2732 if (l == FUNC_NEW && tok == TOK_DOTS) {
2733 l = FUNC_ELLIPSIS;
2734 next();
2735 break;
2739 /* if no parameters, then old type prototype */
2740 if (l == 0)
2741 l = FUNC_OLD;
2742 skip(')');
2743 t1 = type->t & VT_STORAGE;
2744 /* NOTE: const is ignored in returned type as it has a special
2745 meaning in gcc / C++ */
2746 type->t &= ~(VT_STORAGE | VT_CONSTANT);
2747 post_type(type, ad);
2748 /* we push a anonymous symbol which will contain the function prototype */
2749 FUNC_ARGS(ad->func_attr) = arg_size;
2750 s = sym_push(SYM_FIELD, type, ad->func_attr, l);
2751 s->next = first;
2752 type->t = t1 | VT_FUNC;
2753 type->ref = s;
2754 } else if (tok == '[') {
2755 /* array definition */
2756 next();
2757 if (tok == TOK_RESTRICT1)
2758 next();
2759 n = -1;
2760 if (tok != ']') {
2761 n = expr_const();
2762 if (n < 0)
2763 error("invalid array size");
2765 skip(']');
2766 /* parse next post type */
2767 t1 = type->t & VT_STORAGE;
2768 type->t &= ~VT_STORAGE;
2769 post_type(type, ad);
2771 /* we push a anonymous symbol which will contain the array
2772 element type */
2773 s = sym_push(SYM_FIELD, type, 0, n);
2774 type->t = t1 | VT_ARRAY | VT_PTR;
2775 type->ref = s;
2779 /* Parse a type declaration (except basic type), and return the type
2780 in 'type'. 'td' is a bitmask indicating which kind of type decl is
2781 expected. 'type' should contain the basic type. 'ad' is the
2782 attribute definition of the basic type. It can be modified by
2783 type_decl().
2785 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
2787 Sym *s;
2788 CType type1, *type2;
2789 int qualifiers;
2791 while (tok == '*') {
2792 qualifiers = 0;
2793 redo:
2794 next();
2795 switch(tok) {
2796 case TOK_CONST1:
2797 case TOK_CONST2:
2798 case TOK_CONST3:
2799 qualifiers |= VT_CONSTANT;
2800 goto redo;
2801 case TOK_VOLATILE1:
2802 case TOK_VOLATILE2:
2803 case TOK_VOLATILE3:
2804 qualifiers |= VT_VOLATILE;
2805 goto redo;
2806 case TOK_RESTRICT1:
2807 case TOK_RESTRICT2:
2808 case TOK_RESTRICT3:
2809 goto redo;
2811 mk_pointer(type);
2812 type->t |= qualifiers;
2815 /* XXX: clarify attribute handling */
2816 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
2817 parse_attribute(ad);
2819 /* recursive type */
2820 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
2821 type1.t = 0; /* XXX: same as int */
2822 if (tok == '(') {
2823 next();
2824 /* XXX: this is not correct to modify 'ad' at this point, but
2825 the syntax is not clear */
2826 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
2827 parse_attribute(ad);
2828 type_decl(&type1, ad, v, td);
2829 skip(')');
2830 } else {
2831 /* type identifier */
2832 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
2833 *v = tok;
2834 next();
2835 } else {
2836 if (!(td & TYPE_ABSTRACT))
2837 expect("identifier");
2838 *v = 0;
2841 post_type(type, ad);
2842 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
2843 parse_attribute(ad);
2844 if (!type1.t)
2845 return;
2846 /* append type at the end of type1 */
2847 type2 = &type1;
2848 for(;;) {
2849 s = type2->ref;
2850 type2 = &s->type;
2851 if (!type2->t) {
2852 *type2 = *type;
2853 break;
2856 *type = type1;
2859 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
2860 static int lvalue_type(int t)
2862 int bt, r;
2863 r = VT_LVAL;
2864 bt = t & VT_BTYPE;
2865 if (bt == VT_BYTE || bt == VT_BOOL)
2866 r |= VT_LVAL_BYTE;
2867 else if (bt == VT_SHORT)
2868 r |= VT_LVAL_SHORT;
2869 else
2870 return r;
2871 if (t & VT_UNSIGNED)
2872 r |= VT_LVAL_UNSIGNED;
2873 return r;
2876 /* indirection with full error checking and bound check */
2877 static void indir(void)
2879 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
2880 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
2881 return;
2882 expect("pointer");
2884 if ((vtop->r & VT_LVAL) && !nocode_wanted)
2885 gv(RC_INT);
2886 vtop->type = *pointed_type(&vtop->type);
2887 /* Arrays and functions are never lvalues */
2888 if (!(vtop->type.t & VT_ARRAY)
2889 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
2890 vtop->r |= lvalue_type(vtop->type.t);
2891 /* if bound checking, the referenced pointer must be checked */
2892 if (tcc_state->do_bounds_check)
2893 vtop->r |= VT_MUSTBOUND;
2897 /* pass a parameter to a function and do type checking and casting */
2898 static void gfunc_param_typed(Sym *func, Sym *arg)
2900 int func_type;
2901 CType type;
2903 func_type = func->c;
2904 if (func_type == FUNC_OLD ||
2905 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
2906 /* default casting : only need to convert float to double */
2907 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
2908 type.t = VT_DOUBLE;
2909 gen_cast(&type);
2911 } else if (arg == NULL) {
2912 error("too many arguments to function");
2913 } else {
2914 type = arg->type;
2915 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
2916 gen_assign_cast(&type);
2920 /* parse an expression of the form '(type)' or '(expr)' and return its
2921 type */
2922 static void parse_expr_type(CType *type)
2924 int n;
2925 AttributeDef ad;
2927 skip('(');
2928 if (parse_btype(type, &ad)) {
2929 type_decl(type, &ad, &n, TYPE_ABSTRACT);
2930 } else {
2931 expr_type(type);
2933 skip(')');
2936 static void parse_type(CType *type)
2938 AttributeDef ad;
2939 int n;
2941 if (!parse_btype(type, &ad)) {
2942 expect("type");
2944 type_decl(type, &ad, &n, TYPE_ABSTRACT);
2947 static void vpush_tokc(int t)
2949 CType type;
2950 type.t = t;
2951 vsetc(&type, VT_CONST, &tokc);
2954 static void unary(void)
2956 int n, t, align, size, r;
2957 CType type;
2958 Sym *s;
2959 AttributeDef ad;
2961 /* XXX: GCC 2.95.3 does not generate a table although it should be
2962 better here */
2963 tok_next:
2964 switch(tok) {
2965 case TOK_EXTENSION:
2966 next();
2967 goto tok_next;
2968 case TOK_CINT:
2969 case TOK_CCHAR:
2970 case TOK_LCHAR:
2971 vpushi(tokc.i);
2972 next();
2973 break;
2974 case TOK_CUINT:
2975 vpush_tokc(VT_INT | VT_UNSIGNED);
2976 next();
2977 break;
2978 case TOK_CLLONG:
2979 vpush_tokc(VT_LLONG);
2980 next();
2981 break;
2982 case TOK_CULLONG:
2983 vpush_tokc(VT_LLONG | VT_UNSIGNED);
2984 next();
2985 break;
2986 case TOK_CFLOAT:
2987 vpush_tokc(VT_FLOAT);
2988 next();
2989 break;
2990 case TOK_CDOUBLE:
2991 vpush_tokc(VT_DOUBLE);
2992 next();
2993 break;
2994 case TOK_CLDOUBLE:
2995 vpush_tokc(VT_LDOUBLE);
2996 next();
2997 break;
2998 case TOK___FUNCTION__:
2999 if (!gnu_ext)
3000 goto tok_identifier;
3001 /* fall thru */
3002 case TOK___FUNC__:
3004 void *ptr;
3005 int len;
3006 /* special function name identifier */
3007 len = strlen(funcname) + 1;
3008 /* generate char[len] type */
3009 type.t = VT_BYTE;
3010 mk_pointer(&type);
3011 type.t |= VT_ARRAY;
3012 type.ref->c = len;
3013 vpush_ref(&type, data_section, data_section->data_offset, len);
3014 ptr = section_ptr_add(data_section, len);
3015 memcpy(ptr, funcname, len);
3016 next();
3018 break;
3019 case TOK_LSTR:
3020 #ifdef TCC_TARGET_PE
3021 t = VT_SHORT | VT_UNSIGNED;
3022 #else
3023 t = VT_INT;
3024 #endif
3025 goto str_init;
3026 case TOK_STR:
3027 /* string parsing */
3028 t = VT_BYTE;
3029 str_init:
3030 if (tcc_state->warn_write_strings)
3031 t |= VT_CONSTANT;
3032 type.t = t;
3033 mk_pointer(&type);
3034 type.t |= VT_ARRAY;
3035 memset(&ad, 0, sizeof(AttributeDef));
3036 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
3037 break;
3038 case '(':
3039 next();
3040 /* cast ? */
3041 if (parse_btype(&type, &ad)) {
3042 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3043 skip(')');
3044 /* check ISOC99 compound literal */
3045 if (tok == '{') {
3046 /* data is allocated locally by default */
3047 if (global_expr)
3048 r = VT_CONST;
3049 else
3050 r = VT_LOCAL;
3051 /* all except arrays are lvalues */
3052 if (!(type.t & VT_ARRAY))
3053 r |= lvalue_type(type.t);
3054 memset(&ad, 0, sizeof(AttributeDef));
3055 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
3056 } else {
3057 unary();
3058 gen_cast(&type);
3060 } else if (tok == '{') {
3061 /* save all registers */
3062 save_regs(0);
3063 /* statement expression : we do not accept break/continue
3064 inside as GCC does */
3065 block(NULL, NULL, NULL, NULL, 0, 1);
3066 skip(')');
3067 } else {
3068 gexpr();
3069 skip(')');
3071 break;
3072 case '*':
3073 next();
3074 unary();
3075 indir();
3076 break;
3077 case '&':
3078 next();
3079 unary();
3080 /* functions names must be treated as function pointers,
3081 except for unary '&' and sizeof. Since we consider that
3082 functions are not lvalues, we only have to handle it
3083 there and in function calls. */
3084 /* arrays can also be used although they are not lvalues */
3085 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3086 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3087 test_lvalue();
3088 mk_pointer(&vtop->type);
3089 gaddrof();
3090 break;
3091 case '!':
3092 next();
3093 unary();
3094 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3095 CType boolean;
3096 boolean.t = VT_BOOL;
3097 gen_cast(&boolean);
3098 vtop->c.i = !vtop->c.i;
3099 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3100 vtop->c.i = vtop->c.i ^ 1;
3101 else {
3102 save_regs(1);
3103 vseti(VT_JMP, gtst(1, 0));
3105 break;
3106 case '~':
3107 next();
3108 unary();
3109 vpushi(-1);
3110 gen_op('^');
3111 break;
3112 case '+':
3113 next();
3114 /* in order to force cast, we add zero */
3115 unary();
3116 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3117 error("pointer not accepted for unary plus");
3118 vpushi(0);
3119 gen_op('+');
3120 break;
3121 case TOK_SIZEOF:
3122 case TOK_ALIGNOF1:
3123 case TOK_ALIGNOF2:
3124 t = tok;
3125 next();
3126 if (tok == '(') {
3127 parse_expr_type(&type);
3128 } else {
3129 unary_type(&type);
3131 size = type_size(&type, &align);
3132 if (t == TOK_SIZEOF) {
3133 if (size < 0)
3134 error("sizeof applied to an incomplete type");
3135 vpushi(size);
3136 } else {
3137 vpushi(align);
3139 vtop->type.t |= VT_UNSIGNED;
3140 break;
3142 case TOK_builtin_types_compatible_p:
3144 CType type1, type2;
3145 next();
3146 skip('(');
3147 parse_type(&type1);
3148 skip(',');
3149 parse_type(&type2);
3150 skip(')');
3151 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3152 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3153 vpushi(is_compatible_types(&type1, &type2));
3155 break;
3156 case TOK_builtin_constant_p:
3158 int saved_nocode_wanted, res;
3159 next();
3160 skip('(');
3161 saved_nocode_wanted = nocode_wanted;
3162 nocode_wanted = 1;
3163 gexpr();
3164 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3165 vpop();
3166 nocode_wanted = saved_nocode_wanted;
3167 skip(')');
3168 vpushi(res);
3170 break;
3171 case TOK_builtin_frame_address:
3173 CType type;
3174 next();
3175 skip('(');
3176 if (tok != TOK_CINT) {
3177 error("__builtin_frame_address only takes integers");
3179 if (tokc.i != 0) {
3180 error("TCC only supports __builtin_frame_address(0)");
3182 next();
3183 skip(')');
3184 type.t = VT_VOID;
3185 mk_pointer(&type);
3186 vset(&type, VT_LOCAL, 0);
3188 break;
3189 #ifdef TCC_TARGET_X86_64
3190 case TOK_builtin_malloc:
3191 tok = TOK_malloc;
3192 goto tok_identifier;
3193 case TOK_builtin_free:
3194 tok = TOK_free;
3195 goto tok_identifier;
3196 #endif
3197 case TOK_INC:
3198 case TOK_DEC:
3199 t = tok;
3200 next();
3201 unary();
3202 inc(0, t);
3203 break;
3204 case '-':
3205 next();
3206 vpushi(0);
3207 unary();
3208 gen_op('-');
3209 break;
3210 case TOK_LAND:
3211 if (!gnu_ext)
3212 goto tok_identifier;
3213 next();
3214 /* allow to take the address of a label */
3215 if (tok < TOK_UIDENT)
3216 expect("label identifier");
3217 s = label_find(tok);
3218 if (!s) {
3219 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3220 } else {
3221 if (s->r == LABEL_DECLARED)
3222 s->r = LABEL_FORWARD;
3224 if (!s->type.t) {
3225 s->type.t = VT_VOID;
3226 mk_pointer(&s->type);
3227 s->type.t |= VT_STATIC;
3229 vset(&s->type, VT_CONST | VT_SYM, 0);
3230 vtop->sym = s;
3231 next();
3232 break;
3233 default:
3234 tok_identifier:
3235 t = tok;
3236 next();
3237 if (t < TOK_UIDENT)
3238 expect("identifier");
3239 s = sym_find(t);
3240 if (!s) {
3241 if (tok != '(')
3242 error("'%s' undeclared", get_tok_str(t, NULL));
3243 /* for simple function calls, we tolerate undeclared
3244 external reference to int() function */
3245 if (tcc_state->warn_implicit_function_declaration)
3246 warning("implicit declaration of function '%s'",
3247 get_tok_str(t, NULL));
3248 s = external_global_sym(t, &func_old_type, 0);
3250 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3251 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3252 /* if referencing an inline function, then we generate a
3253 symbol to it if not already done. It will have the
3254 effect to generate code for it at the end of the
3255 compilation unit. Inline function as always
3256 generated in the text section. */
3257 if (!s->c)
3258 put_extern_sym(s, text_section, 0, 0);
3259 r = VT_SYM | VT_CONST;
3260 } else {
3261 r = s->r;
3263 vset(&s->type, r, s->c);
3264 /* if forward reference, we must point to s */
3265 if (vtop->r & VT_SYM) {
3266 vtop->sym = s;
3267 vtop->c.ul = 0;
3269 break;
3272 /* post operations */
3273 while (1) {
3274 if (tok == TOK_INC || tok == TOK_DEC) {
3275 inc(1, tok);
3276 next();
3277 } else if (tok == '.' || tok == TOK_ARROW) {
3278 int qualifiers;
3279 /* field */
3280 if (tok == TOK_ARROW)
3281 indir();
3282 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3283 test_lvalue();
3284 gaddrof();
3285 next();
3286 /* expect pointer on structure */
3287 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3288 expect("struct or union");
3289 s = vtop->type.ref;
3290 /* find field */
3291 tok |= SYM_FIELD;
3292 while ((s = s->next) != NULL) {
3293 if (s->v == tok)
3294 break;
3296 if (!s)
3297 error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3298 /* add field offset to pointer */
3299 vtop->type = char_pointer_type; /* change type to 'char *' */
3300 vpushi(s->c);
3301 gen_op('+');
3302 /* change type to field type, and set to lvalue */
3303 vtop->type = s->type;
3304 vtop->type.t |= qualifiers;
3305 /* an array is never an lvalue */
3306 if (!(vtop->type.t & VT_ARRAY)) {
3307 vtop->r |= lvalue_type(vtop->type.t);
3308 /* if bound checking, the referenced pointer must be checked */
3309 if (tcc_state->do_bounds_check)
3310 vtop->r |= VT_MUSTBOUND;
3312 next();
3313 } else if (tok == '[') {
3314 next();
3315 gexpr();
3316 gen_op('+');
3317 indir();
3318 skip(']');
3319 } else if (tok == '(') {
3320 SValue ret;
3321 Sym *sa;
3322 int nb_args;
3324 /* function call */
3325 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3326 /* pointer test (no array accepted) */
3327 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3328 vtop->type = *pointed_type(&vtop->type);
3329 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3330 goto error_func;
3331 } else {
3332 error_func:
3333 expect("function pointer");
3335 } else {
3336 vtop->r &= ~VT_LVAL; /* no lvalue */
3338 /* get return type */
3339 s = vtop->type.ref;
3340 next();
3341 sa = s->next; /* first parameter */
3342 nb_args = 0;
3343 ret.r2 = VT_CONST;
3344 /* compute first implicit argument if a structure is returned */
3345 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3346 /* get some space for the returned structure */
3347 size = type_size(&s->type, &align);
3348 loc = (loc - size) & -align;
3349 ret.type = s->type;
3350 ret.r = VT_LOCAL | VT_LVAL;
3351 /* pass it as 'int' to avoid structure arg passing
3352 problems */
3353 vseti(VT_LOCAL, loc);
3354 ret.c = vtop->c;
3355 nb_args++;
3356 } else {
3357 ret.type = s->type;
3358 /* return in register */
3359 if (is_float(ret.type.t)) {
3360 ret.r = reg_fret(ret.type.t);
3361 } else {
3362 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3363 ret.r2 = REG_LRET;
3364 ret.r = REG_IRET;
3366 ret.c.i = 0;
3368 if (tok != ')') {
3369 for(;;) {
3370 expr_eq();
3371 gfunc_param_typed(s, sa);
3372 nb_args++;
3373 if (sa)
3374 sa = sa->next;
3375 if (tok == ')')
3376 break;
3377 skip(',');
3380 if (sa)
3381 error("too few arguments to function");
3382 skip(')');
3383 if (!nocode_wanted) {
3384 gfunc_call(nb_args);
3385 } else {
3386 vtop -= (nb_args + 1);
3388 /* return value */
3389 vsetc(&ret.type, ret.r, &ret.c);
3390 vtop->r2 = ret.r2;
3391 } else {
3392 break;
3397 static void uneq(void)
3399 int t;
3401 unary();
3402 if (tok == '=' ||
3403 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
3404 tok == TOK_A_XOR || tok == TOK_A_OR ||
3405 tok == TOK_A_SHL || tok == TOK_A_SAR) {
3406 test_lvalue();
3407 t = tok;
3408 next();
3409 if (t == '=') {
3410 expr_eq();
3411 } else {
3412 vdup();
3413 expr_eq();
3414 gen_op(t & 0x7f);
3416 vstore();
3420 static void expr_prod(void)
3422 int t;
3424 uneq();
3425 while (tok == '*' || tok == '/' || tok == '%') {
3426 t = tok;
3427 next();
3428 uneq();
3429 gen_op(t);
3433 static void expr_sum(void)
3435 int t;
3437 expr_prod();
3438 while (tok == '+' || tok == '-') {
3439 t = tok;
3440 next();
3441 expr_prod();
3442 gen_op(t);
3446 static void expr_shift(void)
3448 int t;
3450 expr_sum();
3451 while (tok == TOK_SHL || tok == TOK_SAR) {
3452 t = tok;
3453 next();
3454 expr_sum();
3455 gen_op(t);
3459 static void expr_cmp(void)
3461 int t;
3463 expr_shift();
3464 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3465 tok == TOK_ULT || tok == TOK_UGE) {
3466 t = tok;
3467 next();
3468 expr_shift();
3469 gen_op(t);
3473 static void expr_cmpeq(void)
3475 int t;
3477 expr_cmp();
3478 while (tok == TOK_EQ || tok == TOK_NE) {
3479 t = tok;
3480 next();
3481 expr_cmp();
3482 gen_op(t);
3486 static void expr_and(void)
3488 expr_cmpeq();
3489 while (tok == '&') {
3490 next();
3491 expr_cmpeq();
3492 gen_op('&');
3496 static void expr_xor(void)
3498 expr_and();
3499 while (tok == '^') {
3500 next();
3501 expr_and();
3502 gen_op('^');
3506 static void expr_or(void)
3508 expr_xor();
3509 while (tok == '|') {
3510 next();
3511 expr_xor();
3512 gen_op('|');
3516 /* XXX: fix this mess */
3517 static void expr_land_const(void)
3519 expr_or();
3520 while (tok == TOK_LAND) {
3521 next();
3522 expr_or();
3523 gen_op(TOK_LAND);
3527 /* XXX: fix this mess */
3528 static void expr_lor_const(void)
3530 expr_land_const();
3531 while (tok == TOK_LOR) {
3532 next();
3533 expr_land_const();
3534 gen_op(TOK_LOR);
3538 /* only used if non constant */
3539 static void expr_land(void)
3541 int t;
3543 expr_or();
3544 if (tok == TOK_LAND) {
3545 t = 0;
3546 save_regs(1);
3547 for(;;) {
3548 t = gtst(1, t);
3549 if (tok != TOK_LAND) {
3550 vseti(VT_JMPI, t);
3551 break;
3553 next();
3554 expr_or();
3559 static void expr_lor(void)
3561 int t;
3563 expr_land();
3564 if (tok == TOK_LOR) {
3565 t = 0;
3566 save_regs(1);
3567 for(;;) {
3568 t = gtst(0, t);
3569 if (tok != TOK_LOR) {
3570 vseti(VT_JMP, t);
3571 break;
3573 next();
3574 expr_land();
3579 /* XXX: better constant handling */
3580 static void expr_eq(void)
3582 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
3583 SValue sv;
3584 CType type, type1, type2;
3586 if (const_wanted) {
3587 expr_lor_const();
3588 if (tok == '?') {
3589 CType boolean;
3590 int c;
3591 boolean.t = VT_BOOL;
3592 vdup();
3593 gen_cast(&boolean);
3594 c = vtop->c.i;
3595 vpop();
3596 next();
3597 if (tok != ':' || !gnu_ext) {
3598 vpop();
3599 gexpr();
3601 if (!c)
3602 vpop();
3603 skip(':');
3604 expr_eq();
3605 if (c)
3606 vpop();
3608 } else {
3609 expr_lor();
3610 if (tok == '?') {
3611 next();
3612 if (vtop != vstack) {
3613 /* needed to avoid having different registers saved in
3614 each branch */
3615 if (is_float(vtop->type.t)) {
3616 rc = RC_FLOAT;
3617 #ifdef TCC_TARGET_X86_64
3618 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
3619 rc = RC_ST0;
3621 #endif
3623 else
3624 rc = RC_INT;
3625 gv(rc);
3626 save_regs(1);
3628 if (tok == ':' && gnu_ext) {
3629 gv_dup();
3630 tt = gtst(1, 0);
3631 } else {
3632 tt = gtst(1, 0);
3633 gexpr();
3635 type1 = vtop->type;
3636 sv = *vtop; /* save value to handle it later */
3637 vtop--; /* no vpop so that FP stack is not flushed */
3638 skip(':');
3639 u = gjmp(0);
3640 gsym(tt);
3641 expr_eq();
3642 type2 = vtop->type;
3644 t1 = type1.t;
3645 bt1 = t1 & VT_BTYPE;
3646 t2 = type2.t;
3647 bt2 = t2 & VT_BTYPE;
3648 /* cast operands to correct type according to ISOC rules */
3649 if (is_float(bt1) || is_float(bt2)) {
3650 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3651 type.t = VT_LDOUBLE;
3652 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3653 type.t = VT_DOUBLE;
3654 } else {
3655 type.t = VT_FLOAT;
3657 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3658 /* cast to biggest op */
3659 type.t = VT_LLONG;
3660 /* convert to unsigned if it does not fit in a long long */
3661 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
3662 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
3663 type.t |= VT_UNSIGNED;
3664 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
3665 /* XXX: test pointer compatibility */
3666 type = type1;
3667 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
3668 /* XXX: test function pointer compatibility */
3669 type = type1;
3670 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
3671 /* XXX: test structure compatibility */
3672 type = type1;
3673 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
3674 /* NOTE: as an extension, we accept void on only one side */
3675 type.t = VT_VOID;
3676 } else {
3677 /* integer operations */
3678 type.t = VT_INT;
3679 /* convert to unsigned if it does not fit in an integer */
3680 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
3681 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
3682 type.t |= VT_UNSIGNED;
3685 /* now we convert second operand */
3686 gen_cast(&type);
3687 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
3688 gaddrof();
3689 rc = RC_INT;
3690 if (is_float(type.t)) {
3691 rc = RC_FLOAT;
3692 #ifdef TCC_TARGET_X86_64
3693 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
3694 rc = RC_ST0;
3696 #endif
3697 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
3698 /* for long longs, we use fixed registers to avoid having
3699 to handle a complicated move */
3700 rc = RC_IRET;
3703 r2 = gv(rc);
3704 /* this is horrible, but we must also convert first
3705 operand */
3706 tt = gjmp(0);
3707 gsym(u);
3708 /* put again first value and cast it */
3709 *vtop = sv;
3710 gen_cast(&type);
3711 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
3712 gaddrof();
3713 r1 = gv(rc);
3714 move_reg(r2, r1);
3715 vtop->r = r2;
3716 gsym(tt);
3721 static void gexpr(void)
3723 while (1) {
3724 expr_eq();
3725 if (tok != ',')
3726 break;
3727 vpop();
3728 next();
3732 /* parse an expression and return its type without any side effect. */
3733 static void expr_type(CType *type)
3735 int saved_nocode_wanted;
3737 saved_nocode_wanted = nocode_wanted;
3738 nocode_wanted = 1;
3739 gexpr();
3740 *type = vtop->type;
3741 vpop();
3742 nocode_wanted = saved_nocode_wanted;
3745 /* parse a unary expression and return its type without any side
3746 effect. */
3747 static void unary_type(CType *type)
3749 int a;
3751 a = nocode_wanted;
3752 nocode_wanted = 1;
3753 unary();
3754 *type = vtop->type;
3755 vpop();
3756 nocode_wanted = a;
3759 /* parse a constant expression and return value in vtop. */
3760 static void expr_const1(void)
3762 int a;
3763 a = const_wanted;
3764 const_wanted = 1;
3765 expr_eq();
3766 const_wanted = a;
3769 /* parse an integer constant and return its value. */
3770 static int expr_const(void)
3772 int c;
3773 expr_const1();
3774 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
3775 expect("constant expression");
3776 c = vtop->c.i;
3777 vpop();
3778 return c;
3781 /* return the label token if current token is a label, otherwise
3782 return zero */
3783 static int is_label(void)
3785 int last_tok;
3787 /* fast test first */
3788 if (tok < TOK_UIDENT)
3789 return 0;
3790 /* no need to save tokc because tok is an identifier */
3791 last_tok = tok;
3792 next();
3793 if (tok == ':') {
3794 next();
3795 return last_tok;
3796 } else {
3797 unget_tok(last_tok);
3798 return 0;
3802 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
3803 int case_reg, int is_expr)
3805 int a, b, c, d;
3806 Sym *s;
3808 /* generate line number info */
3809 if (tcc_state->do_debug &&
3810 (last_line_num != file->line_num || last_ind != ind)) {
3811 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
3812 last_ind = ind;
3813 last_line_num = file->line_num;
3816 if (is_expr) {
3817 /* default return value is (void) */
3818 vpushi(0);
3819 vtop->type.t = VT_VOID;
3822 if (tok == TOK_IF) {
3823 /* if test */
3824 next();
3825 skip('(');
3826 gexpr();
3827 skip(')');
3828 a = gtst(1, 0);
3829 block(bsym, csym, case_sym, def_sym, case_reg, 0);
3830 c = tok;
3831 if (c == TOK_ELSE) {
3832 next();
3833 d = gjmp(0);
3834 gsym(a);
3835 block(bsym, csym, case_sym, def_sym, case_reg, 0);
3836 gsym(d); /* patch else jmp */
3837 } else
3838 gsym(a);
3839 } else if (tok == TOK_WHILE) {
3840 next();
3841 d = ind;
3842 skip('(');
3843 gexpr();
3844 skip(')');
3845 a = gtst(1, 0);
3846 b = 0;
3847 block(&a, &b, case_sym, def_sym, case_reg, 0);
3848 gjmp_addr(d);
3849 gsym(a);
3850 gsym_addr(b, d);
3851 } else if (tok == '{') {
3852 Sym *llabel;
3854 next();
3855 /* record local declaration stack position */
3856 s = local_stack;
3857 llabel = local_label_stack;
3858 /* handle local labels declarations */
3859 if (tok == TOK_LABEL) {
3860 next();
3861 for(;;) {
3862 if (tok < TOK_UIDENT)
3863 expect("label identifier");
3864 label_push(&local_label_stack, tok, LABEL_DECLARED);
3865 next();
3866 if (tok == ',') {
3867 next();
3868 } else {
3869 skip(';');
3870 break;
3874 while (tok != '}') {
3875 decl(VT_LOCAL);
3876 if (tok != '}') {
3877 if (is_expr)
3878 vpop();
3879 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
3882 /* pop locally defined labels */
3883 label_pop(&local_label_stack, llabel);
3884 /* pop locally defined symbols */
3885 if(is_expr) {
3886 /* XXX: this solution makes only valgrind happy...
3887 triggered by gcc.c-torture/execute/20000917-1.c */
3888 Sym *p;
3889 switch(vtop->type.t & VT_BTYPE) {
3890 case VT_PTR:
3891 case VT_STRUCT:
3892 case VT_ENUM:
3893 case VT_FUNC:
3894 for(p=vtop->type.ref;p;p=p->prev)
3895 if(p->prev==s)
3896 error("unsupported expression type");
3899 sym_pop(&local_stack, s);
3900 next();
3901 } else if (tok == TOK_RETURN) {
3902 next();
3903 if (tok != ';') {
3904 gexpr();
3905 gen_assign_cast(&func_vt);
3906 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
3907 CType type;
3908 /* if returning structure, must copy it to implicit
3909 first pointer arg location */
3910 #ifdef TCC_ARM_EABI
3911 int align, size;
3912 size = type_size(&func_vt,&align);
3913 if(size <= 4)
3915 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
3916 && (align & 3))
3918 int addr;
3919 loc = (loc - size) & -4;
3920 addr = loc;
3921 type = func_vt;
3922 vset(&type, VT_LOCAL | VT_LVAL, addr);
3923 vswap();
3924 vstore();
3925 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
3927 vtop->type = int_type;
3928 gv(RC_IRET);
3929 } else {
3930 #endif
3931 type = func_vt;
3932 mk_pointer(&type);
3933 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
3934 indir();
3935 vswap();
3936 /* copy structure value to pointer */
3937 vstore();
3938 #ifdef TCC_ARM_EABI
3940 #endif
3941 } else if (is_float(func_vt.t)) {
3942 gv(rc_fret(func_vt.t));
3943 } else {
3944 gv(RC_IRET);
3946 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
3948 skip(';');
3949 rsym = gjmp(rsym); /* jmp */
3950 } else if (tok == TOK_BREAK) {
3951 /* compute jump */
3952 if (!bsym)
3953 error("cannot break");
3954 *bsym = gjmp(*bsym);
3955 next();
3956 skip(';');
3957 } else if (tok == TOK_CONTINUE) {
3958 /* compute jump */
3959 if (!csym)
3960 error("cannot continue");
3961 *csym = gjmp(*csym);
3962 next();
3963 skip(';');
3964 } else if (tok == TOK_FOR) {
3965 int e;
3966 next();
3967 skip('(');
3968 if (tok != ';') {
3969 gexpr();
3970 vpop();
3972 skip(';');
3973 d = ind;
3974 c = ind;
3975 a = 0;
3976 b = 0;
3977 if (tok != ';') {
3978 gexpr();
3979 a = gtst(1, 0);
3981 skip(';');
3982 if (tok != ')') {
3983 e = gjmp(0);
3984 c = ind;
3985 gexpr();
3986 vpop();
3987 gjmp_addr(d);
3988 gsym(e);
3990 skip(')');
3991 block(&a, &b, case_sym, def_sym, case_reg, 0);
3992 gjmp_addr(c);
3993 gsym(a);
3994 gsym_addr(b, c);
3995 } else
3996 if (tok == TOK_DO) {
3997 next();
3998 a = 0;
3999 b = 0;
4000 d = ind;
4001 block(&a, &b, case_sym, def_sym, case_reg, 0);
4002 skip(TOK_WHILE);
4003 skip('(');
4004 gsym(b);
4005 gexpr();
4006 c = gtst(0, 0);
4007 gsym_addr(c, d);
4008 skip(')');
4009 gsym(a);
4010 skip(';');
4011 } else
4012 if (tok == TOK_SWITCH) {
4013 next();
4014 skip('(');
4015 gexpr();
4016 /* XXX: other types than integer */
4017 case_reg = gv(RC_INT);
4018 vpop();
4019 skip(')');
4020 a = 0;
4021 b = gjmp(0); /* jump to first case */
4022 c = 0;
4023 block(&a, csym, &b, &c, case_reg, 0);
4024 /* if no default, jmp after switch */
4025 if (c == 0)
4026 c = ind;
4027 /* default label */
4028 gsym_addr(b, c);
4029 /* break label */
4030 gsym(a);
4031 } else
4032 if (tok == TOK_CASE) {
4033 int v1, v2;
4034 if (!case_sym)
4035 expect("switch");
4036 next();
4037 v1 = expr_const();
4038 v2 = v1;
4039 if (gnu_ext && tok == TOK_DOTS) {
4040 next();
4041 v2 = expr_const();
4042 if (v2 < v1)
4043 warning("empty case range");
4045 /* since a case is like a label, we must skip it with a jmp */
4046 b = gjmp(0);
4047 gsym(*case_sym);
4048 vseti(case_reg, 0);
4049 vpushi(v1);
4050 if (v1 == v2) {
4051 gen_op(TOK_EQ);
4052 *case_sym = gtst(1, 0);
4053 } else {
4054 gen_op(TOK_GE);
4055 *case_sym = gtst(1, 0);
4056 vseti(case_reg, 0);
4057 vpushi(v2);
4058 gen_op(TOK_LE);
4059 *case_sym = gtst(1, *case_sym);
4061 gsym(b);
4062 skip(':');
4063 is_expr = 0;
4064 goto block_after_label;
4065 } else
4066 if (tok == TOK_DEFAULT) {
4067 next();
4068 skip(':');
4069 if (!def_sym)
4070 expect("switch");
4071 if (*def_sym)
4072 error("too many 'default'");
4073 *def_sym = ind;
4074 is_expr = 0;
4075 goto block_after_label;
4076 } else
4077 if (tok == TOK_GOTO) {
4078 next();
4079 if (tok == '*' && gnu_ext) {
4080 /* computed goto */
4081 next();
4082 gexpr();
4083 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4084 expect("pointer");
4085 ggoto();
4086 } else if (tok >= TOK_UIDENT) {
4087 s = label_find(tok);
4088 /* put forward definition if needed */
4089 if (!s) {
4090 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4091 } else {
4092 if (s->r == LABEL_DECLARED)
4093 s->r = LABEL_FORWARD;
4095 /* label already defined */
4096 if (s->r & LABEL_FORWARD)
4097 s->jnext = gjmp(s->jnext);
4098 else
4099 gjmp_addr(s->jnext);
4100 next();
4101 } else {
4102 expect("label identifier");
4104 skip(';');
4105 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4106 asm_instr();
4107 } else {
4108 b = is_label();
4109 if (b) {
4110 /* label case */
4111 s = label_find(b);
4112 if (s) {
4113 if (s->r == LABEL_DEFINED)
4114 error("duplicate label '%s'", get_tok_str(s->v, NULL));
4115 gsym(s->jnext);
4116 s->r = LABEL_DEFINED;
4117 } else {
4118 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4120 s->jnext = ind;
4121 /* we accept this, but it is a mistake */
4122 block_after_label:
4123 if (tok == '}') {
4124 warning("deprecated use of label at end of compound statement");
4125 } else {
4126 if (is_expr)
4127 vpop();
4128 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4130 } else {
4131 /* expression case */
4132 if (tok != ';') {
4133 if (is_expr) {
4134 vpop();
4135 gexpr();
4136 } else {
4137 gexpr();
4138 vpop();
4141 skip(';');
4146 /* t is the array or struct type. c is the array or struct
4147 address. cur_index/cur_field is the pointer to the current
4148 value. 'size_only' is true if only size info is needed (only used
4149 in arrays) */
4150 static void decl_designator(CType *type, Section *sec, unsigned long c,
4151 int *cur_index, Sym **cur_field,
4152 int size_only)
4154 Sym *s, *f;
4155 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4156 CType type1;
4158 notfirst = 0;
4159 elem_size = 0;
4160 nb_elems = 1;
4161 if (gnu_ext && (l = is_label()) != 0)
4162 goto struct_field;
4163 while (tok == '[' || tok == '.') {
4164 if (tok == '[') {
4165 if (!(type->t & VT_ARRAY))
4166 expect("array type");
4167 s = type->ref;
4168 next();
4169 index = expr_const();
4170 if (index < 0 || (s->c >= 0 && index >= s->c))
4171 expect("invalid index");
4172 if (tok == TOK_DOTS && gnu_ext) {
4173 next();
4174 index_last = expr_const();
4175 if (index_last < 0 ||
4176 (s->c >= 0 && index_last >= s->c) ||
4177 index_last < index)
4178 expect("invalid index");
4179 } else {
4180 index_last = index;
4182 skip(']');
4183 if (!notfirst)
4184 *cur_index = index_last;
4185 type = pointed_type(type);
4186 elem_size = type_size(type, &align);
4187 c += index * elem_size;
4188 /* NOTE: we only support ranges for last designator */
4189 nb_elems = index_last - index + 1;
4190 if (nb_elems != 1) {
4191 notfirst = 1;
4192 break;
4194 } else {
4195 next();
4196 l = tok;
4197 next();
4198 struct_field:
4199 if ((type->t & VT_BTYPE) != VT_STRUCT)
4200 expect("struct/union type");
4201 s = type->ref;
4202 l |= SYM_FIELD;
4203 f = s->next;
4204 while (f) {
4205 if (f->v == l)
4206 break;
4207 f = f->next;
4209 if (!f)
4210 expect("field");
4211 if (!notfirst)
4212 *cur_field = f;
4213 /* XXX: fix this mess by using explicit storage field */
4214 type1 = f->type;
4215 type1.t |= (type->t & ~VT_TYPE);
4216 type = &type1;
4217 c += f->c;
4219 notfirst = 1;
4221 if (notfirst) {
4222 if (tok == '=') {
4223 next();
4224 } else {
4225 if (!gnu_ext)
4226 expect("=");
4228 } else {
4229 if (type->t & VT_ARRAY) {
4230 index = *cur_index;
4231 type = pointed_type(type);
4232 c += index * type_size(type, &align);
4233 } else {
4234 f = *cur_field;
4235 if (!f)
4236 error("too many field init");
4237 /* XXX: fix this mess by using explicit storage field */
4238 type1 = f->type;
4239 type1.t |= (type->t & ~VT_TYPE);
4240 type = &type1;
4241 c += f->c;
4244 decl_initializer(type, sec, c, 0, size_only);
4246 /* XXX: make it more general */
4247 if (!size_only && nb_elems > 1) {
4248 unsigned long c_end;
4249 uint8_t *src, *dst;
4250 int i;
4252 if (!sec)
4253 error("range init not supported yet for dynamic storage");
4254 c_end = c + nb_elems * elem_size;
4255 if (c_end > sec->data_allocated)
4256 section_realloc(sec, c_end);
4257 src = sec->data + c;
4258 dst = src;
4259 for(i = 1; i < nb_elems; i++) {
4260 dst += elem_size;
4261 memcpy(dst, src, elem_size);
4266 #define EXPR_VAL 0
4267 #define EXPR_CONST 1
4268 #define EXPR_ANY 2
4270 /* store a value or an expression directly in global data or in local array */
4271 static void init_putv(CType *type, Section *sec, unsigned long c,
4272 int v, int expr_type)
4274 int saved_global_expr, bt, bit_pos, bit_size;
4275 void *ptr;
4276 unsigned long long bit_mask;
4277 CType dtype;
4279 switch(expr_type) {
4280 case EXPR_VAL:
4281 vpushi(v);
4282 break;
4283 case EXPR_CONST:
4284 /* compound literals must be allocated globally in this case */
4285 saved_global_expr = global_expr;
4286 global_expr = 1;
4287 expr_const1();
4288 global_expr = saved_global_expr;
4289 /* NOTE: symbols are accepted */
4290 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4291 error("initializer element is not constant");
4292 break;
4293 case EXPR_ANY:
4294 expr_eq();
4295 break;
4298 dtype = *type;
4299 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4301 if (sec) {
4302 /* XXX: not portable */
4303 /* XXX: generate error if incorrect relocation */
4304 gen_assign_cast(&dtype);
4305 bt = type->t & VT_BTYPE;
4306 /* we'll write at most 12 bytes */
4307 if (c + 12 > sec->data_allocated) {
4308 section_realloc(sec, c + 12);
4310 ptr = sec->data + c;
4311 /* XXX: make code faster ? */
4312 if (!(type->t & VT_BITFIELD)) {
4313 bit_pos = 0;
4314 bit_size = 32;
4315 bit_mask = -1LL;
4316 } else {
4317 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4318 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4319 bit_mask = (1LL << bit_size) - 1;
4321 if ((vtop->r & VT_SYM) &&
4322 (bt == VT_BYTE ||
4323 bt == VT_SHORT ||
4324 bt == VT_DOUBLE ||
4325 bt == VT_LDOUBLE ||
4326 bt == VT_LLONG ||
4327 (bt == VT_INT && bit_size != 32)))
4328 error("initializer element is not computable at load time");
4329 switch(bt) {
4330 case VT_BOOL:
4331 vtop->c.i = (vtop->c.i != 0);
4332 case VT_BYTE:
4333 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4334 break;
4335 case VT_SHORT:
4336 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4337 break;
4338 case VT_DOUBLE:
4339 *(double *)ptr = vtop->c.d;
4340 break;
4341 case VT_LDOUBLE:
4342 *(long double *)ptr = vtop->c.ld;
4343 break;
4344 case VT_LLONG:
4345 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4346 break;
4347 default:
4348 if (vtop->r & VT_SYM) {
4349 greloc(sec, vtop->sym, c, R_DATA_32);
4351 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4352 break;
4354 vtop--;
4355 } else {
4356 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4357 vswap();
4358 vstore();
4359 vpop();
4363 /* put zeros for variable based init */
4364 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4366 if (sec) {
4367 /* nothing to do because globals are already set to zero */
4368 } else {
4369 vpush_global_sym(&func_old_type, TOK_memset);
4370 vseti(VT_LOCAL, c);
4371 vpushi(0);
4372 vpushi(size);
4373 gfunc_call(3);
4377 /* 't' contains the type and storage info. 'c' is the offset of the
4378 object in section 'sec'. If 'sec' is NULL, it means stack based
4379 allocation. 'first' is true if array '{' must be read (multi
4380 dimension implicit array init handling). 'size_only' is true if
4381 size only evaluation is wanted (only for arrays). */
4382 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4383 int first, int size_only)
4385 int index, array_length, n, no_oblock, nb, parlevel, i;
4386 int size1, align1, expr_type;
4387 Sym *s, *f;
4388 CType *t1;
4390 if (type->t & VT_ARRAY) {
4391 s = type->ref;
4392 n = s->c;
4393 array_length = 0;
4394 t1 = pointed_type(type);
4395 size1 = type_size(t1, &align1);
4397 no_oblock = 1;
4398 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4399 tok == '{') {
4400 skip('{');
4401 no_oblock = 0;
4404 /* only parse strings here if correct type (otherwise: handle
4405 them as ((w)char *) expressions */
4406 if ((tok == TOK_LSTR &&
4407 #ifdef TCC_TARGET_PE
4408 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
4409 #else
4410 (t1->t & VT_BTYPE) == VT_INT
4411 #endif
4412 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
4413 while (tok == TOK_STR || tok == TOK_LSTR) {
4414 int cstr_len, ch;
4415 CString *cstr;
4417 cstr = tokc.cstr;
4418 /* compute maximum number of chars wanted */
4419 if (tok == TOK_STR)
4420 cstr_len = cstr->size;
4421 else
4422 cstr_len = cstr->size / sizeof(nwchar_t);
4423 cstr_len--;
4424 nb = cstr_len;
4425 if (n >= 0 && nb > (n - array_length))
4426 nb = n - array_length;
4427 if (!size_only) {
4428 if (cstr_len > nb)
4429 warning("initializer-string for array is too long");
4430 /* in order to go faster for common case (char
4431 string in global variable, we handle it
4432 specifically */
4433 if (sec && tok == TOK_STR && size1 == 1) {
4434 memcpy(sec->data + c + array_length, cstr->data, nb);
4435 } else {
4436 for(i=0;i<nb;i++) {
4437 if (tok == TOK_STR)
4438 ch = ((unsigned char *)cstr->data)[i];
4439 else
4440 ch = ((nwchar_t *)cstr->data)[i];
4441 init_putv(t1, sec, c + (array_length + i) * size1,
4442 ch, EXPR_VAL);
4446 array_length += nb;
4447 next();
4449 /* only add trailing zero if enough storage (no
4450 warning in this case since it is standard) */
4451 if (n < 0 || array_length < n) {
4452 if (!size_only) {
4453 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
4455 array_length++;
4457 } else {
4458 index = 0;
4459 while (tok != '}') {
4460 decl_designator(type, sec, c, &index, NULL, size_only);
4461 if (n >= 0 && index >= n)
4462 error("index too large");
4463 /* must put zero in holes (note that doing it that way
4464 ensures that it even works with designators) */
4465 if (!size_only && array_length < index) {
4466 init_putz(t1, sec, c + array_length * size1,
4467 (index - array_length) * size1);
4469 index++;
4470 if (index > array_length)
4471 array_length = index;
4472 /* special test for multi dimensional arrays (may not
4473 be strictly correct if designators are used at the
4474 same time) */
4475 if (index >= n && no_oblock)
4476 break;
4477 if (tok == '}')
4478 break;
4479 skip(',');
4482 if (!no_oblock)
4483 skip('}');
4484 /* put zeros at the end */
4485 if (!size_only && n >= 0 && array_length < n) {
4486 init_putz(t1, sec, c + array_length * size1,
4487 (n - array_length) * size1);
4489 /* patch type size if needed */
4490 if (n < 0)
4491 s->c = array_length;
4492 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
4493 (sec || !first || tok == '{')) {
4494 int par_count;
4496 /* NOTE: the previous test is a specific case for automatic
4497 struct/union init */
4498 /* XXX: union needs only one init */
4500 /* XXX: this test is incorrect for local initializers
4501 beginning with ( without {. It would be much more difficult
4502 to do it correctly (ideally, the expression parser should
4503 be used in all cases) */
4504 par_count = 0;
4505 if (tok == '(') {
4506 AttributeDef ad1;
4507 CType type1;
4508 next();
4509 while (tok == '(') {
4510 par_count++;
4511 next();
4513 if (!parse_btype(&type1, &ad1))
4514 expect("cast");
4515 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
4516 #if 0
4517 if (!is_assignable_types(type, &type1))
4518 error("invalid type for cast");
4519 #endif
4520 skip(')');
4522 no_oblock = 1;
4523 if (first || tok == '{') {
4524 skip('{');
4525 no_oblock = 0;
4527 s = type->ref;
4528 f = s->next;
4529 array_length = 0;
4530 index = 0;
4531 n = s->c;
4532 while (tok != '}') {
4533 decl_designator(type, sec, c, NULL, &f, size_only);
4534 index = f->c;
4535 if (!size_only && array_length < index) {
4536 init_putz(type, sec, c + array_length,
4537 index - array_length);
4539 index = index + type_size(&f->type, &align1);
4540 if (index > array_length)
4541 array_length = index;
4543 /* gr: skip fields from same union - ugly. */
4544 while (f->next) {
4545 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
4546 /* test for same offset */
4547 if (f->next->c != f->c)
4548 break;
4549 /* if yes, test for bitfield shift */
4550 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
4551 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4552 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4553 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
4554 if (bit_pos_1 != bit_pos_2)
4555 break;
4557 f = f->next;
4560 f = f->next;
4561 if (no_oblock && f == NULL)
4562 break;
4563 if (tok == '}')
4564 break;
4565 skip(',');
4567 /* put zeros at the end */
4568 if (!size_only && array_length < n) {
4569 init_putz(type, sec, c + array_length,
4570 n - array_length);
4572 if (!no_oblock)
4573 skip('}');
4574 while (par_count) {
4575 skip(')');
4576 par_count--;
4578 } else if (tok == '{') {
4579 next();
4580 decl_initializer(type, sec, c, first, size_only);
4581 skip('}');
4582 } else if (size_only) {
4583 /* just skip expression */
4584 parlevel = 0;
4585 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
4586 tok != -1) {
4587 if (tok == '(')
4588 parlevel++;
4589 else if (tok == ')')
4590 parlevel--;
4591 next();
4593 } else {
4594 /* currently, we always use constant expression for globals
4595 (may change for scripting case) */
4596 expr_type = EXPR_CONST;
4597 if (!sec)
4598 expr_type = EXPR_ANY;
4599 init_putv(type, sec, c, 0, expr_type);
4603 /* parse an initializer for type 't' if 'has_init' is non zero, and
4604 allocate space in local or global data space ('r' is either
4605 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
4606 variable 'v' of scope 'scope' is declared before initializers are
4607 parsed. If 'v' is zero, then a reference to the new object is put
4608 in the value stack. If 'has_init' is 2, a special parsing is done
4609 to handle string constants. */
4610 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
4611 int has_init, int v, int scope)
4613 int size, align, addr, data_offset;
4614 int level;
4615 ParseState saved_parse_state = {0};
4616 TokenString init_str;
4617 Section *sec;
4619 size = type_size(type, &align);
4620 /* If unknown size, we must evaluate it before
4621 evaluating initializers because
4622 initializers can generate global data too
4623 (e.g. string pointers or ISOC99 compound
4624 literals). It also simplifies local
4625 initializers handling */
4626 tok_str_new(&init_str);
4627 if (size < 0) {
4628 if (!has_init)
4629 error("unknown type size");
4630 /* get all init string */
4631 if (has_init == 2) {
4632 /* only get strings */
4633 while (tok == TOK_STR || tok == TOK_LSTR) {
4634 tok_str_add_tok(&init_str);
4635 next();
4637 } else {
4638 level = 0;
4639 while (level > 0 || (tok != ',' && tok != ';')) {
4640 if (tok < 0)
4641 error("unexpected end of file in initializer");
4642 tok_str_add_tok(&init_str);
4643 if (tok == '{')
4644 level++;
4645 else if (tok == '}') {
4646 level--;
4647 if (level <= 0) {
4648 next();
4649 break;
4652 next();
4655 tok_str_add(&init_str, -1);
4656 tok_str_add(&init_str, 0);
4658 /* compute size */
4659 save_parse_state(&saved_parse_state);
4661 macro_ptr = init_str.str;
4662 next();
4663 decl_initializer(type, NULL, 0, 1, 1);
4664 /* prepare second initializer parsing */
4665 macro_ptr = init_str.str;
4666 next();
4668 /* if still unknown size, error */
4669 size = type_size(type, &align);
4670 if (size < 0)
4671 error("unknown type size");
4673 /* take into account specified alignment if bigger */
4674 if (ad->aligned) {
4675 if (ad->aligned > align)
4676 align = ad->aligned;
4677 } else if (ad->packed) {
4678 align = 1;
4680 if ((r & VT_VALMASK) == VT_LOCAL) {
4681 sec = NULL;
4682 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY))
4683 loc--;
4684 loc = (loc - size) & -align;
4685 addr = loc;
4686 /* handles bounds */
4687 /* XXX: currently, since we do only one pass, we cannot track
4688 '&' operators, so we add only arrays */
4689 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
4690 unsigned long *bounds_ptr;
4691 /* add padding between regions */
4692 loc--;
4693 /* then add local bound info */
4694 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
4695 bounds_ptr[0] = addr;
4696 bounds_ptr[1] = size;
4698 if (v) {
4699 /* local variable */
4700 sym_push(v, type, r, addr);
4701 } else {
4702 /* push local reference */
4703 vset(type, r, addr);
4705 } else {
4706 Sym *sym;
4708 sym = NULL;
4709 if (v && scope == VT_CONST) {
4710 /* see if the symbol was already defined */
4711 sym = sym_find(v);
4712 if (sym) {
4713 if (!is_compatible_types(&sym->type, type))
4714 error("incompatible types for redefinition of '%s'",
4715 get_tok_str(v, NULL));
4716 if (sym->type.t & VT_EXTERN) {
4717 /* if the variable is extern, it was not allocated */
4718 sym->type.t &= ~VT_EXTERN;
4719 /* set array size if it was ommited in extern
4720 declaration */
4721 if ((sym->type.t & VT_ARRAY) &&
4722 sym->type.ref->c < 0 &&
4723 type->ref->c >= 0)
4724 sym->type.ref->c = type->ref->c;
4725 } else {
4726 /* we accept several definitions of the same
4727 global variable. this is tricky, because we
4728 must play with the SHN_COMMON type of the symbol */
4729 /* XXX: should check if the variable was already
4730 initialized. It is incorrect to initialized it
4731 twice */
4732 /* no init data, we won't add more to the symbol */
4733 if (!has_init)
4734 goto no_alloc;
4739 /* allocate symbol in corresponding section */
4740 sec = ad->section;
4741 if (!sec) {
4742 if (has_init)
4743 sec = data_section;
4744 else if (tcc_state->nocommon)
4745 sec = bss_section;
4747 if (sec) {
4748 data_offset = sec->data_offset;
4749 data_offset = (data_offset + align - 1) & -align;
4750 addr = data_offset;
4751 /* very important to increment global pointer at this time
4752 because initializers themselves can create new initializers */
4753 data_offset += size;
4754 /* add padding if bound check */
4755 if (tcc_state->do_bounds_check)
4756 data_offset++;
4757 sec->data_offset = data_offset;
4758 /* allocate section space to put the data */
4759 if (sec->sh_type != SHT_NOBITS &&
4760 data_offset > sec->data_allocated)
4761 section_realloc(sec, data_offset);
4762 /* align section if needed */
4763 if (align > sec->sh_addralign)
4764 sec->sh_addralign = align;
4765 } else {
4766 addr = 0; /* avoid warning */
4769 if (v) {
4770 if (scope != VT_CONST || !sym) {
4771 sym = sym_push(v, type, r | VT_SYM, 0);
4773 /* update symbol definition */
4774 if (sec) {
4775 put_extern_sym(sym, sec, addr, size);
4776 } else {
4777 ElfW(Sym) *esym;
4778 /* put a common area */
4779 put_extern_sym(sym, NULL, align, size);
4780 /* XXX: find a nicer way */
4781 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
4782 esym->st_shndx = SHN_COMMON;
4784 } else {
4785 CValue cval;
4787 /* push global reference */
4788 sym = get_sym_ref(type, sec, addr, size);
4789 cval.ul = 0;
4790 vsetc(type, VT_CONST | VT_SYM, &cval);
4791 vtop->sym = sym;
4794 /* handles bounds now because the symbol must be defined
4795 before for the relocation */
4796 if (tcc_state->do_bounds_check) {
4797 unsigned long *bounds_ptr;
4799 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
4800 /* then add global bound info */
4801 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
4802 bounds_ptr[0] = 0; /* relocated */
4803 bounds_ptr[1] = size;
4806 if (has_init) {
4807 decl_initializer(type, sec, addr, 1, 0);
4808 /* restore parse state if needed */
4809 if (init_str.str) {
4810 tok_str_free(init_str.str);
4811 restore_parse_state(&saved_parse_state);
4814 no_alloc: ;
4817 void put_func_debug(Sym *sym)
4819 char buf[512];
4821 /* stabs info */
4822 /* XXX: we put here a dummy type */
4823 snprintf(buf, sizeof(buf), "%s:%c1",
4824 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
4825 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
4826 cur_text_section, sym->c);
4827 /* //gr gdb wants a line at the function */
4828 put_stabn(N_SLINE, 0, file->line_num, 0);
4829 last_ind = 0;
4830 last_line_num = 0;
4833 /* parse an old style function declaration list */
4834 /* XXX: check multiple parameter */
4835 static void func_decl_list(Sym *func_sym)
4837 AttributeDef ad;
4838 int v;
4839 Sym *s;
4840 CType btype, type;
4842 /* parse each declaration */
4843 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
4844 if (!parse_btype(&btype, &ad))
4845 expect("declaration list");
4846 if (((btype.t & VT_BTYPE) == VT_ENUM ||
4847 (btype.t & VT_BTYPE) == VT_STRUCT) &&
4848 tok == ';') {
4849 /* we accept no variable after */
4850 } else {
4851 for(;;) {
4852 type = btype;
4853 type_decl(&type, &ad, &v, TYPE_DIRECT);
4854 /* find parameter in function parameter list */
4855 s = func_sym->next;
4856 while (s != NULL) {
4857 if ((s->v & ~SYM_FIELD) == v)
4858 goto found;
4859 s = s->next;
4861 error("declaration for parameter '%s' but no such parameter",
4862 get_tok_str(v, NULL));
4863 found:
4864 /* check that no storage specifier except 'register' was given */
4865 if (type.t & VT_STORAGE)
4866 error("storage class specified for '%s'", get_tok_str(v, NULL));
4867 convert_parameter_type(&type);
4868 /* we can add the type (NOTE: it could be local to the function) */
4869 s->type = type;
4870 /* accept other parameters */
4871 if (tok == ',')
4872 next();
4873 else
4874 break;
4877 skip(';');
4881 /* parse a function defined by symbol 'sym' and generate its code in
4882 'cur_text_section' */
4883 static void gen_function(Sym *sym)
4885 int saved_nocode_wanted = nocode_wanted;
4886 nocode_wanted = 0;
4887 ind = cur_text_section->data_offset;
4888 /* NOTE: we patch the symbol size later */
4889 put_extern_sym(sym, cur_text_section, ind, 0);
4890 funcname = get_tok_str(sym->v, NULL);
4891 func_ind = ind;
4892 /* put debug symbol */
4893 if (tcc_state->do_debug)
4894 put_func_debug(sym);
4895 /* push a dummy symbol to enable local sym storage */
4896 sym_push2(&local_stack, SYM_FIELD, 0, 0);
4897 gfunc_prolog(&sym->type);
4898 rsym = 0;
4899 block(NULL, NULL, NULL, NULL, 0, 0);
4900 gsym(rsym);
4901 gfunc_epilog();
4902 cur_text_section->data_offset = ind;
4903 label_pop(&global_label_stack, NULL);
4904 sym_pop(&local_stack, NULL); /* reset local stack */
4905 /* end of function */
4906 /* patch symbol size */
4907 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
4908 ind - func_ind;
4909 if (tcc_state->do_debug) {
4910 put_stabn(N_FUN, 0, 0, ind - func_ind);
4912 /* It's better to crash than to generate wrong code */
4913 cur_text_section = NULL;
4914 funcname = ""; /* for safety */
4915 func_vt.t = VT_VOID; /* for safety */
4916 ind = 0; /* for safety */
4917 nocode_wanted = saved_nocode_wanted;
4920 static void gen_inline_functions(void)
4922 Sym *sym;
4923 int *str, inline_generated, i;
4924 struct InlineFunc *fn;
4926 /* iterate while inline function are referenced */
4927 for(;;) {
4928 inline_generated = 0;
4929 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
4930 fn = tcc_state->inline_fns[i];
4931 sym = fn->sym;
4932 if (sym && sym->c) {
4933 /* the function was used: generate its code and
4934 convert it to a normal function */
4935 str = fn->token_str;
4936 fn->sym = NULL;
4937 if (file)
4938 strcpy(file->filename, fn->filename);
4939 sym->r = VT_SYM | VT_CONST;
4940 sym->type.t &= ~VT_INLINE;
4942 macro_ptr = str;
4943 next();
4944 cur_text_section = text_section;
4945 gen_function(sym);
4946 macro_ptr = NULL; /* fail safe */
4948 tok_str_free(str);
4949 inline_generated = 1;
4952 if (!inline_generated)
4953 break;
4955 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
4958 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
4959 static void decl(int l)
4961 int v, has_init, r;
4962 CType type, btype;
4963 Sym *sym;
4964 AttributeDef ad;
4966 while (1) {
4967 if (!parse_btype(&btype, &ad)) {
4968 /* skip redundant ';' */
4969 /* XXX: find more elegant solution */
4970 if (tok == ';') {
4971 next();
4972 continue;
4974 if (l == VT_CONST &&
4975 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
4976 /* global asm block */
4977 asm_global_instr();
4978 continue;
4980 /* special test for old K&R protos without explicit int
4981 type. Only accepted when defining global data */
4982 if (l == VT_LOCAL || tok < TOK_DEFINE)
4983 break;
4984 btype.t = VT_INT;
4986 if (((btype.t & VT_BTYPE) == VT_ENUM ||
4987 (btype.t & VT_BTYPE) == VT_STRUCT) &&
4988 tok == ';') {
4989 /* we accept no variable after */
4990 next();
4991 continue;
4993 while (1) { /* iterate thru each declaration */
4994 type = btype;
4995 type_decl(&type, &ad, &v, TYPE_DIRECT);
4996 #if 0
4998 char buf[500];
4999 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5000 printf("type = '%s'\n", buf);
5002 #endif
5003 if ((type.t & VT_BTYPE) == VT_FUNC) {
5004 /* if old style function prototype, we accept a
5005 declaration list */
5006 sym = type.ref;
5007 if (sym->c == FUNC_OLD)
5008 func_decl_list(sym);
5011 if (tok == '{') {
5012 if (l == VT_LOCAL)
5013 error("cannot use local functions");
5014 if ((type.t & VT_BTYPE) != VT_FUNC)
5015 expect("function definition");
5017 /* reject abstract declarators in function definition */
5018 sym = type.ref;
5019 while ((sym = sym->next) != NULL)
5020 if (!(sym->v & ~SYM_FIELD))
5021 expect("identifier");
5023 /* XXX: cannot do better now: convert extern line to static inline */
5024 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5025 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5027 sym = sym_find(v);
5028 if (sym) {
5029 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5030 goto func_error1;
5032 r = sym->type.ref->r;
5033 /* use func_call from prototype if not defined */
5034 if (FUNC_CALL(r) != FUNC_CDECL
5035 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5036 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5038 /* use export from prototype */
5039 if (FUNC_EXPORT(r))
5040 FUNC_EXPORT(type.ref->r) = 1;
5042 /* use static from prototype */
5043 if (sym->type.t & VT_STATIC)
5044 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5046 if (!is_compatible_types(&sym->type, &type)) {
5047 func_error1:
5048 error("incompatible types for redefinition of '%s'",
5049 get_tok_str(v, NULL));
5051 /* if symbol is already defined, then put complete type */
5052 sym->type = type;
5053 } else {
5054 /* put function symbol */
5055 sym = global_identifier_push(v, type.t, 0);
5056 sym->type.ref = type.ref;
5059 /* static inline functions are just recorded as a kind
5060 of macro. Their code will be emitted at the end of
5061 the compilation unit only if they are used */
5062 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5063 (VT_INLINE | VT_STATIC)) {
5064 TokenString func_str;
5065 int block_level;
5066 struct InlineFunc *fn;
5067 const char *filename;
5069 tok_str_new(&func_str);
5071 block_level = 0;
5072 for(;;) {
5073 int t;
5074 if (tok == TOK_EOF)
5075 error("unexpected end of file");
5076 tok_str_add_tok(&func_str);
5077 t = tok;
5078 next();
5079 if (t == '{') {
5080 block_level++;
5081 } else if (t == '}') {
5082 block_level--;
5083 if (block_level == 0)
5084 break;
5087 tok_str_add(&func_str, -1);
5088 tok_str_add(&func_str, 0);
5089 filename = file ? file->filename : "";
5090 fn = tcc_malloc(sizeof *fn + strlen(filename));
5091 strcpy(fn->filename, filename);
5092 fn->sym = sym;
5093 fn->token_str = func_str.str;
5094 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5096 } else {
5097 /* compute text section */
5098 cur_text_section = ad.section;
5099 if (!cur_text_section)
5100 cur_text_section = text_section;
5101 sym->r = VT_SYM | VT_CONST;
5102 gen_function(sym);
5104 break;
5105 } else {
5106 if (btype.t & VT_TYPEDEF) {
5107 /* save typedefed type */
5108 /* XXX: test storage specifiers ? */
5109 sym = sym_push(v, &type, 0, 0);
5110 sym->type.t |= VT_TYPEDEF;
5111 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
5112 /* external function definition */
5113 /* specific case for func_call attribute */
5114 if (ad.func_attr)
5115 type.ref->r = ad.func_attr;
5116 external_sym(v, &type, 0);
5117 } else {
5118 /* not lvalue if array */
5119 r = 0;
5120 if (!(type.t & VT_ARRAY))
5121 r |= lvalue_type(type.t);
5122 has_init = (tok == '=');
5123 if ((btype.t & VT_EXTERN) ||
5124 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5125 !has_init && l == VT_CONST && type.ref->c < 0)) {
5126 /* external variable */
5127 /* NOTE: as GCC, uninitialized global static
5128 arrays of null size are considered as
5129 extern */
5130 external_sym(v, &type, r);
5131 } else {
5132 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5133 if (type.t & VT_STATIC)
5134 r |= VT_CONST;
5135 else
5136 r |= l;
5137 if (has_init)
5138 next();
5139 decl_initializer_alloc(&type, &ad, r,
5140 has_init, v, l);
5143 if (tok != ',') {
5144 skip(';');
5145 break;
5147 next();