2 * TCC - Tiny C Compiler
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
23 /********************************************************/
24 /* global variables */
26 /* loc : local variable index
27 ind : output code index
29 anon_sym: anonymous symbol index
31 ST_DATA
int rsym
, anon_sym
, ind
, loc
;
33 ST_DATA Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
34 ST_DATA Section
*cur_text_section
; /* current section where function code is generated */
36 ST_DATA Section
*last_text_section
; /* to handle .previous asm directive */
38 #ifdef CONFIG_TCC_BCHECK
39 /* bound check related sections */
40 ST_DATA Section
*bounds_section
; /* contains global data bound description */
41 ST_DATA Section
*lbounds_section
; /* contains local data bound description */
44 ST_DATA Section
*symtab_section
, *strtab_section
;
46 ST_DATA Section
*stab_section
, *stabstr_section
;
47 ST_DATA Sym
*sym_free_first
;
48 ST_DATA
void **sym_pools
;
49 ST_DATA
int nb_sym_pools
;
51 ST_DATA Sym
*global_stack
;
52 ST_DATA Sym
*local_stack
;
53 ST_DATA Sym
*scope_stack_bottom
;
54 ST_DATA Sym
*define_stack
;
55 ST_DATA Sym
*global_label_stack
;
56 ST_DATA Sym
*local_label_stack
;
58 ST_DATA SValue __vstack
[1+VSTACK_SIZE
], *vtop
;
60 ST_DATA
int const_wanted
; /* true if constant wanted */
61 ST_DATA
int nocode_wanted
; /* true if no code generation wanted for an expression */
62 ST_DATA
int global_expr
; /* true if compound literals must be allocated globally (used during initializers parsing */
63 ST_DATA CType func_vt
; /* current function return type (used by return instruction) */
65 ST_DATA
int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
66 ST_DATA
char *funcname
;
68 ST_DATA CType char_pointer_type
, func_old_type
, int_type
, size_type
;
70 /* ------------------------------------------------------------------------- */
71 static void gen_cast(CType
*type
);
72 static inline CType
*pointed_type(CType
*type
);
73 static int is_compatible_types(CType
*type1
, CType
*type2
);
74 static int parse_btype(CType
*type
, AttributeDef
*ad
);
75 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
76 static void parse_expr_type(CType
*type
);
77 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
, int first
, int size_only
);
78 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
, int is_expr
);
79 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
, int has_init
, int v
, char *asm_label
, int scope
);
80 static int decl0(int l
, int is_for_loop_init
);
81 static void expr_eq(void);
82 static void unary_type(CType
*type
);
83 static void vla_runtime_type_size(CType
*type
, int *a
);
84 static int is_compatible_parameter_types(CType
*type1
, CType
*type2
);
85 static void expr_type(CType
*type
);
87 ST_INLN
int is_float(int t
)
91 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
94 /* we use our own 'finite' function to avoid potential problems with
95 non standard math libs */
96 /* XXX: endianness dependent */
97 ST_FUNC
int ieee_finite(double d
)
100 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
103 ST_FUNC
void test_lvalue(void)
105 if (!(vtop
->r
& VT_LVAL
))
109 /* ------------------------------------------------------------------------- */
110 /* symbol allocator */
111 static Sym
*__sym_malloc(void)
113 Sym
*sym_pool
, *sym
, *last_sym
;
116 sym_pool
= tcc_malloc(SYM_POOL_NB
* sizeof(Sym
));
117 dynarray_add(&sym_pools
, &nb_sym_pools
, sym_pool
);
119 last_sym
= sym_free_first
;
121 for(i
= 0; i
< SYM_POOL_NB
; i
++) {
122 sym
->next
= last_sym
;
126 sym_free_first
= last_sym
;
130 static inline Sym
*sym_malloc(void)
133 sym
= sym_free_first
;
135 sym
= __sym_malloc();
136 sym_free_first
= sym
->next
;
140 ST_INLN
void sym_free(Sym
*sym
)
142 sym
->next
= sym_free_first
;
143 tcc_free(sym
->asm_label
);
144 sym_free_first
= sym
;
147 /* push, without hashing */
148 ST_FUNC Sym
*sym_push2(Sym
**ps
, int v
, int t
, long c
)
151 if (ps
== &local_stack
) {
152 for (s
= *ps
; s
&& s
!= scope_stack_bottom
; s
= s
->prev
)
153 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
&& s
->v
== v
)
154 tcc_error("incompatible types for redefinition of '%s'",
155 get_tok_str(v
, NULL
));
174 /* find a symbol and return its associated structure. 's' is the top
175 of the symbol stack */
176 ST_FUNC Sym
*sym_find2(Sym
*s
, int v
)
186 /* structure lookup */
187 ST_INLN Sym
*struct_find(int v
)
190 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
192 return table_ident
[v
]->sym_struct
;
195 /* find an identifier */
196 ST_INLN Sym
*sym_find(int v
)
199 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
201 return table_ident
[v
]->sym_identifier
;
204 /* push a given symbol on the symbol stack */
205 ST_FUNC Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
214 s
= sym_push2(ps
, v
, type
->t
, c
);
215 s
->type
.ref
= type
->ref
;
217 /* don't record fields or anonymous symbols */
219 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
220 /* record symbol in token array */
221 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
223 ps
= &ts
->sym_struct
;
225 ps
= &ts
->sym_identifier
;
232 /* push a global identifier */
233 ST_FUNC Sym
*global_identifier_push(int v
, int t
, int c
)
236 s
= sym_push2(&global_stack
, v
, t
, c
);
237 /* don't record anonymous symbol */
238 if (v
< SYM_FIRST_ANOM
) {
239 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
240 /* modify the top most local identifier, so that
241 sym_identifier will point to 's' when popped */
243 ps
= &(*ps
)->prev_tok
;
250 /* pop symbols until top reaches 'b' */
251 ST_FUNC
void sym_pop(Sym
**ptop
, Sym
*b
)
261 /* remove symbol in token array */
263 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
264 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
266 ps
= &ts
->sym_struct
;
268 ps
= &ts
->sym_identifier
;
277 static void weaken_symbol(Sym
*sym
)
279 sym
->type
.t
|= VT_WEAK
;
284 esym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym
->c
];
285 esym_type
= ELFW(ST_TYPE
)(esym
->st_info
);
286 esym
->st_info
= ELFW(ST_INFO
)(STB_WEAK
, esym_type
);
290 /* ------------------------------------------------------------------------- */
292 ST_FUNC
void swap(int *p
, int *q
)
300 static void vsetc(CType
*type
, int r
, CValue
*vc
)
304 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
305 tcc_error("memory full");
306 /* cannot let cpu flags if other instruction are generated. Also
307 avoid leaving VT_JMP anywhere except on the top of the stack
308 because it would complicate the code generator. */
309 if (vtop
>= vstack
) {
310 v
= vtop
->r
& VT_VALMASK
;
311 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
321 /* push constant of type "type" with useless value */
322 void vpush(CType
*type
)
325 vsetc(type
, VT_CONST
, &cval
);
328 /* push integer constant */
329 ST_FUNC
void vpushi(int v
)
333 vsetc(&int_type
, VT_CONST
, &cval
);
336 /* push a pointer sized constant */
337 static void vpushs(long long v
)
344 vsetc(&size_type
, VT_CONST
, &cval
);
347 /* push long long constant */
348 static void vpushll(long long v
)
355 vsetc(&ctype
, VT_CONST
, &cval
);
358 /* push arbitrary 64bit constant */
359 void vpush64(int ty
, unsigned long long v
)
365 vsetc(&ctype
, VT_CONST
, &cval
);
368 /* Return a static symbol pointing to a section */
369 ST_FUNC Sym
*get_sym_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
375 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
376 sym
->type
.ref
= type
->ref
;
377 sym
->r
= VT_CONST
| VT_SYM
;
378 put_extern_sym(sym
, sec
, offset
, size
);
382 /* push a reference to a section offset by adding a dummy symbol */
383 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
388 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
389 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
392 /* define a new external reference to a symbol 'v' of type 'u' */
393 ST_FUNC Sym
*external_global_sym(int v
, CType
*type
, int r
)
399 /* push forward reference */
400 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
401 s
->type
.ref
= type
->ref
;
402 s
->r
= r
| VT_CONST
| VT_SYM
;
407 /* define a new external reference to a symbol 'v' with alternate asm
408 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
409 is no alternate name (most cases) */
410 static Sym
*external_sym(int v
, CType
*type
, int r
, char *asm_label
)
416 /* push forward reference */
417 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
418 s
->asm_label
= asm_label
;
419 s
->type
.t
|= VT_EXTERN
;
420 } else if (s
->type
.ref
== func_old_type
.ref
) {
421 s
->type
.ref
= type
->ref
;
422 s
->r
= r
| VT_CONST
| VT_SYM
;
423 s
->type
.t
|= VT_EXTERN
;
424 } else if (!is_compatible_types(&s
->type
, type
)) {
425 tcc_error("incompatible types for redefinition of '%s'",
426 get_tok_str(v
, NULL
));
431 /* push a reference to global symbol v */
432 ST_FUNC
void vpush_global_sym(CType
*type
, int v
)
437 sym
= external_global_sym(v
, type
, 0);
439 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
443 ST_FUNC
void vset(CType
*type
, int r
, int v
)
448 vsetc(type
, r
, &cval
);
451 static void vseti(int r
, int v
)
459 ST_FUNC
void vswap(void)
462 /* cannot let cpu flags if other instruction are generated. Also
463 avoid leaving VT_JMP anywhere except on the top of the stack
464 because it would complicate the code generator. */
465 if (vtop
>= vstack
) {
466 int v
= vtop
->r
& VT_VALMASK
;
467 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
474 /* XXX: +2% overall speed possible with optimized memswap
476 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
480 ST_FUNC
void vpushv(SValue
*v
)
482 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
483 tcc_error("memory full");
488 static void vdup(void)
493 /* save r to the memory stack, and mark it as being free */
494 ST_FUNC
void save_reg(int r
)
496 int l
, saved
, size
, align
;
500 /* modify all stack values */
503 for(p
=vstack
;p
<=vtop
;p
++) {
504 if ((p
->r
& VT_VALMASK
) == r
||
505 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& (p
->r2
& VT_VALMASK
) == r
)) {
506 /* must save value on stack if not already done */
508 /* NOTE: must reload 'r' because r might be equal to r2 */
509 r
= p
->r
& VT_VALMASK
;
510 /* store register in the stack */
512 if ((p
->r
& VT_LVAL
) ||
513 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
514 #ifdef TCC_TARGET_X86_64
515 type
= &char_pointer_type
;
519 size
= type_size(type
, &align
);
520 loc
= (loc
- size
) & -align
;
522 sv
.r
= VT_LOCAL
| VT_LVAL
;
525 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
526 /* x86 specific: need to pop fp register ST0 if saved */
528 o(0xd8dd); /* fstp %st(0) */
531 #ifndef TCC_TARGET_X86_64
532 /* special long long case */
533 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
541 /* mark that stack entry as being saved on the stack */
542 if (p
->r
& VT_LVAL
) {
543 /* also clear the bounded flag because the
544 relocation address of the function was stored in
546 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
548 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
556 #ifdef TCC_TARGET_ARM
557 /* find a register of class 'rc2' with at most one reference on stack.
558 * If none, call get_reg(rc) */
559 ST_FUNC
int get_reg_ex(int rc
, int rc2
)
564 for(r
=0;r
<NB_REGS
;r
++) {
565 if (reg_classes
[r
] & rc2
) {
568 for(p
= vstack
; p
<= vtop
; p
++) {
569 if ((p
->r
& VT_VALMASK
) == r
||
570 (p
->r2
& VT_VALMASK
) == r
)
581 /* find a free register of class 'rc'. If none, save one register */
582 ST_FUNC
int get_reg(int rc
)
587 /* find a free register */
588 for(r
=0;r
<NB_REGS
;r
++) {
589 if (reg_classes
[r
] & rc
) {
590 for(p
=vstack
;p
<=vtop
;p
++) {
591 if ((p
->r
& VT_VALMASK
) == r
||
592 (p
->r2
& VT_VALMASK
) == r
)
600 /* no register left : free the first one on the stack (VERY
601 IMPORTANT to start from the bottom to ensure that we don't
602 spill registers used in gen_opi()) */
603 for(p
=vstack
;p
<=vtop
;p
++) {
604 /* look at second register (if long long) */
605 r
= p
->r2
& VT_VALMASK
;
606 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
608 r
= p
->r
& VT_VALMASK
;
609 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
615 /* Should never comes here */
619 /* save registers up to (vtop - n) stack entry */
620 ST_FUNC
void save_regs(int n
)
625 for(p
= vstack
;p
<= p1
; p
++) {
626 r
= p
->r
& VT_VALMASK
;
633 /* move register 's' to 'r', and flush previous value of r to memory
635 static void move_reg(int r
, int s
)
648 /* get address of vtop (vtop MUST BE an lvalue) */
649 static void gaddrof(void)
651 if (vtop
->r
& VT_REF
)
654 /* tricky: if saved lvalue, then we can go back to lvalue */
655 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
656 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
661 #ifdef CONFIG_TCC_BCHECK
662 /* generate lvalue bound code */
663 static void gbound(void)
668 vtop
->r
&= ~VT_MUSTBOUND
;
669 /* if lvalue, then use checking code before dereferencing */
670 if (vtop
->r
& VT_LVAL
) {
671 /* if not VT_BOUNDED value, then make one */
672 if (!(vtop
->r
& VT_BOUNDED
)) {
673 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
674 /* must save type because we must set it to int to get pointer */
676 vtop
->type
.t
= VT_INT
;
679 gen_bounded_ptr_add();
680 vtop
->r
|= lval_type
;
683 /* then check for dereferencing */
684 gen_bounded_ptr_deref();
689 /* store vtop a register belonging to class 'rc'. lvalues are
690 converted to values. Cannot be used if cannot be converted to
691 register value (such as structures). */
692 ST_FUNC
int gv(int rc
)
694 int r
, bit_pos
, bit_size
, size
, align
, i
;
695 #ifndef TCC_TARGET_X86_64
699 /* NOTE: get_reg can modify vstack[] */
700 if (vtop
->type
.t
& VT_BITFIELD
) {
703 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
704 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
705 /* remove bit field info to avoid loops */
706 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
707 /* cast to int to propagate signedness in following ops */
708 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
713 if((vtop
->type
.t
& VT_UNSIGNED
) ||
714 (vtop
->type
.t
& VT_BTYPE
) == VT_BOOL
)
715 type
.t
|= VT_UNSIGNED
;
717 /* generate shifts */
718 vpushi(bits
- (bit_pos
+ bit_size
));
720 vpushi(bits
- bit_size
);
721 /* NOTE: transformed to SHR if unsigned */
725 if (is_float(vtop
->type
.t
) &&
726 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
729 unsigned long offset
;
730 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
734 /* XXX: unify with initializers handling ? */
735 /* CPUs usually cannot use float constants, so we store them
736 generically in data segment */
737 size
= type_size(&vtop
->type
, &align
);
738 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
739 data_section
->data_offset
= offset
;
740 /* XXX: not portable yet */
741 #if defined(__i386__) || defined(__x86_64__)
742 /* Zero pad x87 tenbyte long doubles */
743 if (size
== LDOUBLE_SIZE
) {
744 vtop
->c
.tab
[2] &= 0xffff;
745 #if LDOUBLE_SIZE == 16
750 ptr
= section_ptr_add(data_section
, size
);
752 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
756 ptr
[i
] = vtop
->c
.tab
[size
-1-i
];
760 ptr
[i
] = vtop
->c
.tab
[i
];
761 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
762 vtop
->r
|= VT_LVAL
| VT_SYM
;
766 #ifdef CONFIG_TCC_BCHECK
767 if (vtop
->r
& VT_MUSTBOUND
)
771 r
= vtop
->r
& VT_VALMASK
;
772 #ifndef TCC_TARGET_X86_64
777 /* need to reload if:
779 - lvalue (need to dereference pointer)
780 - already a register, but not in the right class */
782 || (vtop
->r
& VT_LVAL
)
783 || !(reg_classes
[r
] & rc
)
784 #ifndef TCC_TARGET_X86_64
785 || ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&& !(reg_classes
[vtop
->r2
] & rc2
))
790 #ifndef TCC_TARGET_X86_64
791 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
793 unsigned long long ll
;
794 /* two register type load : expand to two words
796 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
799 vtop
->c
.ui
= ll
; /* first word */
801 vtop
->r
= r
; /* save register value */
802 vpushi(ll
>> 32); /* second word */
803 } else if (r
>= VT_CONST
|| /* XXX: test to VT_CONST incorrect ? */
804 (vtop
->r
& VT_LVAL
)) {
805 /* We do not want to modifier the long long
806 pointer here, so the safest (and less
807 efficient) is to save all the other registers
808 in the stack. XXX: totally inefficient. */
810 /* load from memory */
813 vtop
[-1].r
= r
; /* save register value */
814 /* increment pointer to get second word */
815 vtop
->type
.t
= VT_INT
;
824 vtop
[-1].r
= r
; /* save register value */
825 vtop
->r
= vtop
[-1].r2
;
827 /* Allocate second register. Here we rely on the fact that
828 get_reg() tries first to free r2 of an SValue. */
832 /* write second register */
836 if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
838 /* lvalue of scalar type : need to use lvalue type
839 because of possible cast */
842 /* compute memory access type */
843 if (vtop
->r
& VT_LVAL_BYTE
)
845 else if (vtop
->r
& VT_LVAL_SHORT
)
847 if (vtop
->r
& VT_LVAL_UNSIGNED
)
851 /* restore wanted type */
854 /* one register type load */
859 #ifdef TCC_TARGET_C67
860 /* uses register pairs for doubles */
861 if ((vtop
->type
.t
& VT_BTYPE
) == VT_DOUBLE
)
868 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
869 ST_FUNC
void gv2(int rc1
, int rc2
)
873 /* generate more generic register first. But VT_JMP or VT_CMP
874 values must be generated first in all cases to avoid possible
876 v
= vtop
[0].r
& VT_VALMASK
;
877 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
882 /* test if reload is needed for first register */
883 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
893 /* test if reload is needed for first register */
894 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
900 /* wrapper around RC_FRET to return a register by type */
901 static int rc_fret(int t
)
903 #ifdef TCC_TARGET_X86_64
904 if (t
== VT_LDOUBLE
) {
911 /* wrapper around REG_FRET to return a register by type */
912 static int reg_fret(int t
)
914 #ifdef TCC_TARGET_X86_64
915 if (t
== VT_LDOUBLE
) {
922 /* expand long long on stack in two int registers */
923 static void lexpand(void)
927 u
= vtop
->type
.t
& VT_UNSIGNED
;
930 vtop
[0].r
= vtop
[-1].r2
;
931 vtop
[0].r2
= VT_CONST
;
932 vtop
[-1].r2
= VT_CONST
;
933 vtop
[0].type
.t
= VT_INT
| u
;
934 vtop
[-1].type
.t
= VT_INT
| u
;
937 #ifdef TCC_TARGET_ARM
938 /* expand long long on stack */
939 ST_FUNC
void lexpand_nr(void)
943 u
= vtop
->type
.t
& VT_UNSIGNED
;
946 vtop
->type
.t
= VT_INT
| u
;
947 v
=vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
);
949 vtop
[-1].c
.ui
= vtop
->c
.ull
;
950 vtop
->c
.ui
= vtop
->c
.ull
>> 32;
952 } else if (v
== (VT_LVAL
|VT_CONST
) || v
== (VT_LVAL
|VT_LOCAL
)) {
954 vtop
->r
= vtop
[-1].r
;
955 } else if (v
> VT_CONST
) {
959 vtop
->r
= vtop
[-1].r2
;
960 vtop
[-1].r2
= VT_CONST
;
961 vtop
[-1].type
.t
= VT_INT
| u
;
965 /* build a long long from two ints */
966 static void lbuild(int t
)
969 vtop
[-1].r2
= vtop
[0].r
;
974 /* rotate n first stack elements to the bottom
975 I1 ... In -> I2 ... In I1 [top is right]
977 ST_FUNC
void vrotb(int n
)
988 /* rotate the n elements before entry e towards the top
989 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
991 ST_FUNC
void vrote(SValue
*e
, int n
)
997 for(i
= 0;i
< n
- 1; i
++)
1002 /* rotate n first stack elements to the top
1003 I1 ... In -> In I1 ... I(n-1) [top is right]
1005 ST_FUNC
void vrott(int n
)
1010 /* pop stack value */
1011 ST_FUNC
void vpop(void)
1014 v
= vtop
->r
& VT_VALMASK
;
1015 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1016 /* for x86, we need to pop the FP stack */
1017 if (v
== TREG_ST0
&& !nocode_wanted
) {
1018 o(0xd8dd); /* fstp %st(0) */
1021 if (v
== VT_JMP
|| v
== VT_JMPI
) {
1022 /* need to put correct jump if && or || without test */
1028 /* convert stack entry to register and duplicate its value in another
1030 static void gv_dup(void)
1036 if ((t
& VT_BTYPE
) == VT_LLONG
) {
1043 /* stack: H L L1 H1 */
1051 /* duplicate value */
1056 #ifdef TCC_TARGET_X86_64
1057 if ((t
& VT_BTYPE
) == VT_LDOUBLE
) {
1067 load(r1
, &sv
); /* move r to r1 */
1069 /* duplicates value */
1075 #ifndef TCC_TARGET_X86_64
1076 /* generate CPU independent (unsigned) long long operations */
1077 static void gen_opl(int op
)
1079 int t
, a
, b
, op1
, c
, i
;
1081 unsigned short reg_iret
= REG_IRET
;
1082 unsigned short reg_lret
= REG_LRET
;
1088 func
= TOK___divdi3
;
1091 func
= TOK___udivdi3
;
1094 func
= TOK___moddi3
;
1097 func
= TOK___umoddi3
;
1104 /* call generic long long function */
1105 vpush_global_sym(&func_old_type
, func
);
1110 vtop
->r2
= reg_lret
;
1123 /* stack: L1 H1 L2 H2 */
1128 vtop
[-2] = vtop
[-3];
1131 /* stack: H1 H2 L1 L2 */
1137 /* stack: H1 H2 L1 L2 ML MH */
1140 /* stack: ML MH H1 H2 L1 L2 */
1144 /* stack: ML MH H1 L2 H2 L1 */
1149 /* stack: ML MH M1 M2 */
1152 } else if (op
== '+' || op
== '-') {
1153 /* XXX: add non carry method too (for MIPS or alpha) */
1159 /* stack: H1 H2 (L1 op L2) */
1162 gen_op(op1
+ 1); /* TOK_xxxC2 */
1165 /* stack: H1 H2 (L1 op L2) */
1168 /* stack: (L1 op L2) H1 H2 */
1170 /* stack: (L1 op L2) (H1 op H2) */
1178 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
1179 t
= vtop
[-1].type
.t
;
1183 /* stack: L H shift */
1185 /* constant: simpler */
1186 /* NOTE: all comments are for SHL. the other cases are
1187 done by swaping words */
1198 if (op
!= TOK_SAR
) {
1231 /* XXX: should provide a faster fallback on x86 ? */
1234 func
= TOK___ashrdi3
;
1237 func
= TOK___lshrdi3
;
1240 func
= TOK___ashldi3
;
1246 /* compare operations */
1252 /* stack: L1 H1 L2 H2 */
1254 vtop
[-1] = vtop
[-2];
1256 /* stack: L1 L2 H1 H2 */
1259 /* when values are equal, we need to compare low words. since
1260 the jump is inverted, we invert the test too. */
1263 else if (op1
== TOK_GT
)
1265 else if (op1
== TOK_ULT
)
1267 else if (op1
== TOK_UGT
)
1272 if (op1
!= TOK_NE
) {
1276 /* generate non equal test */
1277 /* XXX: NOT PORTABLE yet */
1281 #if defined(TCC_TARGET_I386)
1282 b
= psym(0x850f, 0);
1283 #elif defined(TCC_TARGET_ARM)
1285 o(0x1A000000 | encbranch(ind
, 0, 1));
1286 #elif defined(TCC_TARGET_C67)
1287 tcc_error("not implemented");
1289 #error not supported
1293 /* compare low. Always unsigned */
1297 else if (op1
== TOK_LE
)
1299 else if (op1
== TOK_GT
)
1301 else if (op1
== TOK_GE
)
1312 /* handle integer constant optimizations and various machine
1314 static void gen_opic(int op
)
1316 int c1
, c2
, t1
, t2
, n
;
1319 typedef unsigned long long U
;
1323 t1
= v1
->type
.t
& VT_BTYPE
;
1324 t2
= v2
->type
.t
& VT_BTYPE
;
1328 else if (v1
->type
.t
& VT_UNSIGNED
)
1335 else if (v2
->type
.t
& VT_UNSIGNED
)
1340 /* currently, we cannot do computations with forward symbols */
1341 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1342 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1345 case '+': l1
+= l2
; break;
1346 case '-': l1
-= l2
; break;
1347 case '&': l1
&= l2
; break;
1348 case '^': l1
^= l2
; break;
1349 case '|': l1
|= l2
; break;
1350 case '*': l1
*= l2
; break;
1357 /* if division by zero, generate explicit division */
1360 tcc_error("division by zero in constant");
1364 default: l1
/= l2
; break;
1365 case '%': l1
%= l2
; break;
1366 case TOK_UDIV
: l1
= (U
)l1
/ l2
; break;
1367 case TOK_UMOD
: l1
= (U
)l1
% l2
; break;
1370 case TOK_SHL
: l1
<<= l2
; break;
1371 case TOK_SHR
: l1
= (U
)l1
>> l2
; break;
1372 case TOK_SAR
: l1
>>= l2
; break;
1374 case TOK_ULT
: l1
= (U
)l1
< (U
)l2
; break;
1375 case TOK_UGE
: l1
= (U
)l1
>= (U
)l2
; break;
1376 case TOK_EQ
: l1
= l1
== l2
; break;
1377 case TOK_NE
: l1
= l1
!= l2
; break;
1378 case TOK_ULE
: l1
= (U
)l1
<= (U
)l2
; break;
1379 case TOK_UGT
: l1
= (U
)l1
> (U
)l2
; break;
1380 case TOK_LT
: l1
= l1
< l2
; break;
1381 case TOK_GE
: l1
= l1
>= l2
; break;
1382 case TOK_LE
: l1
= l1
<= l2
; break;
1383 case TOK_GT
: l1
= l1
> l2
; break;
1385 case TOK_LAND
: l1
= l1
&& l2
; break;
1386 case TOK_LOR
: l1
= l1
|| l2
; break;
1393 /* if commutative ops, put c2 as constant */
1394 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
1395 op
== '|' || op
== '*')) {
1397 c2
= c1
; //c = c1, c1 = c2, c2 = c;
1398 l2
= l1
; //l = l1, l1 = l2, l2 = l;
1400 /* Filter out NOP operations like x*1, x-0, x&-1... */
1401 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
1404 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
1405 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
1411 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
1412 /* try to use shifts instead of muls or divs */
1413 if (l2
> 0 && (l2
& (l2
- 1)) == 0) {
1422 else if (op
== TOK_PDIV
)
1428 } else if (c2
&& (op
== '+' || op
== '-') &&
1429 (((vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == (VT_CONST
| VT_SYM
))
1430 || (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
)) == VT_LOCAL
)) {
1431 /* symbol + constant case */
1438 if (!nocode_wanted
) {
1439 /* call low level op generator */
1440 if (t1
== VT_LLONG
|| t2
== VT_LLONG
)
1451 /* generate a floating point operation with constant propagation */
1452 static void gen_opif(int op
)
1460 /* currently, we cannot do computations with forward symbols */
1461 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1462 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1464 if (v1
->type
.t
== VT_FLOAT
) {
1467 } else if (v1
->type
.t
== VT_DOUBLE
) {
1475 /* NOTE: we only do constant propagation if finite number (not
1476 NaN or infinity) (ANSI spec) */
1477 if (!ieee_finite(f1
) || !ieee_finite(f2
))
1481 case '+': f1
+= f2
; break;
1482 case '-': f1
-= f2
; break;
1483 case '*': f1
*= f2
; break;
1487 tcc_error("division by zero in constant");
1492 /* XXX: also handles tests ? */
1496 /* XXX: overflow test ? */
1497 if (v1
->type
.t
== VT_FLOAT
) {
1499 } else if (v1
->type
.t
== VT_DOUBLE
) {
1507 if (!nocode_wanted
) {
1515 static int pointed_size(CType
*type
)
1518 return type_size(pointed_type(type
), &align
);
1521 static void vla_runtime_pointed_size(CType
*type
)
1524 vla_runtime_type_size(pointed_type(type
), &align
);
1527 static inline int is_null_pointer(SValue
*p
)
1529 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
1531 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& p
->c
.i
== 0) ||
1532 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.ll
== 0) ||
1533 ((p
->type
.t
& VT_BTYPE
) == VT_PTR
&& p
->c
.ptr
== 0);
1536 static inline int is_integer_btype(int bt
)
1538 return (bt
== VT_BYTE
|| bt
== VT_SHORT
||
1539 bt
== VT_INT
|| bt
== VT_LLONG
);
1542 /* check types for comparison or substraction of pointers */
1543 static void check_comparison_pointer_types(SValue
*p1
, SValue
*p2
, int op
)
1545 CType
*type1
, *type2
, tmp_type1
, tmp_type2
;
1548 /* null pointers are accepted for all comparisons as gcc */
1549 if (is_null_pointer(p1
) || is_null_pointer(p2
))
1553 bt1
= type1
->t
& VT_BTYPE
;
1554 bt2
= type2
->t
& VT_BTYPE
;
1555 /* accept comparison between pointer and integer with a warning */
1556 if ((is_integer_btype(bt1
) || is_integer_btype(bt2
)) && op
!= '-') {
1557 if (op
!= TOK_LOR
&& op
!= TOK_LAND
)
1558 tcc_warning("comparison between pointer and integer");
1562 /* both must be pointers or implicit function pointers */
1563 if (bt1
== VT_PTR
) {
1564 type1
= pointed_type(type1
);
1565 } else if (bt1
!= VT_FUNC
)
1566 goto invalid_operands
;
1568 if (bt2
== VT_PTR
) {
1569 type2
= pointed_type(type2
);
1570 } else if (bt2
!= VT_FUNC
) {
1572 tcc_error("invalid operands to binary %s", get_tok_str(op
, NULL
));
1574 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
1575 (type2
->t
& VT_BTYPE
) == VT_VOID
)
1579 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
1580 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
1581 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
1582 /* gcc-like error if '-' is used */
1584 goto invalid_operands
;
1586 tcc_warning("comparison of distinct pointer types lacks a cast");
1590 /* generic gen_op: handles types problems */
1591 ST_FUNC
void gen_op(int op
)
1593 int u
, t1
, t2
, bt1
, bt2
, t
;
1596 t1
= vtop
[-1].type
.t
;
1597 t2
= vtop
[0].type
.t
;
1598 bt1
= t1
& VT_BTYPE
;
1599 bt2
= t2
& VT_BTYPE
;
1601 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
1602 /* at least one operand is a pointer */
1603 /* relationnal op: must be both pointers */
1604 if (op
>= TOK_ULT
&& op
<= TOK_LOR
) {
1605 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
1606 /* pointers are handled are unsigned */
1607 #ifdef TCC_TARGET_X86_64
1608 t
= VT_LLONG
| VT_UNSIGNED
;
1610 t
= VT_INT
| VT_UNSIGNED
;
1614 /* if both pointers, then it must be the '-' op */
1615 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
1617 tcc_error("cannot use pointers here");
1618 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
1619 /* XXX: check that types are compatible */
1620 if (vtop
[-1].type
.t
& VT_VLA
) {
1621 vla_runtime_pointed_size(&vtop
[-1].type
);
1623 vpushi(pointed_size(&vtop
[-1].type
));
1627 /* set to integer type */
1628 #ifdef TCC_TARGET_X86_64
1629 vtop
->type
.t
= VT_LLONG
;
1631 vtop
->type
.t
= VT_INT
;
1636 /* exactly one pointer : must be '+' or '-'. */
1637 if (op
!= '-' && op
!= '+')
1638 tcc_error("cannot use pointers here");
1639 /* Put pointer as first operand */
1640 if (bt2
== VT_PTR
) {
1644 type1
= vtop
[-1].type
;
1645 type1
.t
&= ~VT_ARRAY
;
1646 if (vtop
[-1].type
.t
& VT_VLA
)
1647 vla_runtime_pointed_size(&vtop
[-1].type
);
1649 u
= pointed_size(&vtop
[-1].type
);
1651 tcc_error("unknown array element size");
1652 #ifdef TCC_TARGET_X86_64
1655 /* XXX: cast to int ? (long long case) */
1660 #ifdef CONFIG_TCC_BCHECK
1661 /* if evaluating constant expression, no code should be
1662 generated, so no bound check */
1663 if (tcc_state
->do_bounds_check
&& !const_wanted
) {
1664 /* if bounded pointers, we generate a special code to
1671 gen_bounded_ptr_add();
1677 /* put again type if gen_opic() swaped operands */
1680 } else if (is_float(bt1
) || is_float(bt2
)) {
1681 /* compute bigger type and do implicit casts */
1682 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
1684 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
1689 /* floats can only be used for a few operations */
1690 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
1691 (op
< TOK_ULT
|| op
> TOK_GT
))
1692 tcc_error("invalid operands for binary operation");
1694 } else if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
) {
1695 t
= bt1
== VT_LLONG
? VT_LLONG
: VT_INT
;
1696 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (t
| VT_UNSIGNED
))
1699 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
1700 /* cast to biggest op */
1702 /* convert to unsigned if it does not fit in a long long */
1703 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
1704 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
1707 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
1708 tcc_error("comparison of struct");
1710 /* integer operations */
1712 /* convert to unsigned if it does not fit in an integer */
1713 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
1714 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
1717 /* XXX: currently, some unsigned operations are explicit, so
1718 we modify them here */
1719 if (t
& VT_UNSIGNED
) {
1726 else if (op
== TOK_LT
)
1728 else if (op
== TOK_GT
)
1730 else if (op
== TOK_LE
)
1732 else if (op
== TOK_GE
)
1739 /* special case for shifts and long long: we keep the shift as
1741 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
1748 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
1749 /* relationnal op: the result is an int */
1750 vtop
->type
.t
= VT_INT
;
1757 #ifndef TCC_TARGET_ARM
1758 /* generic itof for unsigned long long case */
1759 static void gen_cvt_itof1(int t
)
1761 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
1762 (VT_LLONG
| VT_UNSIGNED
)) {
1765 vpush_global_sym(&func_old_type
, TOK___floatundisf
);
1766 #if LDOUBLE_SIZE != 8
1767 else if (t
== VT_LDOUBLE
)
1768 vpush_global_sym(&func_old_type
, TOK___floatundixf
);
1771 vpush_global_sym(&func_old_type
, TOK___floatundidf
);
1775 vtop
->r
= reg_fret(t
);
1782 /* generic ftoi for unsigned long long case */
1783 static void gen_cvt_ftoi1(int t
)
1787 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
1788 /* not handled natively */
1789 st
= vtop
->type
.t
& VT_BTYPE
;
1791 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
1792 #if LDOUBLE_SIZE != 8
1793 else if (st
== VT_LDOUBLE
)
1794 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
1797 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
1802 vtop
->r2
= REG_LRET
;
1808 /* force char or short cast */
1809 static void force_charshort_cast(int t
)
1813 /* XXX: add optimization if lvalue : just change type and offset */
1818 if (t
& VT_UNSIGNED
) {
1819 vpushi((1 << bits
) - 1);
1825 /* result must be signed or the SAR is converted to an SHL
1826 This was not the case when "t" was a signed short
1827 and the last value on the stack was an unsigned int */
1828 vtop
->type
.t
&= ~VT_UNSIGNED
;
1834 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1835 static void gen_cast(CType
*type
)
1837 int sbt
, dbt
, sf
, df
, c
, p
;
1839 /* special delayed cast for char/short */
1840 /* XXX: in some cases (multiple cascaded casts), it may still
1842 if (vtop
->r
& VT_MUSTCAST
) {
1843 vtop
->r
&= ~VT_MUSTCAST
;
1844 force_charshort_cast(vtop
->type
.t
);
1847 /* bitfields first get cast to ints */
1848 if (vtop
->type
.t
& VT_BITFIELD
) {
1852 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
1853 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
1858 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1859 p
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == (VT_CONST
| VT_SYM
);
1861 /* constant case: we can do it now */
1862 /* XXX: in ISOC, cannot do it if error in convert */
1863 if (sbt
== VT_FLOAT
)
1864 vtop
->c
.ld
= vtop
->c
.f
;
1865 else if (sbt
== VT_DOUBLE
)
1866 vtop
->c
.ld
= vtop
->c
.d
;
1869 if ((sbt
& VT_BTYPE
) == VT_LLONG
) {
1870 if (sbt
& VT_UNSIGNED
)
1871 vtop
->c
.ld
= vtop
->c
.ull
;
1873 vtop
->c
.ld
= vtop
->c
.ll
;
1875 if (sbt
& VT_UNSIGNED
)
1876 vtop
->c
.ld
= vtop
->c
.ui
;
1878 vtop
->c
.ld
= vtop
->c
.i
;
1881 if (dbt
== VT_FLOAT
)
1882 vtop
->c
.f
= (float)vtop
->c
.ld
;
1883 else if (dbt
== VT_DOUBLE
)
1884 vtop
->c
.d
= (double)vtop
->c
.ld
;
1885 } else if (sf
&& dbt
== (VT_LLONG
|VT_UNSIGNED
)) {
1886 vtop
->c
.ull
= (unsigned long long)vtop
->c
.ld
;
1887 } else if (sf
&& dbt
== VT_BOOL
) {
1888 vtop
->c
.i
= (vtop
->c
.ld
!= 0);
1891 vtop
->c
.ll
= (long long)vtop
->c
.ld
;
1892 else if (sbt
== (VT_LLONG
|VT_UNSIGNED
))
1893 vtop
->c
.ll
= vtop
->c
.ull
;
1894 else if (sbt
& VT_UNSIGNED
)
1895 vtop
->c
.ll
= vtop
->c
.ui
;
1896 #ifdef TCC_TARGET_X86_64
1897 else if (sbt
== VT_PTR
)
1900 else if (sbt
!= VT_LLONG
)
1901 vtop
->c
.ll
= vtop
->c
.i
;
1903 if (dbt
== (VT_LLONG
|VT_UNSIGNED
))
1904 vtop
->c
.ull
= vtop
->c
.ll
;
1905 else if (dbt
== VT_BOOL
)
1906 vtop
->c
.i
= (vtop
->c
.ll
!= 0);
1907 else if (dbt
!= VT_LLONG
) {
1909 if ((dbt
& VT_BTYPE
) == VT_BYTE
)
1911 else if ((dbt
& VT_BTYPE
) == VT_SHORT
)
1914 if(dbt
& VT_UNSIGNED
)
1915 vtop
->c
.ui
= ((unsigned int)vtop
->c
.ll
<< s
) >> s
;
1917 vtop
->c
.i
= ((int)vtop
->c
.ll
<< s
) >> s
;
1920 } else if (p
&& dbt
== VT_BOOL
) {
1923 } else if (!nocode_wanted
) {
1924 /* non constant case: generate code */
1926 /* convert from fp to fp */
1929 /* convert int to fp */
1932 /* convert fp to int */
1933 if (dbt
== VT_BOOL
) {
1937 /* we handle char/short/etc... with generic code */
1938 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
1939 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
1943 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
1944 /* additional cast for char/short... */
1949 #ifndef TCC_TARGET_X86_64
1950 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
1951 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
1952 /* scalar to long long */
1953 /* machine independent conversion */
1955 /* generate high word */
1956 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
1960 if (sbt
== VT_PTR
) {
1961 /* cast from pointer to int before we apply
1962 shift operation, which pointers don't support*/
1963 gen_cast(&int_type
);
1969 /* patch second register */
1970 vtop
[-1].r2
= vtop
->r
;
1974 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
||
1975 (dbt
& VT_BTYPE
) == VT_PTR
||
1976 (dbt
& VT_BTYPE
) == VT_FUNC
) {
1977 if ((sbt
& VT_BTYPE
) != VT_LLONG
&&
1978 (sbt
& VT_BTYPE
) != VT_PTR
&&
1979 (sbt
& VT_BTYPE
) != VT_FUNC
) {
1980 /* need to convert from 32bit to 64bit */
1982 if (sbt
!= (VT_INT
| VT_UNSIGNED
)) {
1983 /* x86_64 specific: movslq */
1985 o(0xc0 + (REG_VALUE(r
) << 3) + REG_VALUE(r
));
1989 } else if (dbt
== VT_BOOL
) {
1990 /* scalar to bool */
1993 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
1994 (dbt
& VT_BTYPE
) == VT_SHORT
) {
1995 if (sbt
== VT_PTR
) {
1996 vtop
->type
.t
= VT_INT
;
1997 tcc_warning("nonportable conversion from pointer to char/short");
1999 force_charshort_cast(dbt
);
2000 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
2002 if (sbt
== VT_LLONG
) {
2003 /* from long long: just take low order word */
2007 /* if lvalue and single word type, nothing to do because
2008 the lvalue already contains the real type size (see
2009 VT_LVAL_xxx constants) */
2012 } else if ((dbt
& VT_BTYPE
) == VT_PTR
&& !(vtop
->r
& VT_LVAL
)) {
2013 /* if we are casting between pointer types,
2014 we must update the VT_LVAL_xxx size */
2015 vtop
->r
= (vtop
->r
& ~VT_LVAL_TYPE
)
2016 | (lvalue_type(type
->ref
->type
.t
) & VT_LVAL_TYPE
);
2021 /* return type size as known at compile time. Put alignment at 'a' */
2022 ST_FUNC
int type_size(CType
*type
, int *a
)
2027 bt
= type
->t
& VT_BTYPE
;
2028 if (bt
== VT_STRUCT
) {
2033 } else if (bt
== VT_PTR
) {
2034 if (type
->t
& VT_ARRAY
) {
2038 ts
= type_size(&s
->type
, a
);
2040 if (ts
< 0 && s
->c
< 0)
2048 } else if (bt
== VT_LDOUBLE
) {
2050 return LDOUBLE_SIZE
;
2051 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
2052 #ifdef TCC_TARGET_I386
2053 #ifdef TCC_TARGET_PE
2058 #elif defined(TCC_TARGET_ARM)
2068 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
2071 } else if (bt
== VT_SHORT
) {
2075 /* char, void, function, _Bool */
2081 /* push type size as known at runtime time on top of value stack. Put
2083 ST_FUNC
void vla_runtime_type_size(CType
*type
, int *a
)
2085 if (type
->t
& VT_VLA
) {
2086 vset(&int_type
, VT_LOCAL
|VT_LVAL
, type
->ref
->c
);
2088 vpushi(type_size(type
, a
));
2092 /* return the pointed type of t */
2093 static inline CType
*pointed_type(CType
*type
)
2095 return &type
->ref
->type
;
2098 /* modify type so that its it is a pointer to type. */
2099 ST_FUNC
void mk_pointer(CType
*type
)
2102 s
= sym_push(SYM_FIELD
, type
, 0, -1);
2103 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
2107 /* compare function types. OLD functions match any new functions */
2108 static int is_compatible_func(CType
*type1
, CType
*type2
)
2114 if (!is_compatible_types(&s1
->type
, &s2
->type
))
2116 /* check func_call */
2117 if (FUNC_CALL(s1
->r
) != FUNC_CALL(s2
->r
))
2119 /* XXX: not complete */
2120 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
2124 while (s1
!= NULL
) {
2127 if (!is_compatible_parameter_types(&s1
->type
, &s2
->type
))
2137 /* return true if type1 and type2 are the same. If unqualified is
2138 true, qualifiers on the types are ignored.
2140 - enums are not checked as gcc __builtin_types_compatible_p ()
2142 static int compare_types(CType
*type1
, CType
*type2
, int unqualified
)
2146 t1
= type1
->t
& VT_TYPE
;
2147 t2
= type2
->t
& VT_TYPE
;
2149 /* strip qualifiers before comparing */
2150 t1
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2151 t2
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2153 /* XXX: bitfields ? */
2156 /* test more complicated cases */
2157 bt1
= t1
& VT_BTYPE
;
2158 if (bt1
== VT_PTR
) {
2159 type1
= pointed_type(type1
);
2160 type2
= pointed_type(type2
);
2161 return is_compatible_types(type1
, type2
);
2162 } else if (bt1
== VT_STRUCT
) {
2163 return (type1
->ref
== type2
->ref
);
2164 } else if (bt1
== VT_FUNC
) {
2165 return is_compatible_func(type1
, type2
);
2171 /* return true if type1 and type2 are exactly the same (including
2174 static int is_compatible_types(CType
*type1
, CType
*type2
)
2176 return compare_types(type1
,type2
,0);
2179 /* return true if type1 and type2 are the same (ignoring qualifiers).
2181 static int is_compatible_parameter_types(CType
*type1
, CType
*type2
)
2183 return compare_types(type1
,type2
,1);
2186 /* print a type. If 'varstr' is not NULL, then the variable is also
2187 printed in the type */
2189 /* XXX: add array and function pointers */
2190 static void type_to_str(char *buf
, int buf_size
,
2191 CType
*type
, const char *varstr
)
2198 t
= type
->t
& VT_TYPE
;
2201 if (t
& VT_CONSTANT
)
2202 pstrcat(buf
, buf_size
, "const ");
2203 if (t
& VT_VOLATILE
)
2204 pstrcat(buf
, buf_size
, "volatile ");
2205 if (t
& VT_UNSIGNED
)
2206 pstrcat(buf
, buf_size
, "unsigned ");
2236 tstr
= "long double";
2238 pstrcat(buf
, buf_size
, tstr
);
2242 if (bt
== VT_STRUCT
)
2246 pstrcat(buf
, buf_size
, tstr
);
2247 v
= type
->ref
->v
& ~SYM_STRUCT
;
2248 if (v
>= SYM_FIRST_ANOM
)
2249 pstrcat(buf
, buf_size
, "<anonymous>");
2251 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
2255 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
2256 pstrcat(buf
, buf_size
, "(");
2258 while (sa
!= NULL
) {
2259 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
2260 pstrcat(buf
, buf_size
, buf1
);
2263 pstrcat(buf
, buf_size
, ", ");
2265 pstrcat(buf
, buf_size
, ")");
2269 pstrcpy(buf1
, sizeof(buf1
), "*");
2271 pstrcat(buf1
, sizeof(buf1
), varstr
);
2272 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
2276 pstrcat(buf
, buf_size
, " ");
2277 pstrcat(buf
, buf_size
, varstr
);
2282 /* verify type compatibility to store vtop in 'dt' type, and generate
2284 static void gen_assign_cast(CType
*dt
)
2286 CType
*st
, *type1
, *type2
, tmp_type1
, tmp_type2
;
2287 char buf1
[256], buf2
[256];
2290 st
= &vtop
->type
; /* source type */
2291 dbt
= dt
->t
& VT_BTYPE
;
2292 sbt
= st
->t
& VT_BTYPE
;
2294 tcc_error("Cannot assign void value");
2295 if (dt
->t
& VT_CONSTANT
)
2296 tcc_warning("assignment of read-only location");
2299 /* special cases for pointers */
2300 /* '0' can also be a pointer */
2301 if (is_null_pointer(vtop
))
2303 /* accept implicit pointer to integer cast with warning */
2304 if (is_integer_btype(sbt
)) {
2305 tcc_warning("assignment makes pointer from integer without a cast");
2308 type1
= pointed_type(dt
);
2309 /* a function is implicitely a function pointer */
2310 if (sbt
== VT_FUNC
) {
2311 if ((type1
->t
& VT_BTYPE
) != VT_VOID
&&
2312 !is_compatible_types(pointed_type(dt
), st
))
2313 tcc_warning("assignment from incompatible pointer type");
2318 type2
= pointed_type(st
);
2319 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
2320 (type2
->t
& VT_BTYPE
) == VT_VOID
) {
2321 /* void * can match anything */
2323 /* exact type match, except for unsigned */
2326 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
2327 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
2328 if (!is_compatible_types(&tmp_type1
, &tmp_type2
))
2329 tcc_warning("assignment from incompatible pointer type");
2331 /* check const and volatile */
2332 if ((!(type1
->t
& VT_CONSTANT
) && (type2
->t
& VT_CONSTANT
)) ||
2333 (!(type1
->t
& VT_VOLATILE
) && (type2
->t
& VT_VOLATILE
)))
2334 tcc_warning("assignment discards qualifiers from pointer target type");
2340 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
2341 tcc_warning("assignment makes integer from pointer without a cast");
2343 /* XXX: more tests */
2348 tmp_type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2349 tmp_type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2350 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
2352 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
2353 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
2354 tcc_error("cannot cast '%s' to '%s'", buf1
, buf2
);
2362 /* store vtop in lvalue pushed on stack */
2363 ST_FUNC
void vstore(void)
2365 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
2367 ft
= vtop
[-1].type
.t
;
2368 sbt
= vtop
->type
.t
& VT_BTYPE
;
2369 dbt
= ft
& VT_BTYPE
;
2370 if ((((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
2371 (sbt
== VT_INT
&& dbt
== VT_SHORT
))
2372 && !(vtop
->type
.t
& VT_BITFIELD
)) {
2373 /* optimize char/short casts */
2374 delayed_cast
= VT_MUSTCAST
;
2375 vtop
->type
.t
= ft
& (VT_TYPE
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
)));
2376 /* XXX: factorize */
2377 if (ft
& VT_CONSTANT
)
2378 tcc_warning("assignment of read-only location");
2381 if (!(ft
& VT_BITFIELD
))
2382 gen_assign_cast(&vtop
[-1].type
);
2385 if (sbt
== VT_STRUCT
) {
2386 /* if structure, only generate pointer */
2387 /* structure assignment : generate memcpy */
2388 /* XXX: optimize if small size */
2389 if (!nocode_wanted
) {
2390 size
= type_size(&vtop
->type
, &align
);
2394 vtop
->type
.t
= VT_PTR
;
2397 /* address of memcpy() */
2400 vpush_global_sym(&func_old_type
, TOK_memcpy8
);
2401 else if(!(align
& 3))
2402 vpush_global_sym(&func_old_type
, TOK_memcpy4
);
2405 vpush_global_sym(&func_old_type
, TOK_memcpy
);
2410 vtop
->type
.t
= VT_PTR
;
2419 /* leave source on stack */
2420 } else if (ft
& VT_BITFIELD
) {
2421 /* bitfield store handling */
2422 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
2423 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2424 /* remove bit field info to avoid loops */
2425 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2427 /* duplicate source into other register */
2432 if((ft
& VT_BTYPE
) == VT_BOOL
) {
2433 gen_cast(&vtop
[-1].type
);
2434 vtop
[-1].type
.t
= (vtop
[-1].type
.t
& ~VT_BTYPE
) | (VT_BYTE
| VT_UNSIGNED
);
2437 /* duplicate destination */
2439 vtop
[-1] = vtop
[-2];
2441 /* mask and shift source */
2442 if((ft
& VT_BTYPE
) != VT_BOOL
) {
2443 if((ft
& VT_BTYPE
) == VT_LLONG
) {
2444 vpushll((1ULL << bit_size
) - 1ULL);
2446 vpushi((1 << bit_size
) - 1);
2452 /* load destination, mask and or with source */
2454 if((ft
& VT_BTYPE
) == VT_LLONG
) {
2455 vpushll(~(((1ULL << bit_size
) - 1ULL) << bit_pos
));
2457 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
2464 /* pop off shifted source from "duplicate source..." above */
2468 #ifdef CONFIG_TCC_BCHECK
2469 /* bound check case */
2470 if (vtop
[-1].r
& VT_MUSTBOUND
) {
2476 if (!nocode_wanted
) {
2480 #ifdef TCC_TARGET_X86_64
2481 if ((ft
& VT_BTYPE
) == VT_LDOUBLE
) {
2486 r
= gv(rc
); /* generate value */
2487 /* if lvalue was saved on stack, must read it */
2488 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
2490 t
= get_reg(RC_INT
);
2491 #ifdef TCC_TARGET_X86_64
2496 sv
.r
= VT_LOCAL
| VT_LVAL
;
2497 sv
.c
.ul
= vtop
[-1].c
.ul
;
2499 vtop
[-1].r
= t
| VT_LVAL
;
2502 #ifndef TCC_TARGET_X86_64
2503 /* two word case handling : store second register at word + 4 */
2504 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
2506 /* convert to int to increment easily */
2507 vtop
->type
.t
= VT_INT
;
2513 /* XXX: it works because r2 is spilled last ! */
2514 store(vtop
->r2
, vtop
- 1);
2519 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
2520 vtop
->r
|= delayed_cast
;
2524 /* post defines POST/PRE add. c is the token ++ or -- */
2525 ST_FUNC
void inc(int post
, int c
)
2528 vdup(); /* save lvalue */
2530 gv_dup(); /* duplicate value */
2535 vpushi(c
- TOK_MID
);
2537 vstore(); /* store value */
2539 vpop(); /* if post op, return saved value */
2542 /* Parse GNUC __attribute__ extension. Currently, the following
2543 extensions are recognized:
2544 - aligned(n) : set data/function alignment.
2545 - packed : force data alignment to 1
2546 - section(x) : generate data/code in this section.
2547 - unused : currently ignored, but may be used someday.
2548 - regparm(n) : pass function parameters in registers (i386 only)
2550 static void parse_attribute(AttributeDef
*ad
)
2554 while (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
) {
2558 while (tok
!= ')') {
2559 if (tok
< TOK_IDENT
)
2560 expect("attribute name");
2568 expect("section name");
2569 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
2577 expect("alias(\"target\")");
2578 ad
->alias_target
= /* save string as token, for later */
2579 tok_alloc((char*)tokc
.cstr
->data
, tokc
.cstr
->size
-1)->tok
;
2588 if (n
<= 0 || (n
& (n
- 1)) != 0)
2589 tcc_error("alignment must be a positive power of two");
2606 /* currently, no need to handle it because tcc does not
2607 track unused objects */
2611 /* currently, no need to handle it because tcc does not
2612 track unused objects */
2617 ad
->func_call
= FUNC_CDECL
;
2622 ad
->func_call
= FUNC_STDCALL
;
2624 #ifdef TCC_TARGET_I386
2634 ad
->func_call
= FUNC_FASTCALL1
+ n
- 1;
2640 ad
->func_call
= FUNC_FASTCALLW
;
2647 ad
->mode
= VT_LLONG
+ 1;
2650 ad
->mode
= VT_SHORT
+ 1;
2653 ad
->mode
= VT_INT
+ 1;
2656 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok
, NULL
));
2663 ad
->func_export
= 1;
2666 ad
->func_import
= 1;
2669 if (tcc_state
->warn_unsupported
)
2670 tcc_warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
2671 /* skip parameters */
2673 int parenthesis
= 0;
2677 else if (tok
== ')')
2680 } while (parenthesis
&& tok
!= -1);
2693 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2694 static void struct_decl(CType
*type
, int u
)
2696 int a
, v
, size
, align
, maxalign
, c
, offset
;
2697 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
, prevbt
;
2698 Sym
*s
, *ss
, *ass
, **ps
;
2702 a
= tok
; /* save decl type */
2707 /* struct already defined ? return it */
2709 expect("struct/union/enum name");
2713 tcc_error("invalid type");
2720 /* we put an undefined size for struct/union */
2721 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
2722 s
->r
= 0; /* default alignment is zero as gcc */
2723 /* put struct/union/enum name in type */
2731 tcc_error("struct/union/enum already defined");
2732 /* cannot be empty */
2734 /* non empty enums are not allowed */
2735 if (a
== TOK_ENUM
) {
2739 expect("identifier");
2745 /* enum symbols have static storage */
2746 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
2747 ss
->type
.t
|= VT_STATIC
;
2752 /* NOTE: we accept a trailing comma */
2763 while (tok
!= '}') {
2764 parse_btype(&btype
, &ad
);
2770 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
| TYPE_ABSTRACT
);
2771 if (v
== 0 && (type1
.t
& VT_BTYPE
) != VT_STRUCT
)
2772 expect("identifier");
2773 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
2774 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
| VT_INLINE
)))
2775 tcc_error("invalid type for '%s'",
2776 get_tok_str(v
, NULL
));
2780 bit_size
= expr_const();
2781 /* XXX: handle v = 0 case for messages */
2783 tcc_error("negative width in bit-field '%s'",
2784 get_tok_str(v
, NULL
));
2785 if (v
&& bit_size
== 0)
2786 tcc_error("zero width for bit-field '%s'",
2787 get_tok_str(v
, NULL
));
2789 size
= type_size(&type1
, &align
);
2791 if (align
< ad
.aligned
)
2793 } else if (ad
.packed
) {
2795 } else if (*tcc_state
->pack_stack_ptr
) {
2796 if (align
> *tcc_state
->pack_stack_ptr
)
2797 align
= *tcc_state
->pack_stack_ptr
;
2800 if (bit_size
>= 0) {
2801 bt
= type1
.t
& VT_BTYPE
;
2808 tcc_error("bitfields must have scalar type");
2810 if (bit_size
> bsize
) {
2811 tcc_error("width of '%s' exceeds its type",
2812 get_tok_str(v
, NULL
));
2813 } else if (bit_size
== bsize
) {
2814 /* no need for bit fields */
2816 } else if (bit_size
== 0) {
2817 /* XXX: what to do if only padding in a
2819 /* zero size: means to pad */
2822 /* we do not have enough room ?
2823 did the type change?
2825 if ((bit_pos
+ bit_size
) > bsize
||
2826 bt
!= prevbt
|| a
== TOK_UNION
)
2829 /* XXX: handle LSB first */
2830 type1
.t
|= VT_BITFIELD
|
2831 (bit_pos
<< VT_STRUCT_SHIFT
) |
2832 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
2833 bit_pos
+= bit_size
;
2839 if (v
!= 0 || (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
2840 /* add new memory data only if starting
2842 if (lbit_pos
== 0) {
2843 if (a
== TOK_STRUCT
) {
2844 c
= (c
+ align
- 1) & -align
;
2853 if (align
> maxalign
)
2857 printf("add field %s offset=%d",
2858 get_tok_str(v
, NULL
), offset
);
2859 if (type1
.t
& VT_BITFIELD
) {
2860 printf(" pos=%d size=%d",
2861 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
2862 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
2867 if (v
== 0 && (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
2869 while ((ass
= ass
->next
) != NULL
) {
2870 ss
= sym_push(ass
->v
, &ass
->type
, 0, offset
+ ass
->c
);
2875 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
2879 if (tok
== ';' || tok
== TOK_EOF
)
2886 /* store size and alignment */
2887 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
2893 /* return 0 if no type declaration. otherwise, return the basic type
2896 static int parse_btype(CType
*type
, AttributeDef
*ad
)
2898 int t
, u
, type_found
, typespec_found
, typedef_found
;
2902 memset(ad
, 0, sizeof(AttributeDef
));
2910 /* currently, we really ignore extension */
2920 if ((t
& VT_BTYPE
) != 0)
2921 tcc_error("too many basic types");
2937 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
2938 #ifndef TCC_TARGET_PE
2939 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
2941 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
2942 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
2956 if ((t
& VT_BTYPE
) == VT_LONG
) {
2957 #ifdef TCC_TARGET_PE
2958 t
= (t
& ~VT_BTYPE
) | VT_DOUBLE
;
2960 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
2968 struct_decl(&type1
, VT_ENUM
);
2971 type
->ref
= type1
.ref
;
2975 struct_decl(&type1
, VT_STRUCT
);
2978 /* type modifiers */
3031 /* GNUC attribute */
3032 case TOK_ATTRIBUTE1
:
3033 case TOK_ATTRIBUTE2
:
3034 parse_attribute(ad
);
3037 t
= (t
& ~VT_BTYPE
) | u
;
3045 parse_expr_type(&type1
);
3046 /* remove all storage modifiers except typedef */
3047 type1
.t
&= ~(VT_STORAGE
&~VT_TYPEDEF
);
3050 if (typespec_found
|| typedef_found
)
3053 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
3056 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
3057 type
->ref
= s
->type
.ref
;
3059 /* get attributes from typedef */
3060 if (0 == ad
->aligned
)
3061 ad
->aligned
= FUNC_ALIGN(s
->r
);
3062 if (0 == ad
->func_call
)
3063 ad
->func_call
= FUNC_CALL(s
->r
);
3064 ad
->packed
|= FUNC_PACKED(s
->r
);
3073 if ((t
& (VT_SIGNED
|VT_UNSIGNED
)) == (VT_SIGNED
|VT_UNSIGNED
))
3074 tcc_error("signed and unsigned modifier");
3075 if (tcc_state
->char_is_unsigned
) {
3076 if ((t
& (VT_SIGNED
|VT_UNSIGNED
|VT_BTYPE
)) == VT_BYTE
)
3081 /* long is never used as type */
3082 if ((t
& VT_BTYPE
) == VT_LONG
)
3083 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3084 t
= (t
& ~VT_BTYPE
) | VT_INT
;
3086 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
3092 /* convert a function parameter type (array to pointer and function to
3093 function pointer) */
3094 static inline void convert_parameter_type(CType
*pt
)
3096 /* remove const and volatile qualifiers (XXX: const could be used
3097 to indicate a const function parameter */
3098 pt
->t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
3099 /* array must be transformed to pointer according to ANSI C */
3101 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
3106 ST_FUNC
void parse_asm_str(CString
*astr
)
3109 /* read the string */
3111 expect("string constant");
3113 while (tok
== TOK_STR
) {
3114 /* XXX: add \0 handling too ? */
3115 cstr_cat(astr
, tokc
.cstr
->data
);
3118 cstr_ccat(astr
, '\0');
3121 /* Parse an asm label and return the label
3122 * Don't forget to free the CString in the caller! */
3123 static void asm_label_instr(CString
*astr
)
3126 parse_asm_str(astr
);
3129 printf("asm_alias: \"%s\"\n", (char *)astr
->data
);
3133 static void post_type(CType
*type
, AttributeDef
*ad
)
3135 int n
, l
, t1
, arg_size
, align
;
3136 Sym
**plast
, *s
, *first
;
3141 /* function declaration */
3149 /* read param name and compute offset */
3150 if (l
!= FUNC_OLD
) {
3151 if (!parse_btype(&pt
, &ad1
)) {
3153 tcc_error("invalid type");
3160 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
3162 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
3163 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
3164 tcc_error("parameter declared as void");
3165 arg_size
+= (type_size(&pt
, &align
) + PTR_SIZE
- 1) / PTR_SIZE
;
3170 expect("identifier");
3174 convert_parameter_type(&pt
);
3175 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
3181 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
3188 /* if no parameters, then old type prototype */
3192 /* NOTE: const is ignored in returned type as it has a special
3193 meaning in gcc / C++ */
3194 type
->t
&= ~VT_CONSTANT
;
3195 /* some ancient pre-K&R C allows a function to return an array
3196 and the array brackets to be put after the arguments, such
3197 that "int c()[]" means something like "int[] c()" */
3200 skip(']'); /* only handle simple "[]" */
3203 /* we push a anonymous symbol which will contain the function prototype */
3204 ad
->func_args
= arg_size
;
3205 s
= sym_push(SYM_FIELD
, type
, INT_ATTR(ad
), l
);
3209 } else if (tok
== '[') {
3210 /* array definition */
3212 if (tok
== TOK_RESTRICT1
)
3217 if (!local_stack
|| nocode_wanted
)
3218 vpushi(expr_const());
3220 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3223 tcc_error("invalid array size");
3225 if (!is_integer_btype(vtop
->type
.t
& VT_BTYPE
))
3226 tcc_error("size of variable length array should be an integer");
3231 /* parse next post type */
3232 post_type(type
, ad
);
3233 t1
|= type
->t
& VT_VLA
;
3236 loc
-= type_size(&int_type
, &align
);
3240 vla_runtime_type_size(type
, &align
);
3242 vset(&int_type
, VT_LOCAL
|VT_LVAL
, loc
);
3249 /* we push an anonymous symbol which will contain the array
3251 s
= sym_push(SYM_FIELD
, type
, 0, n
);
3252 type
->t
= (t1
? VT_VLA
: VT_ARRAY
) | VT_PTR
;
3257 /* Parse a type declaration (except basic type), and return the type
3258 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3259 expected. 'type' should contain the basic type. 'ad' is the
3260 attribute definition of the basic type. It can be modified by
3263 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
3266 CType type1
, *type2
;
3267 int qualifiers
, storage
;
3269 while (tok
== '*') {
3277 qualifiers
|= VT_CONSTANT
;
3282 qualifiers
|= VT_VOLATILE
;
3290 type
->t
|= qualifiers
;
3293 /* XXX: clarify attribute handling */
3294 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
3295 parse_attribute(ad
);
3297 /* recursive type */
3298 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3299 type1
.t
= 0; /* XXX: same as int */
3302 /* XXX: this is not correct to modify 'ad' at this point, but
3303 the syntax is not clear */
3304 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
3305 parse_attribute(ad
);
3306 type_decl(&type1
, ad
, v
, td
);
3309 /* type identifier */
3310 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
3314 if (!(td
& TYPE_ABSTRACT
))
3315 expect("identifier");
3319 storage
= type
->t
& VT_STORAGE
;
3320 type
->t
&= ~VT_STORAGE
;
3321 if (storage
& VT_STATIC
) {
3322 int saved_nocode_wanted
= nocode_wanted
;
3324 post_type(type
, ad
);
3325 nocode_wanted
= saved_nocode_wanted
;
3327 post_type(type
, ad
);
3329 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
3330 parse_attribute(ad
);
3334 /* append type at the end of type1 */
3347 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3348 ST_FUNC
int lvalue_type(int t
)
3353 if (bt
== VT_BYTE
|| bt
== VT_BOOL
)
3355 else if (bt
== VT_SHORT
)
3359 if (t
& VT_UNSIGNED
)
3360 r
|= VT_LVAL_UNSIGNED
;
3364 /* indirection with full error checking and bound check */
3365 ST_FUNC
void indir(void)
3367 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
) {
3368 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
3372 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
3374 vtop
->type
= *pointed_type(&vtop
->type
);
3375 /* Arrays and functions are never lvalues */
3376 if (!(vtop
->type
.t
& VT_ARRAY
) && !(vtop
->type
.t
& VT_VLA
)
3377 && (vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
3378 vtop
->r
|= lvalue_type(vtop
->type
.t
);
3379 /* if bound checking, the referenced pointer must be checked */
3380 #ifdef CONFIG_TCC_BCHECK
3381 if (tcc_state
->do_bounds_check
)
3382 vtop
->r
|= VT_MUSTBOUND
;
3387 /* pass a parameter to a function and do type checking and casting */
3388 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
3393 func_type
= func
->c
;
3394 if (func_type
== FUNC_OLD
||
3395 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
3396 /* default casting : only need to convert float to double */
3397 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
3401 } else if (arg
== NULL
) {
3402 tcc_error("too many arguments to function");
3405 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
3406 gen_assign_cast(&type
);
3410 /* parse an expression of the form '(type)' or '(expr)' and return its
3412 static void parse_expr_type(CType
*type
)
3418 if (parse_btype(type
, &ad
)) {
3419 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
3426 static void parse_type(CType
*type
)
3431 if (!parse_btype(type
, &ad
)) {
3434 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
3437 static void vpush_tokc(int t
)
3442 vsetc(&type
, VT_CONST
, &tokc
);
3445 ST_FUNC
void unary(void)
3447 int n
, t
, align
, size
, r
, sizeof_caller
;
3451 static int in_sizeof
= 0;
3453 sizeof_caller
= in_sizeof
;
3455 /* XXX: GCC 2.95.3 does not generate a table although it should be
3469 vpush_tokc(VT_INT
| VT_UNSIGNED
);
3473 vpush_tokc(VT_LLONG
);
3477 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
3481 vpush_tokc(VT_FLOAT
);
3485 vpush_tokc(VT_DOUBLE
);
3489 vpush_tokc(VT_LDOUBLE
);
3492 case TOK___FUNCTION__
:
3494 goto tok_identifier
;
3500 /* special function name identifier */
3501 len
= strlen(funcname
) + 1;
3502 /* generate char[len] type */
3507 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
3508 ptr
= section_ptr_add(data_section
, len
);
3509 memcpy(ptr
, funcname
, len
);
3514 #ifdef TCC_TARGET_PE
3515 t
= VT_SHORT
| VT_UNSIGNED
;
3521 /* string parsing */
3524 if (tcc_state
->warn_write_strings
)
3529 memset(&ad
, 0, sizeof(AttributeDef
));
3530 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, NULL
, 0);
3535 if (parse_btype(&type
, &ad
)) {
3536 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
3538 /* check ISOC99 compound literal */
3540 /* data is allocated locally by default */
3545 /* all except arrays are lvalues */
3546 if (!(type
.t
& VT_ARRAY
))
3547 r
|= lvalue_type(type
.t
);
3548 memset(&ad
, 0, sizeof(AttributeDef
));
3549 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, NULL
, 0);
3551 if (sizeof_caller
) {
3558 } else if (tok
== '{') {
3559 /* save all registers */
3561 /* statement expression : we do not accept break/continue
3562 inside as GCC does */
3563 block(NULL
, NULL
, NULL
, NULL
, 0, 1);
3578 /* functions names must be treated as function pointers,
3579 except for unary '&' and sizeof. Since we consider that
3580 functions are not lvalues, we only have to handle it
3581 there and in function calls. */
3582 /* arrays can also be used although they are not lvalues */
3583 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
3584 !(vtop
->type
.t
& VT_ARRAY
) && !(vtop
->type
.t
& VT_LLOCAL
))
3586 mk_pointer(&vtop
->type
);
3592 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3594 boolean
.t
= VT_BOOL
;
3596 vtop
->c
.i
= !vtop
->c
.i
;
3597 } else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
3598 vtop
->c
.i
= vtop
->c
.i
^ 1;
3601 vseti(VT_JMP
, gtst(1, 0));
3612 /* in order to force cast, we add zero */
3614 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
3615 tcc_error("pointer not accepted for unary plus");
3625 unary_type(&type
); // Perform a in_sizeof = 0;
3626 size
= type_size(&type
, &align
);
3627 if (t
== TOK_SIZEOF
) {
3628 if (!(type
.t
& VT_VLA
)) {
3630 tcc_error("sizeof applied to an incomplete type");
3633 vla_runtime_type_size(&type
, &align
);
3638 vtop
->type
.t
|= VT_UNSIGNED
;
3641 case TOK_builtin_types_compatible_p
:
3650 type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
3651 type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
3652 vpushi(is_compatible_types(&type1
, &type2
));
3655 case TOK_builtin_constant_p
:
3657 int saved_nocode_wanted
, res
;
3660 saved_nocode_wanted
= nocode_wanted
;
3663 res
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3665 nocode_wanted
= saved_nocode_wanted
;
3670 case TOK_builtin_frame_address
:
3676 if (tok
!= TOK_CINT
|| tokc
.i
< 0) {
3677 tcc_error("__builtin_frame_address only takes positive integers");
3684 vset(&type
, VT_LOCAL
, 0); /* local frame */
3686 mk_pointer(&vtop
->type
);
3687 indir(); /* -> parent frame */
3691 #ifdef TCC_TARGET_X86_64
3692 case TOK_builtin_va_arg_types
:
3694 /* This definition must be synced with stdarg.h */
3695 enum __va_arg_type
{
3696 __va_gen_reg
, __va_float_reg
, __va_stack
3704 bt
= type
.t
& VT_BTYPE
;
3705 if (bt
== VT_STRUCT
|| bt
== VT_LDOUBLE
) {
3707 } else if (bt
== VT_FLOAT
|| bt
== VT_DOUBLE
) {
3708 vpushi(__va_float_reg
);
3710 vpushi(__va_gen_reg
);
3730 goto tok_identifier
;
3732 /* allow to take the address of a label */
3733 if (tok
< TOK_UIDENT
)
3734 expect("label identifier");
3735 s
= label_find(tok
);
3737 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
3739 if (s
->r
== LABEL_DECLARED
)
3740 s
->r
= LABEL_FORWARD
;
3743 s
->type
.t
= VT_VOID
;
3744 mk_pointer(&s
->type
);
3745 s
->type
.t
|= VT_STATIC
;
3747 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
3752 // special qnan , snan and infinity values
3754 vpush64(VT_DOUBLE
, 0x7ff8000000000000ULL
);
3758 vpush64(VT_DOUBLE
, 0x7ff0000000000001ULL
);
3762 vpush64(VT_DOUBLE
, 0x7ff0000000000000ULL
);
3771 expect("identifier");
3775 tcc_error("'%s' undeclared", get_tok_str(t
, NULL
));
3776 /* for simple function calls, we tolerate undeclared
3777 external reference to int() function */
3778 if (tcc_state
->warn_implicit_function_declaration
)
3779 tcc_warning("implicit declaration of function '%s'",
3780 get_tok_str(t
, NULL
));
3781 s
= external_global_sym(t
, &func_old_type
, 0);
3783 if ((s
->type
.t
& (VT_STATIC
| VT_INLINE
| VT_BTYPE
)) ==
3784 (VT_STATIC
| VT_INLINE
| VT_FUNC
)) {
3785 /* if referencing an inline function, then we generate a
3786 symbol to it if not already done. It will have the
3787 effect to generate code for it at the end of the
3788 compilation unit. Inline function as always
3789 generated in the text section. */
3791 put_extern_sym(s
, text_section
, 0, 0);
3792 r
= VT_SYM
| VT_CONST
;
3796 vset(&s
->type
, r
, s
->c
);
3797 /* if forward reference, we must point to s */
3798 if (vtop
->r
& VT_SYM
) {
3805 /* post operations */
3807 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
3810 } else if (tok
== '.' || tok
== TOK_ARROW
) {
3813 if (tok
== TOK_ARROW
)
3815 qualifiers
= vtop
->type
.t
& (VT_CONSTANT
| VT_VOLATILE
);
3819 /* expect pointer on structure */
3820 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
3821 expect("struct or union");
3825 while ((s
= s
->next
) != NULL
) {
3830 tcc_error("field not found: %s", get_tok_str(tok
& ~SYM_FIELD
, NULL
));
3831 /* add field offset to pointer */
3832 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
3835 /* change type to field type, and set to lvalue */
3836 vtop
->type
= s
->type
;
3837 vtop
->type
.t
|= qualifiers
;
3838 /* an array is never an lvalue */
3839 if (!(vtop
->type
.t
& VT_ARRAY
)) {
3840 vtop
->r
|= lvalue_type(vtop
->type
.t
);
3841 #ifdef CONFIG_TCC_BCHECK
3842 /* if bound checking, the referenced pointer must be checked */
3843 if (tcc_state
->do_bounds_check
)
3844 vtop
->r
|= VT_MUSTBOUND
;
3848 } else if (tok
== '[') {
3854 } else if (tok
== '(') {
3860 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
3861 /* pointer test (no array accepted) */
3862 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
3863 vtop
->type
= *pointed_type(&vtop
->type
);
3864 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
3868 expect("function pointer");
3871 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
3873 /* get return type */
3876 sa
= s
->next
; /* first parameter */
3879 /* compute first implicit argument if a structure is returned */
3880 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
3881 /* get some space for the returned structure */
3882 size
= type_size(&s
->type
, &align
);
3883 loc
= (loc
- size
) & -align
;
3885 ret
.r
= VT_LOCAL
| VT_LVAL
;
3886 /* pass it as 'int' to avoid structure arg passing
3888 vseti(VT_LOCAL
, loc
);
3893 /* return in register */
3894 if (is_float(ret
.type
.t
)) {
3895 ret
.r
= reg_fret(ret
.type
.t
);
3897 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
3906 gfunc_param_typed(s
, sa
);
3916 tcc_error("too few arguments to function");
3918 if (!nocode_wanted
) {
3919 gfunc_call(nb_args
);
3921 vtop
-= (nb_args
+ 1);
3924 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
3932 ST_FUNC
void expr_prod(void)
3937 while (tok
== '*' || tok
== '/' || tok
== '%') {
3945 ST_FUNC
void expr_sum(void)
3950 while (tok
== '+' || tok
== '-') {
3958 static void expr_shift(void)
3963 while (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
3971 static void expr_cmp(void)
3976 while ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
3977 tok
== TOK_ULT
|| tok
== TOK_UGE
) {
3985 static void expr_cmpeq(void)
3990 while (tok
== TOK_EQ
|| tok
== TOK_NE
) {
3998 static void expr_and(void)
4001 while (tok
== '&') {
4008 static void expr_xor(void)
4011 while (tok
== '^') {
4018 static void expr_or(void)
4021 while (tok
== '|') {
4028 /* XXX: fix this mess */
4029 static void expr_land_const(void)
4032 while (tok
== TOK_LAND
) {
4039 /* XXX: fix this mess */
4040 static void expr_lor_const(void)
4043 while (tok
== TOK_LOR
) {
4050 /* only used if non constant */
4051 static void expr_land(void)
4056 if (tok
== TOK_LAND
) {
4061 if (tok
!= TOK_LAND
) {
4071 static void expr_lor(void)
4076 if (tok
== TOK_LOR
) {
4081 if (tok
!= TOK_LOR
) {
4091 /* XXX: better constant handling */
4092 static void expr_cond(void)
4094 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
4096 CType type
, type1
, type2
;
4103 boolean
.t
= VT_BOOL
;
4109 if (tok
!= ':' || !gnu_ext
) {
4124 if (vtop
!= vstack
) {
4125 /* needed to avoid having different registers saved in
4127 if (is_float(vtop
->type
.t
)) {
4129 #ifdef TCC_TARGET_X86_64
4130 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LDOUBLE
) {
4140 if (tok
== ':' && gnu_ext
) {
4148 sv
= *vtop
; /* save value to handle it later */
4149 vtop
--; /* no vpop so that FP stack is not flushed */
4157 bt1
= t1
& VT_BTYPE
;
4159 bt2
= t2
& VT_BTYPE
;
4160 /* cast operands to correct type according to ISOC rules */
4161 if (is_float(bt1
) || is_float(bt2
)) {
4162 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
4163 type
.t
= VT_LDOUBLE
;
4164 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
4169 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
4170 /* cast to biggest op */
4172 /* convert to unsigned if it does not fit in a long long */
4173 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
4174 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
4175 type
.t
|= VT_UNSIGNED
;
4176 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
4177 /* If one is a null ptr constant the result type
4179 if (is_null_pointer (vtop
))
4181 else if (is_null_pointer (&sv
))
4183 /* XXX: test pointer compatibility, C99 has more elaborate
4187 } else if (bt1
== VT_FUNC
|| bt2
== VT_FUNC
) {
4188 /* XXX: test function pointer compatibility */
4189 type
= bt1
== VT_FUNC
? type1
: type2
;
4190 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
4191 /* XXX: test structure compatibility */
4192 type
= bt1
== VT_STRUCT
? type1
: type2
;
4193 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
4194 /* NOTE: as an extension, we accept void on only one side */
4197 /* integer operations */
4199 /* convert to unsigned if it does not fit in an integer */
4200 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
4201 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
4202 type
.t
|= VT_UNSIGNED
;
4205 /* now we convert second operand */
4207 if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
4210 if (is_float(type
.t
)) {
4212 #ifdef TCC_TARGET_X86_64
4213 if ((type
.t
& VT_BTYPE
) == VT_LDOUBLE
) {
4217 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
4218 /* for long longs, we use fixed registers to avoid having
4219 to handle a complicated move */
4224 /* this is horrible, but we must also convert first
4228 /* put again first value and cast it */
4231 if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
4241 static void expr_eq(void)
4247 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
4248 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
4249 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
4264 ST_FUNC
void gexpr(void)
4275 /* parse an expression and return its type without any side effect. */
4276 static void expr_type(CType
*type
)
4278 int saved_nocode_wanted
;
4280 saved_nocode_wanted
= nocode_wanted
;
4285 nocode_wanted
= saved_nocode_wanted
;
4288 /* parse a unary expression and return its type without any side
4290 static void unary_type(CType
*type
)
4302 /* parse a constant expression and return value in vtop. */
4303 static void expr_const1(void)
4312 /* parse an integer constant and return its value. */
4313 ST_FUNC
int expr_const(void)
4317 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
4318 expect("constant expression");
4324 /* return the label token if current token is a label, otherwise
4326 static int is_label(void)
4330 /* fast test first */
4331 if (tok
< TOK_UIDENT
)
4333 /* no need to save tokc because tok is an identifier */
4340 unget_tok(last_tok
);
4345 static void label_or_decl(int l
)
4349 /* fast test first */
4350 if (tok
>= TOK_UIDENT
)
4352 /* no need to save tokc because tok is an identifier */
4356 unget_tok(last_tok
);
4359 unget_tok(last_tok
);
4364 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
4365 int case_reg
, int is_expr
)
4368 Sym
*s
, *frame_bottom
;
4370 /* generate line number info */
4371 if (tcc_state
->do_debug
&&
4372 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
4373 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
4375 last_line_num
= file
->line_num
;
4379 /* default return value is (void) */
4381 vtop
->type
.t
= VT_VOID
;
4384 if (tok
== TOK_IF
) {
4391 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
4393 if (c
== TOK_ELSE
) {
4397 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
4398 gsym(d
); /* patch else jmp */
4401 } else if (tok
== TOK_WHILE
) {
4409 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
4413 } else if (tok
== '{') {
4417 /* record local declaration stack position */
4419 frame_bottom
= sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
4420 frame_bottom
->next
= scope_stack_bottom
;
4421 scope_stack_bottom
= frame_bottom
;
4422 llabel
= local_label_stack
;
4423 /* handle local labels declarations */
4424 if (tok
== TOK_LABEL
) {
4427 if (tok
< TOK_UIDENT
)
4428 expect("label identifier");
4429 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
4439 while (tok
!= '}') {
4440 label_or_decl(VT_LOCAL
);
4444 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
4447 /* pop locally defined labels */
4448 label_pop(&local_label_stack
, llabel
);
4450 /* XXX: this solution makes only valgrind happy...
4451 triggered by gcc.c-torture/execute/20000917-1.c */
4453 switch(vtop
->type
.t
& VT_BTYPE
) {
4458 for(p
=vtop
->type
.ref
;p
;p
=p
->prev
)
4460 tcc_error("unsupported expression type");
4463 /* pop locally defined symbols */
4464 scope_stack_bottom
= scope_stack_bottom
->next
;
4465 sym_pop(&local_stack
, s
);
4467 } else if (tok
== TOK_RETURN
) {
4471 gen_assign_cast(&func_vt
);
4472 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
4474 /* if returning structure, must copy it to implicit
4475 first pointer arg location */
4478 size
= type_size(&func_vt
,&align
);
4481 if((vtop
->r
!= (VT_LOCAL
| VT_LVAL
) || (vtop
->c
.i
& 3))
4485 loc
= (loc
- size
) & -4;
4488 vset(&type
, VT_LOCAL
| VT_LVAL
, addr
);
4491 vset(&int_type
, VT_LOCAL
| VT_LVAL
, addr
);
4493 vtop
->type
= int_type
;
4499 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
4502 /* copy structure value to pointer */
4507 } else if (is_float(func_vt
.t
)) {
4508 gv(rc_fret(func_vt
.t
));
4512 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4515 rsym
= gjmp(rsym
); /* jmp */
4516 } else if (tok
== TOK_BREAK
) {
4519 tcc_error("cannot break");
4520 *bsym
= gjmp(*bsym
);
4523 } else if (tok
== TOK_CONTINUE
) {
4526 tcc_error("cannot continue");
4527 *csym
= gjmp(*csym
);
4530 } else if (tok
== TOK_FOR
) {
4535 frame_bottom
= sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
4536 frame_bottom
->next
= scope_stack_bottom
;
4537 scope_stack_bottom
= frame_bottom
;
4539 /* c99 for-loop init decl? */
4540 if (!decl0(VT_LOCAL
, 1)) {
4541 /* no, regular for-loop init expr */
4565 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
4569 scope_stack_bottom
= scope_stack_bottom
->next
;
4570 sym_pop(&local_stack
, s
);
4572 if (tok
== TOK_DO
) {
4577 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
4588 if (tok
== TOK_SWITCH
) {
4592 /* XXX: other types than integer */
4593 case_reg
= gv(RC_INT
);
4597 b
= gjmp(0); /* jump to first case */
4599 block(&a
, csym
, &b
, &c
, case_reg
, 0);
4600 /* if no default, jmp after switch */
4608 if (tok
== TOK_CASE
) {
4615 if (gnu_ext
&& tok
== TOK_DOTS
) {
4619 tcc_warning("empty case range");
4621 /* since a case is like a label, we must skip it with a jmp */
4628 *case_sym
= gtst(1, 0);
4631 *case_sym
= gtst(1, 0);
4635 *case_sym
= gtst(1, *case_sym
);
4640 goto block_after_label
;
4642 if (tok
== TOK_DEFAULT
) {
4648 tcc_error("too many 'default'");
4651 goto block_after_label
;
4653 if (tok
== TOK_GOTO
) {
4655 if (tok
== '*' && gnu_ext
) {
4659 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
4662 } else if (tok
>= TOK_UIDENT
) {
4663 s
= label_find(tok
);
4664 /* put forward definition if needed */
4666 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
4668 if (s
->r
== LABEL_DECLARED
)
4669 s
->r
= LABEL_FORWARD
;
4671 /* label already defined */
4672 if (s
->r
& LABEL_FORWARD
)
4673 s
->jnext
= gjmp(s
->jnext
);
4675 gjmp_addr(s
->jnext
);
4678 expect("label identifier");
4681 } else if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
4689 if (s
->r
== LABEL_DEFINED
)
4690 tcc_error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
4692 s
->r
= LABEL_DEFINED
;
4694 s
= label_push(&global_label_stack
, b
, LABEL_DEFINED
);
4697 /* we accept this, but it is a mistake */
4700 tcc_warning("deprecated use of label at end of compound statement");
4704 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
4707 /* expression case */
4722 /* t is the array or struct type. c is the array or struct
4723 address. cur_index/cur_field is the pointer to the current
4724 value. 'size_only' is true if only size info is needed (only used
4726 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
4727 int *cur_index
, Sym
**cur_field
,
4731 int notfirst
, index
, index_last
, align
, l
, nb_elems
, elem_size
;
4737 if (gnu_ext
&& (l
= is_label()) != 0)
4739 while (tok
== '[' || tok
== '.') {
4741 if (!(type
->t
& VT_ARRAY
))
4742 expect("array type");
4745 index
= expr_const();
4746 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
4747 expect("invalid index");
4748 if (tok
== TOK_DOTS
&& gnu_ext
) {
4750 index_last
= expr_const();
4751 if (index_last
< 0 ||
4752 (s
->c
>= 0 && index_last
>= s
->c
) ||
4754 expect("invalid index");
4760 *cur_index
= index_last
;
4761 type
= pointed_type(type
);
4762 elem_size
= type_size(type
, &align
);
4763 c
+= index
* elem_size
;
4764 /* NOTE: we only support ranges for last designator */
4765 nb_elems
= index_last
- index
+ 1;
4766 if (nb_elems
!= 1) {
4775 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
4776 expect("struct/union type");
4789 /* XXX: fix this mess by using explicit storage field */
4791 type1
.t
|= (type
->t
& ~VT_TYPE
);
4805 if (type
->t
& VT_ARRAY
) {
4807 type
= pointed_type(type
);
4808 c
+= index
* type_size(type
, &align
);
4812 tcc_error("too many field init");
4813 /* XXX: fix this mess by using explicit storage field */
4815 type1
.t
|= (type
->t
& ~VT_TYPE
);
4820 decl_initializer(type
, sec
, c
, 0, size_only
);
4822 /* XXX: make it more general */
4823 if (!size_only
&& nb_elems
> 1) {
4824 unsigned long c_end
;
4829 tcc_error("range init not supported yet for dynamic storage");
4830 c_end
= c
+ nb_elems
* elem_size
;
4831 if (c_end
> sec
->data_allocated
)
4832 section_realloc(sec
, c_end
);
4833 src
= sec
->data
+ c
;
4835 for(i
= 1; i
< nb_elems
; i
++) {
4837 memcpy(dst
, src
, elem_size
);
4843 #define EXPR_CONST 1
4846 /* store a value or an expression directly in global data or in local array */
4847 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
4848 int v
, int expr_type
)
4850 int saved_global_expr
, bt
, bit_pos
, bit_size
;
4852 unsigned long long bit_mask
;
4860 /* compound literals must be allocated globally in this case */
4861 saved_global_expr
= global_expr
;
4864 global_expr
= saved_global_expr
;
4865 /* NOTE: symbols are accepted */
4866 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
4867 tcc_error("initializer element is not constant");
4875 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
4878 /* XXX: not portable */
4879 /* XXX: generate error if incorrect relocation */
4880 gen_assign_cast(&dtype
);
4881 bt
= type
->t
& VT_BTYPE
;
4882 /* we'll write at most 12 bytes */
4883 if (c
+ 12 > sec
->data_allocated
) {
4884 section_realloc(sec
, c
+ 12);
4886 ptr
= sec
->data
+ c
;
4887 /* XXX: make code faster ? */
4888 if (!(type
->t
& VT_BITFIELD
)) {
4893 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
4894 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4895 bit_mask
= (1LL << bit_size
) - 1;
4897 if ((vtop
->r
& VT_SYM
) &&
4903 (bt
== VT_INT
&& bit_size
!= 32)))
4904 tcc_error("initializer element is not computable at load time");
4907 vtop
->c
.i
= (vtop
->c
.i
!= 0);
4909 *(char *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
4912 *(short *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
4915 *(double *)ptr
= vtop
->c
.d
;
4918 *(long double *)ptr
= vtop
->c
.ld
;
4921 *(long long *)ptr
|= (vtop
->c
.ll
& bit_mask
) << bit_pos
;
4924 if (vtop
->r
& VT_SYM
) {
4925 greloc(sec
, vtop
->sym
, c
, R_DATA_PTR
);
4927 *(int *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
4932 vset(&dtype
, VT_LOCAL
|VT_LVAL
, c
);
4939 /* put zeros for variable based init */
4940 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
4943 /* nothing to do because globals are already set to zero */
4945 vpush_global_sym(&func_old_type
, TOK_memset
);
4953 /* 't' contains the type and storage info. 'c' is the offset of the
4954 object in section 'sec'. If 'sec' is NULL, it means stack based
4955 allocation. 'first' is true if array '{' must be read (multi
4956 dimension implicit array init handling). 'size_only' is true if
4957 size only evaluation is wanted (only for arrays). */
4958 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
4959 int first
, int size_only
)
4961 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, parlevel1
, i
;
4962 int size1
, align1
, expr_type
;
4966 if (type
->t
& VT_VLA
) {
4967 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
4971 vpush_global_sym(&func_old_type
, TOK_alloca
);
4972 vla_runtime_type_size(type
, &a
);
4977 vsetc(type
, REG_IRET
, &retcval
);
4978 vset(type
, VT_LOCAL
|VT_LVAL
, c
);
4983 tcc_error("variable length arrays unsupported for this target");
4985 } else if (type
->t
& VT_ARRAY
) {
4989 t1
= pointed_type(type
);
4990 size1
= type_size(t1
, &align1
);
4993 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
4996 tcc_error("character array initializer must be a literal,"
4997 " optionally enclosed in braces");
5002 /* only parse strings here if correct type (otherwise: handle
5003 them as ((w)char *) expressions */
5004 if ((tok
== TOK_LSTR
&&
5005 #ifdef TCC_TARGET_PE
5006 (t1
->t
& VT_BTYPE
) == VT_SHORT
&& (t1
->t
& VT_UNSIGNED
)
5008 (t1
->t
& VT_BTYPE
) == VT_INT
5010 ) || (tok
== TOK_STR
&& (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
5011 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5016 /* compute maximum number of chars wanted */
5018 cstr_len
= cstr
->size
;
5020 cstr_len
= cstr
->size
/ sizeof(nwchar_t
);
5023 if (n
>= 0 && nb
> (n
- array_length
))
5024 nb
= n
- array_length
;
5027 tcc_warning("initializer-string for array is too long");
5028 /* in order to go faster for common case (char
5029 string in global variable, we handle it
5031 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
5032 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
5036 ch
= ((unsigned char *)cstr
->data
)[i
];
5038 ch
= ((nwchar_t
*)cstr
->data
)[i
];
5039 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
5047 /* only add trailing zero if enough storage (no
5048 warning in this case since it is standard) */
5049 if (n
< 0 || array_length
< n
) {
5051 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
5057 while (tok
!= '}') {
5058 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
5059 if (n
>= 0 && index
>= n
)
5060 tcc_error("index too large");
5061 /* must put zero in holes (note that doing it that way
5062 ensures that it even works with designators) */
5063 if (!size_only
&& array_length
< index
) {
5064 init_putz(t1
, sec
, c
+ array_length
* size1
,
5065 (index
- array_length
) * size1
);
5068 if (index
> array_length
)
5069 array_length
= index
;
5070 /* special test for multi dimensional arrays (may not
5071 be strictly correct if designators are used at the
5073 if (index
>= n
&& no_oblock
)
5082 /* put zeros at the end */
5083 if (!size_only
&& n
>= 0 && array_length
< n
) {
5084 init_putz(t1
, sec
, c
+ array_length
* size1
,
5085 (n
- array_length
) * size1
);
5087 /* patch type size if needed */
5089 s
->c
= array_length
;
5090 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&&
5091 (sec
|| !first
|| tok
== '{')) {
5094 /* NOTE: the previous test is a specific case for automatic
5095 struct/union init */
5096 /* XXX: union needs only one init */
5098 /* XXX: this test is incorrect for local initializers
5099 beginning with ( without {. It would be much more difficult
5100 to do it correctly (ideally, the expression parser should
5101 be used in all cases) */
5107 while (tok
== '(') {
5111 if (!parse_btype(&type1
, &ad1
))
5113 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
5115 if (!is_assignable_types(type
, &type1
))
5116 tcc_error("invalid type for cast");
5121 if (first
|| tok
== '{') {
5130 while (tok
!= '}') {
5131 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
5133 if (!size_only
&& array_length
< index
) {
5134 init_putz(type
, sec
, c
+ array_length
,
5135 index
- array_length
);
5137 index
= index
+ type_size(&f
->type
, &align1
);
5138 if (index
> array_length
)
5139 array_length
= index
;
5141 /* gr: skip fields from same union - ugly. */
5143 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5144 /* test for same offset */
5145 if (f
->next
->c
!= f
->c
)
5147 /* if yes, test for bitfield shift */
5148 if ((f
->type
.t
& VT_BITFIELD
) && (f
->next
->type
.t
& VT_BITFIELD
)) {
5149 int bit_pos_1
= (f
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
5150 int bit_pos_2
= (f
->next
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
5151 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5152 if (bit_pos_1
!= bit_pos_2
)
5159 if (no_oblock
&& f
== NULL
)
5165 /* put zeros at the end */
5166 if (!size_only
&& array_length
< n
) {
5167 init_putz(type
, sec
, c
+ array_length
,
5176 } else if (tok
== '{') {
5178 decl_initializer(type
, sec
, c
, first
, size_only
);
5180 } else if (size_only
) {
5181 /* just skip expression */
5182 parlevel
= parlevel1
= 0;
5183 while ((parlevel
> 0 || parlevel1
> 0 ||
5184 (tok
!= '}' && tok
!= ',')) && tok
!= -1) {
5187 else if (tok
== ')')
5189 else if (tok
== '{')
5191 else if (tok
== '}')
5196 /* currently, we always use constant expression for globals
5197 (may change for scripting case) */
5198 expr_type
= EXPR_CONST
;
5200 expr_type
= EXPR_ANY
;
5201 init_putv(type
, sec
, c
, 0, expr_type
);
5205 /* parse an initializer for type 't' if 'has_init' is non zero, and
5206 allocate space in local or global data space ('r' is either
5207 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5208 variable 'v' with an associated name represented by 'asm_label' of
5209 scope 'scope' is declared before initializers are parsed. If 'v' is
5210 zero, then a reference to the new object is put in the value stack.
5211 If 'has_init' is 2, a special parsing is done to handle string
5213 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
5214 int has_init
, int v
, char *asm_label
,
5217 int size
, align
, addr
, data_offset
;
5219 ParseState saved_parse_state
= {0};
5220 TokenString init_str
;
5222 Sym
*flexible_array
;
5224 flexible_array
= NULL
;
5225 if ((type
->t
& VT_BTYPE
) == VT_STRUCT
) {
5228 while (field
&& field
->next
)
5229 field
= field
->next
;
5230 if (field
->type
.t
& VT_ARRAY
&& field
->type
.ref
->c
< 0)
5231 flexible_array
= field
;
5234 size
= type_size(type
, &align
);
5235 /* If unknown size, we must evaluate it before
5236 evaluating initializers because
5237 initializers can generate global data too
5238 (e.g. string pointers or ISOC99 compound
5239 literals). It also simplifies local
5240 initializers handling */
5241 tok_str_new(&init_str
);
5242 if (size
< 0 || (flexible_array
&& has_init
)) {
5244 tcc_error("unknown type size");
5245 /* get all init string */
5246 if (has_init
== 2) {
5247 /* only get strings */
5248 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5249 tok_str_add_tok(&init_str
);
5254 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
5256 tcc_error("unexpected end of file in initializer");
5257 tok_str_add_tok(&init_str
);
5260 else if (tok
== '}') {
5270 tok_str_add(&init_str
, -1);
5271 tok_str_add(&init_str
, 0);
5274 save_parse_state(&saved_parse_state
);
5276 macro_ptr
= init_str
.str
;
5278 decl_initializer(type
, NULL
, 0, 1, 1);
5279 /* prepare second initializer parsing */
5280 macro_ptr
= init_str
.str
;
5283 /* if still unknown size, error */
5284 size
= type_size(type
, &align
);
5286 tcc_error("unknown type size");
5289 size
+= flexible_array
->type
.ref
->c
* pointed_size(&flexible_array
->type
);
5290 /* take into account specified alignment if bigger */
5292 if (ad
->aligned
> align
)
5293 align
= ad
->aligned
;
5294 } else if (ad
->packed
) {
5297 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
5299 #ifdef CONFIG_TCC_BCHECK
5300 if (tcc_state
->do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
5304 loc
= (loc
- size
) & -align
;
5306 #ifdef CONFIG_TCC_BCHECK
5307 /* handles bounds */
5308 /* XXX: currently, since we do only one pass, we cannot track
5309 '&' operators, so we add only arrays */
5310 if (tcc_state
->do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
5311 unsigned long *bounds_ptr
;
5312 /* add padding between regions */
5314 /* then add local bound info */
5315 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
5316 bounds_ptr
[0] = addr
;
5317 bounds_ptr
[1] = size
;
5321 /* local variable */
5322 sym_push(v
, type
, r
, addr
);
5324 /* push local reference */
5325 vset(type
, r
, addr
);
5331 if (v
&& scope
== VT_CONST
) {
5332 /* see if the symbol was already defined */
5335 if (!is_compatible_types(&sym
->type
, type
))
5336 tcc_error("incompatible types for redefinition of '%s'",
5337 get_tok_str(v
, NULL
));
5338 if (sym
->type
.t
& VT_EXTERN
) {
5339 /* if the variable is extern, it was not allocated */
5340 sym
->type
.t
&= ~VT_EXTERN
;
5341 /* set array size if it was ommited in extern
5343 if ((sym
->type
.t
& VT_ARRAY
) &&
5344 sym
->type
.ref
->c
< 0 &&
5346 sym
->type
.ref
->c
= type
->ref
->c
;
5348 /* we accept several definitions of the same
5349 global variable. this is tricky, because we
5350 must play with the SHN_COMMON type of the symbol */
5351 /* XXX: should check if the variable was already
5352 initialized. It is incorrect to initialized it
5354 /* no init data, we won't add more to the symbol */
5361 /* allocate symbol in corresponding section */
5366 else if (tcc_state
->nocommon
)
5370 data_offset
= sec
->data_offset
;
5371 data_offset
= (data_offset
+ align
- 1) & -align
;
5373 /* very important to increment global pointer at this time
5374 because initializers themselves can create new initializers */
5375 data_offset
+= size
;
5376 #ifdef CONFIG_TCC_BCHECK
5377 /* add padding if bound check */
5378 if (tcc_state
->do_bounds_check
)
5381 sec
->data_offset
= data_offset
;
5382 /* allocate section space to put the data */
5383 if (sec
->sh_type
!= SHT_NOBITS
&&
5384 data_offset
> sec
->data_allocated
)
5385 section_realloc(sec
, data_offset
);
5386 /* align section if needed */
5387 if (align
> sec
->sh_addralign
)
5388 sec
->sh_addralign
= align
;
5390 addr
= 0; /* avoid warning */
5394 if (scope
!= VT_CONST
|| !sym
) {
5395 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
5396 sym
->asm_label
= asm_label
;
5398 /* update symbol definition */
5400 put_extern_sym(sym
, sec
, addr
, size
);
5403 /* put a common area */
5404 put_extern_sym(sym
, NULL
, align
, size
);
5405 /* XXX: find a nicer way */
5406 esym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym
->c
];
5407 esym
->st_shndx
= SHN_COMMON
;
5412 /* push global reference */
5413 sym
= get_sym_ref(type
, sec
, addr
, size
);
5415 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
5418 /* patch symbol weakness */
5419 if (type
->t
& VT_WEAK
)
5421 #ifdef CONFIG_TCC_BCHECK
5422 /* handles bounds now because the symbol must be defined
5423 before for the relocation */
5424 if (tcc_state
->do_bounds_check
) {
5425 unsigned long *bounds_ptr
;
5427 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_PTR
);
5428 /* then add global bound info */
5429 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
5430 bounds_ptr
[0] = 0; /* relocated */
5431 bounds_ptr
[1] = size
;
5435 if (has_init
|| (type
->t
& VT_VLA
)) {
5436 decl_initializer(type
, sec
, addr
, 1, 0);
5437 /* restore parse state if needed */
5439 tok_str_free(init_str
.str
);
5440 restore_parse_state(&saved_parse_state
);
5442 /* patch flexible array member size back to -1, */
5443 /* for possible subsequent similar declarations */
5445 flexible_array
->type
.ref
->c
= -1;
5450 static void put_func_debug(Sym
*sym
)
5455 /* XXX: we put here a dummy type */
5456 snprintf(buf
, sizeof(buf
), "%s:%c1",
5457 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
5458 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
5459 cur_text_section
, sym
->c
);
5460 /* //gr gdb wants a line at the function */
5461 put_stabn(N_SLINE
, 0, file
->line_num
, 0);
5466 /* parse an old style function declaration list */
5467 /* XXX: check multiple parameter */
5468 static void func_decl_list(Sym
*func_sym
)
5475 /* parse each declaration */
5476 while (tok
!= '{' && tok
!= ';' && tok
!= ',' && tok
!= TOK_EOF
&&
5477 tok
!= TOK_ASM1
&& tok
!= TOK_ASM2
&& tok
!= TOK_ASM3
) {
5478 if (!parse_btype(&btype
, &ad
))
5479 expect("declaration list");
5480 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
5481 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
5483 /* we accept no variable after */
5487 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
5488 /* find parameter in function parameter list */
5491 if ((s
->v
& ~SYM_FIELD
) == v
)
5495 tcc_error("declaration for parameter '%s' but no such parameter",
5496 get_tok_str(v
, NULL
));
5498 /* check that no storage specifier except 'register' was given */
5499 if (type
.t
& VT_STORAGE
)
5500 tcc_error("storage class specified for '%s'", get_tok_str(v
, NULL
));
5501 convert_parameter_type(&type
);
5502 /* we can add the type (NOTE: it could be local to the function) */
5504 /* accept other parameters */
5515 /* parse a function defined by symbol 'sym' and generate its code in
5516 'cur_text_section' */
5517 static void gen_function(Sym
*sym
)
5519 int saved_nocode_wanted
= nocode_wanted
;
5521 ind
= cur_text_section
->data_offset
;
5522 /* NOTE: we patch the symbol size later */
5523 put_extern_sym(sym
, cur_text_section
, ind
, 0);
5524 funcname
= get_tok_str(sym
->v
, NULL
);
5526 /* put debug symbol */
5527 if (tcc_state
->do_debug
)
5528 put_func_debug(sym
);
5529 /* push a dummy symbol to enable local sym storage */
5530 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
5531 gfunc_prolog(&sym
->type
);
5533 block(NULL
, NULL
, NULL
, NULL
, 0, 0);
5536 cur_text_section
->data_offset
= ind
;
5537 label_pop(&global_label_stack
, NULL
);
5538 /* reset local stack */
5539 scope_stack_bottom
= NULL
;
5540 sym_pop(&local_stack
, NULL
);
5541 /* end of function */
5542 /* patch symbol size */
5543 ((ElfW(Sym
) *)symtab_section
->data
)[sym
->c
].st_size
=
5545 /* patch symbol weakness (this definition overrules any prototype) */
5546 if (sym
->type
.t
& VT_WEAK
)
5548 if (tcc_state
->do_debug
) {
5549 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
5551 /* It's better to crash than to generate wrong code */
5552 cur_text_section
= NULL
;
5553 funcname
= ""; /* for safety */
5554 func_vt
.t
= VT_VOID
; /* for safety */
5555 ind
= 0; /* for safety */
5556 nocode_wanted
= saved_nocode_wanted
;
5559 ST_FUNC
void gen_inline_functions(void)
5562 int *str
, inline_generated
, i
;
5563 struct InlineFunc
*fn
;
5565 /* iterate while inline function are referenced */
5567 inline_generated
= 0;
5568 for (i
= 0; i
< tcc_state
->nb_inline_fns
; ++i
) {
5569 fn
= tcc_state
->inline_fns
[i
];
5571 if (sym
&& sym
->c
) {
5572 /* the function was used: generate its code and
5573 convert it to a normal function */
5574 str
= fn
->token_str
;
5577 pstrcpy(file
->filename
, sizeof file
->filename
, fn
->filename
);
5578 sym
->r
= VT_SYM
| VT_CONST
;
5579 sym
->type
.t
&= ~VT_INLINE
;
5583 cur_text_section
= text_section
;
5585 macro_ptr
= NULL
; /* fail safe */
5587 inline_generated
= 1;
5590 if (!inline_generated
)
5593 for (i
= 0; i
< tcc_state
->nb_inline_fns
; ++i
) {
5594 fn
= tcc_state
->inline_fns
[i
];
5595 str
= fn
->token_str
;
5598 dynarray_reset(&tcc_state
->inline_fns
, &tcc_state
->nb_inline_fns
);
5601 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5602 static int decl0(int l
, int is_for_loop_init
)
5610 if (!parse_btype(&btype
, &ad
)) {
5611 if (is_for_loop_init
)
5613 /* skip redundant ';' */
5614 /* XXX: find more elegant solution */
5619 if (l
== VT_CONST
&&
5620 (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
5621 /* global asm block */
5625 /* special test for old K&R protos without explicit int
5626 type. Only accepted when defining global data */
5627 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
5631 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
5632 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
5634 /* we accept no variable after */
5638 while (1) { /* iterate thru each declaration */
5639 char *asm_label
; // associated asm label
5641 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
5645 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
5646 printf("type = '%s'\n", buf
);
5649 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
5650 if ((type
.t
& VT_STATIC
) && (l
== VT_LOCAL
)) {
5651 tcc_error("function without file scope cannot be static");
5653 /* if old style function prototype, we accept a
5656 if (sym
->c
== FUNC_OLD
)
5657 func_decl_list(sym
);
5661 if (gnu_ext
&& (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
5664 asm_label_instr(&astr
);
5665 asm_label
= tcc_strdup(astr
.data
);
5668 /* parse one last attribute list, after asm label */
5669 parse_attribute(&ad
);
5674 #ifdef TCC_TARGET_PE
5676 type
.t
|= VT_IMPORT
;
5678 type
.t
|= VT_EXPORT
;
5682 tcc_error("cannot use local functions");
5683 if ((type
.t
& VT_BTYPE
) != VT_FUNC
)
5684 expect("function definition");
5686 /* reject abstract declarators in function definition */
5688 while ((sym
= sym
->next
) != NULL
)
5689 if (!(sym
->v
& ~SYM_FIELD
))
5690 expect("identifier");
5692 /* XXX: cannot do better now: convert extern line to static inline */
5693 if ((type
.t
& (VT_EXTERN
| VT_INLINE
)) == (VT_EXTERN
| VT_INLINE
))
5694 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
5698 if ((sym
->type
.t
& VT_BTYPE
) != VT_FUNC
)
5701 r
= sym
->type
.ref
->r
;
5702 /* use func_call from prototype if not defined */
5703 if (FUNC_CALL(r
) != FUNC_CDECL
5704 && FUNC_CALL(type
.ref
->r
) == FUNC_CDECL
)
5705 FUNC_CALL(type
.ref
->r
) = FUNC_CALL(r
);
5707 /* use export from prototype */
5709 FUNC_EXPORT(type
.ref
->r
) = 1;
5711 /* use static from prototype */
5712 if (sym
->type
.t
& VT_STATIC
)
5713 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
5715 if (!is_compatible_types(&sym
->type
, &type
)) {
5717 tcc_error("incompatible types for redefinition of '%s'",
5718 get_tok_str(v
, NULL
));
5720 /* if symbol is already defined, then put complete type */
5723 /* put function symbol */
5724 sym
= global_identifier_push(v
, type
.t
, 0);
5725 sym
->type
.ref
= type
.ref
;
5728 /* static inline functions are just recorded as a kind
5729 of macro. Their code will be emitted at the end of
5730 the compilation unit only if they are used */
5731 if ((type
.t
& (VT_INLINE
| VT_STATIC
)) ==
5732 (VT_INLINE
| VT_STATIC
)) {
5733 TokenString func_str
;
5735 struct InlineFunc
*fn
;
5736 const char *filename
;
5738 tok_str_new(&func_str
);
5744 tcc_error("unexpected end of file");
5745 tok_str_add_tok(&func_str
);
5750 } else if (t
== '}') {
5752 if (block_level
== 0)
5756 tok_str_add(&func_str
, -1);
5757 tok_str_add(&func_str
, 0);
5758 filename
= file
? file
->filename
: "";
5759 fn
= tcc_malloc(sizeof *fn
+ strlen(filename
));
5760 strcpy(fn
->filename
, filename
);
5762 fn
->token_str
= func_str
.str
;
5763 dynarray_add((void ***)&tcc_state
->inline_fns
, &tcc_state
->nb_inline_fns
, fn
);
5766 /* compute text section */
5767 cur_text_section
= ad
.section
;
5768 if (!cur_text_section
)
5769 cur_text_section
= text_section
;
5770 sym
->r
= VT_SYM
| VT_CONST
;
5775 if (btype
.t
& VT_TYPEDEF
) {
5776 /* save typedefed type */
5777 /* XXX: test storage specifiers ? */
5778 sym
= sym_push(v
, &type
, INT_ATTR(&ad
), 0);
5779 sym
->type
.t
|= VT_TYPEDEF
;
5782 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
5783 /* external function definition */
5784 /* specific case for func_call attribute */
5785 type
.ref
->r
= INT_ATTR(&ad
);
5786 } else if (!(type
.t
& VT_ARRAY
)) {
5787 /* not lvalue if array */
5788 r
|= lvalue_type(type
.t
);
5790 has_init
= (tok
== '=');
5791 if (has_init
&& (type
.t
& VT_VLA
))
5792 tcc_error("Variable length array cannot be initialized");
5793 if ((btype
.t
& VT_EXTERN
) || ((type
.t
& VT_BTYPE
) == VT_FUNC
) ||
5794 ((type
.t
& VT_ARRAY
) && (type
.t
& VT_STATIC
) &&
5795 !has_init
&& l
== VT_CONST
&& type
.ref
->c
< 0)) {
5796 /* external variable or function */
5797 /* NOTE: as GCC, uninitialized global static
5798 arrays of null size are considered as
5800 sym
= external_sym(v
, &type
, r
, asm_label
);
5802 if (type
.t
& VT_WEAK
)
5805 if (ad
.alias_target
) {
5810 alias_target
= sym_find(ad
.alias_target
);
5811 if (!alias_target
|| !alias_target
->c
)
5812 tcc_error("unsupported forward __alias__ attribute");
5813 esym
= &((Elf32_Sym
*)symtab_section
->data
)[alias_target
->c
];
5814 tsec
.sh_num
= esym
->st_shndx
;
5815 put_extern_sym2(sym
, &tsec
, esym
->st_value
, esym
->st_size
, 0);
5818 type
.t
|= (btype
.t
& VT_STATIC
); /* Retain "static". */
5819 if (type
.t
& VT_STATIC
)
5825 decl_initializer_alloc(&type
, &ad
, r
, has_init
, v
, asm_label
, l
);
5829 if (is_for_loop_init
)
5842 ST_FUNC
void decl(int l
)