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
int vla_sp_loc_tmp
; /* vla_sp_loc is set to this when the value won't be needed later */
59 ST_DATA
int vla_sp_root_loc
; /* vla_sp_loc for SP before any VLAs were pushed */
60 ST_DATA
int *vla_sp_loc
; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
61 ST_DATA
int vla_flags
; /* VLA_* flags */
63 ST_DATA SValue __vstack
[1+VSTACK_SIZE
], *vtop
;
65 ST_DATA
int const_wanted
; /* true if constant wanted */
66 ST_DATA
int nocode_wanted
; /* true if no code generation wanted for an expression */
67 ST_DATA
int global_expr
; /* true if compound literals must be allocated globally (used during initializers parsing */
68 ST_DATA CType func_vt
; /* current function return type (used by return instruction) */
69 ST_DATA
int func_var
; /* true if current function is variadic (used by return instruction) */
71 ST_DATA
int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
72 ST_DATA
char *funcname
;
74 ST_DATA CType char_pointer_type
, func_old_type
, int_type
, size_type
;
76 /* ------------------------------------------------------------------------- */
77 static void gen_cast(CType
*type
);
78 static inline CType
*pointed_type(CType
*type
);
79 static int is_compatible_types(CType
*type1
, CType
*type2
);
80 static int parse_btype(CType
*type
, AttributeDef
*ad
);
81 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
82 static void parse_expr_type(CType
*type
);
83 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
, int first
, int size_only
);
84 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
, int is_expr
);
85 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
, int has_init
, int v
, char *asm_label
, int scope
);
86 static int decl0(int l
, int is_for_loop_init
);
87 static void expr_eq(void);
88 static void unary_type(CType
*type
);
89 static void vla_runtime_type_size(CType
*type
, int *a
);
90 static void vla_sp_save(void);
91 static int is_compatible_parameter_types(CType
*type1
, CType
*type2
);
92 static void expr_type(CType
*type
);
93 ST_FUNC
void vpush64(int ty
, unsigned long long v
);
94 ST_FUNC
void vpush(CType
*type
);
95 ST_FUNC
int gvtst(int inv
, int t
);
96 ST_FUNC
int is_btype_size(int bt
);
98 ST_INLN
int is_float(int t
)
102 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
|| bt
== VT_QFLOAT
;
105 /* we use our own 'finite' function to avoid potential problems with
106 non standard math libs */
107 /* XXX: endianness dependent */
108 ST_FUNC
int ieee_finite(double d
)
111 memcpy(p
, &d
, sizeof(double));
112 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
115 ST_FUNC
void test_lvalue(void)
117 if (!(vtop
->r
& VT_LVAL
))
121 /* ------------------------------------------------------------------------- */
122 /* symbol allocator */
123 static Sym
*__sym_malloc(void)
125 Sym
*sym_pool
, *sym
, *last_sym
;
128 sym_pool
= tcc_malloc(SYM_POOL_NB
* sizeof(Sym
));
129 dynarray_add(&sym_pools
, &nb_sym_pools
, sym_pool
);
131 last_sym
= sym_free_first
;
133 for(i
= 0; i
< SYM_POOL_NB
; i
++) {
134 sym
->next
= last_sym
;
138 sym_free_first
= last_sym
;
142 static inline Sym
*sym_malloc(void)
145 sym
= sym_free_first
;
147 sym
= __sym_malloc();
148 sym_free_first
= sym
->next
;
152 ST_INLN
void sym_free(Sym
*sym
)
154 sym
->next
= sym_free_first
;
155 sym_free_first
= sym
;
158 /* push, without hashing */
159 ST_FUNC Sym
*sym_push2(Sym
**ps
, int v
, int t
, long c
)
162 if (ps
== &local_stack
) {
163 for (s
= *ps
; s
&& s
!= scope_stack_bottom
; s
= s
->prev
)
164 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
&& s
->v
== v
)
165 tcc_error("incompatible types for redefinition of '%s'",
166 get_tok_str(v
, NULL
));
184 /* find a symbol and return its associated structure. 's' is the top
185 of the symbol stack */
186 ST_FUNC Sym
*sym_find2(Sym
*s
, int v
)
198 /* structure lookup */
199 ST_INLN Sym
*struct_find(int v
)
202 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
204 return table_ident
[v
]->sym_struct
;
207 /* find an identifier */
208 ST_INLN Sym
*sym_find(int v
)
211 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
213 return table_ident
[v
]->sym_identifier
;
216 /* push a given symbol on the symbol stack */
217 ST_FUNC Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
226 s
= sym_push2(ps
, v
, type
->t
, c
);
227 s
->type
.ref
= type
->ref
;
229 /* don't record fields or anonymous symbols */
231 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
232 /* record symbol in token array */
233 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
235 ps
= &ts
->sym_struct
;
237 ps
= &ts
->sym_identifier
;
244 /* push a global identifier */
245 ST_FUNC Sym
*global_identifier_push(int v
, int t
, int c
)
248 s
= sym_push2(&global_stack
, v
, t
, c
);
249 /* don't record anonymous symbol */
250 if (v
< SYM_FIRST_ANOM
) {
251 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
252 /* modify the top most local identifier, so that
253 sym_identifier will point to 's' when popped */
255 ps
= &(*ps
)->prev_tok
;
262 /* pop symbols until top reaches 'b' */
263 ST_FUNC
void sym_pop(Sym
**ptop
, Sym
*b
)
273 /* remove symbol in token array */
275 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
276 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
278 ps
= &ts
->sym_struct
;
280 ps
= &ts
->sym_identifier
;
289 static void weaken_symbol(Sym
*sym
)
291 sym
->type
.t
|= VT_WEAK
;
296 esym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym
->c
];
297 esym_type
= ELFW(ST_TYPE
)(esym
->st_info
);
298 esym
->st_info
= ELFW(ST_INFO
)(STB_WEAK
, esym_type
);
302 static void apply_visibility(Sym
*sym
, CType
*type
)
304 int vis
= sym
->type
.t
& VT_VIS_MASK
;
305 int vis2
= type
->t
& VT_VIS_MASK
;
306 if (vis
== (STV_DEFAULT
<< VT_VIS_SHIFT
))
308 else if (vis2
== (STV_DEFAULT
<< VT_VIS_SHIFT
))
311 vis
= (vis
< vis2
) ? vis
: vis2
;
312 sym
->type
.t
&= ~VT_VIS_MASK
;
318 esym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym
->c
];
319 vis
>>= VT_VIS_SHIFT
;
320 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1)) | vis
;
324 /* ------------------------------------------------------------------------- */
326 ST_FUNC
void swap(int *p
, int *q
)
334 static void vsetc(CType
*type
, int r
, CValue
*vc
)
338 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
339 tcc_error("memory full (vstack)");
340 /* cannot let cpu flags if other instruction are generated. Also
341 avoid leaving VT_JMP anywhere except on the top of the stack
342 because it would complicate the code generator. */
343 if (vtop
>= vstack
) {
344 v
= vtop
->r
& VT_VALMASK
;
345 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
355 /* push constant of type "type" with useless value */
356 ST_FUNC
void vpush(CType
*type
)
359 vsetc(type
, VT_CONST
, &cval
);
362 /* push integer constant */
363 ST_FUNC
void vpushi(int v
)
367 vsetc(&int_type
, VT_CONST
, &cval
);
370 /* push a pointer sized constant */
371 static void vpushs(addr_t v
)
375 vsetc(&size_type
, VT_CONST
, &cval
);
378 /* push arbitrary 64bit constant */
379 ST_FUNC
void vpush64(int ty
, unsigned long long v
)
386 vsetc(&ctype
, VT_CONST
, &cval
);
389 /* push long long constant */
390 static inline void vpushll(long long v
)
392 vpush64(VT_LLONG
, v
);
395 /* push a symbol value of TYPE */
396 static inline void vpushsym(CType
*type
, Sym
*sym
)
400 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
404 /* Return a static symbol pointing to a section */
405 ST_FUNC Sym
*get_sym_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
411 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
412 sym
->type
.ref
= type
->ref
;
413 sym
->r
= VT_CONST
| VT_SYM
;
414 put_extern_sym(sym
, sec
, offset
, size
);
418 /* push a reference to a section offset by adding a dummy symbol */
419 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
421 vpushsym(type
, get_sym_ref(type
, sec
, offset
, size
));
424 /* define a new external reference to a symbol 'v' of type 'u' */
425 ST_FUNC Sym
*external_global_sym(int v
, CType
*type
, int r
)
431 /* push forward reference */
432 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
433 s
->type
.ref
= type
->ref
;
434 s
->r
= r
| VT_CONST
| VT_SYM
;
439 /* define a new external reference to a symbol 'v' with alternate asm
440 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
441 is no alternate name (most cases) */
442 static Sym
*external_sym(int v
, CType
*type
, int r
, char *asm_label
)
448 /* push forward reference */
449 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
450 s
->asm_label
= asm_label
;
451 s
->type
.t
|= VT_EXTERN
;
452 } else if (s
->type
.ref
== func_old_type
.ref
) {
453 s
->type
.ref
= type
->ref
;
454 s
->r
= r
| VT_CONST
| VT_SYM
;
455 s
->type
.t
|= VT_EXTERN
;
456 } else if (!is_compatible_types(&s
->type
, type
)) {
457 tcc_error("incompatible types for redefinition of '%s'",
458 get_tok_str(v
, NULL
));
460 /* Merge some storage attributes. */
461 if (type
->t
& VT_WEAK
)
464 if (type
->t
& VT_VIS_MASK
)
465 apply_visibility(s
, type
);
470 /* push a reference to global symbol v */
471 ST_FUNC
void vpush_global_sym(CType
*type
, int v
)
473 vpushsym(type
, external_global_sym(v
, type
, 0));
476 ST_FUNC
void vset(CType
*type
, int r
, int v
)
481 vsetc(type
, r
, &cval
);
484 static void vseti(int r
, int v
)
492 ST_FUNC
void vswap(void)
495 /* cannot let cpu flags if other instruction are generated. Also
496 avoid leaving VT_JMP anywhere except on the top of the stack
497 because it would complicate the code generator. */
498 if (vtop
>= vstack
) {
499 int v
= vtop
->r
& VT_VALMASK
;
500 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
507 /* XXX: +2% overall speed possible with optimized memswap
509 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
513 ST_FUNC
void vpushv(SValue
*v
)
515 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
516 tcc_error("memory full (vstack)");
521 static void vdup(void)
526 /* save r to the memory stack, and mark it as being free */
527 ST_FUNC
void save_reg(int r
)
529 int l
, saved
, size
, align
;
533 /* modify all stack values */
536 for(p
=vstack
;p
<=vtop
;p
++) {
537 if ((p
->r
& VT_VALMASK
) == r
||
538 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& (p
->r2
& VT_VALMASK
) == r
)) {
539 /* must save value on stack if not already done */
541 /* NOTE: must reload 'r' because r might be equal to r2 */
542 r
= p
->r
& VT_VALMASK
;
543 /* store register in the stack */
545 if ((p
->r
& VT_LVAL
) ||
546 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
547 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
548 type
= &char_pointer_type
;
552 size
= type_size(type
, &align
);
553 loc
= (loc
- size
) & -align
;
555 sv
.r
= VT_LOCAL
| VT_LVAL
;
558 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
559 /* x86 specific: need to pop fp register ST0 if saved */
561 o(0xd8dd); /* fstp %st(0) */
564 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
565 /* special long long case */
566 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
574 /* mark that stack entry as being saved on the stack */
575 if (p
->r
& VT_LVAL
) {
576 /* also clear the bounded flag because the
577 relocation address of the function was stored in
579 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
581 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
589 #ifdef TCC_TARGET_ARM
590 /* find a register of class 'rc2' with at most one reference on stack.
591 * If none, call get_reg(rc) */
592 ST_FUNC
int get_reg_ex(int rc
, int rc2
)
597 for(r
=0;r
<NB_REGS
;r
++) {
598 if (reg_classes
[r
] & rc2
) {
601 for(p
= vstack
; p
<= vtop
; p
++) {
602 if ((p
->r
& VT_VALMASK
) == r
||
603 (p
->r2
& VT_VALMASK
) == r
)
614 /* find a free register of class 'rc'. If none, save one register */
615 ST_FUNC
int get_reg(int rc
)
620 /* find a free register */
621 for(r
=0;r
<NB_REGS
;r
++) {
622 if (reg_classes
[r
] & rc
) {
623 for(p
=vstack
;p
<=vtop
;p
++) {
624 if ((p
->r
& VT_VALMASK
) == r
||
625 (p
->r2
& VT_VALMASK
) == r
)
633 /* no register left : free the first one on the stack (VERY
634 IMPORTANT to start from the bottom to ensure that we don't
635 spill registers used in gen_opi()) */
636 for(p
=vstack
;p
<=vtop
;p
++) {
637 /* look at second register (if long long) */
638 r
= p
->r2
& VT_VALMASK
;
639 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
641 r
= p
->r
& VT_VALMASK
;
642 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
648 /* Should never comes here */
652 /* save registers up to (vtop - n) stack entry */
653 ST_FUNC
void save_regs(int n
)
658 for(p
= vstack
;p
<= p1
; p
++) {
659 r
= p
->r
& VT_VALMASK
;
666 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
668 static void move_reg(int r
, int s
, int t
)
682 /* get address of vtop (vtop MUST BE an lvalue) */
683 ST_FUNC
void gaddrof(void)
685 if (vtop
->r
& VT_REF
&& !nocode_wanted
)
688 /* tricky: if saved lvalue, then we can go back to lvalue */
689 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
690 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
695 #ifdef CONFIG_TCC_BCHECK
696 /* generate lvalue bound code */
697 static void gbound(void)
702 vtop
->r
&= ~VT_MUSTBOUND
;
703 /* if lvalue, then use checking code before dereferencing */
704 if (vtop
->r
& VT_LVAL
) {
705 /* if not VT_BOUNDED value, then make one */
706 if (!(vtop
->r
& VT_BOUNDED
)) {
707 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
708 /* must save type because we must set it to int to get pointer */
710 vtop
->type
.t
= VT_PTR
;
713 gen_bounded_ptr_add();
714 vtop
->r
|= lval_type
;
717 /* then check for dereferencing */
718 gen_bounded_ptr_deref();
723 /* store vtop a register belonging to class 'rc'. lvalues are
724 converted to values. Cannot be used if cannot be converted to
725 register value (such as structures). */
726 ST_FUNC
int gv(int rc
)
728 int r
, bit_pos
, bit_size
, size
, align
, i
;
731 /* NOTE: get_reg can modify vstack[] */
732 if (vtop
->type
.t
& VT_BITFIELD
) {
735 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
736 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
737 /* remove bit field info to avoid loops */
738 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
739 /* cast to int to propagate signedness in following ops */
740 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
745 if((vtop
->type
.t
& VT_UNSIGNED
) ||
746 (vtop
->type
.t
& VT_BTYPE
) == VT_BOOL
)
747 type
.t
|= VT_UNSIGNED
;
749 /* generate shifts */
750 vpushi(bits
- (bit_pos
+ bit_size
));
752 vpushi(bits
- bit_size
);
753 /* NOTE: transformed to SHR if unsigned */
757 if (is_float(vtop
->type
.t
) &&
758 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
761 unsigned long offset
;
762 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
766 /* XXX: unify with initializers handling ? */
767 /* CPUs usually cannot use float constants, so we store them
768 generically in data segment */
769 size
= type_size(&vtop
->type
, &align
);
770 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
771 data_section
->data_offset
= offset
;
772 /* XXX: not portable yet */
773 #if defined(__i386__) || defined(__x86_64__)
774 /* Zero pad x87 tenbyte long doubles */
775 if (size
== LDOUBLE_SIZE
) {
776 vtop
->c
.tab
[2] &= 0xffff;
777 #if LDOUBLE_SIZE == 16
782 ptr
= section_ptr_add(data_section
, size
);
784 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
788 ptr
[i
] = vtop
->c
.tab
[size
-1-i
];
792 ptr
[i
] = vtop
->c
.tab
[i
];
793 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
794 vtop
->r
|= VT_LVAL
| VT_SYM
;
796 vtop
->c
.ptr_offset
= 0;
798 #ifdef CONFIG_TCC_BCHECK
799 if (vtop
->r
& VT_MUSTBOUND
)
803 r
= vtop
->r
& VT_VALMASK
;
804 rc2
= (rc
& RC_FLOAT
) ? RC_FLOAT
: RC_INT
;
805 #ifndef TCC_TARGET_ARM64
808 #ifdef TCC_TARGET_X86_64
809 else if (rc
== RC_FRET
)
814 /* need to reload if:
816 - lvalue (need to dereference pointer)
817 - already a register, but not in the right class */
819 || (vtop
->r
& VT_LVAL
)
820 || !(reg_classes
[r
] & rc
)
821 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
822 || ((vtop
->type
.t
& VT_BTYPE
) == VT_QLONG
&& !(reg_classes
[vtop
->r2
] & rc2
))
823 || ((vtop
->type
.t
& VT_BTYPE
) == VT_QFLOAT
&& !(reg_classes
[vtop
->r2
] & rc2
))
825 || ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&& !(reg_classes
[vtop
->r2
] & rc2
))
830 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
831 if (((vtop
->type
.t
& VT_BTYPE
) == VT_QLONG
) || ((vtop
->type
.t
& VT_BTYPE
) == VT_QFLOAT
)) {
832 int addr_type
= VT_LLONG
, load_size
= 8, load_type
= ((vtop
->type
.t
& VT_BTYPE
) == VT_QLONG
) ? VT_LLONG
: VT_DOUBLE
;
834 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
835 int addr_type
= VT_INT
, load_size
= 4, load_type
= VT_INT
;
836 unsigned long long ll
;
838 int r2
, original_type
;
839 original_type
= vtop
->type
.t
;
840 /* two register type load : expand to two words
842 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
843 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
846 vtop
->c
.ui
= ll
; /* first word */
848 vtop
->r
= r
; /* save register value */
849 vpushi(ll
>> 32); /* second word */
852 if (r
>= VT_CONST
|| /* XXX: test to VT_CONST incorrect ? */
853 (vtop
->r
& VT_LVAL
)) {
854 /* We do not want to modifier the long long
855 pointer here, so the safest (and less
856 efficient) is to save all the other registers
857 in the stack. XXX: totally inefficient. */
859 /* load from memory */
860 vtop
->type
.t
= load_type
;
863 vtop
[-1].r
= r
; /* save register value */
864 /* increment pointer to get second word */
865 vtop
->type
.t
= addr_type
;
870 vtop
->type
.t
= load_type
;
875 vtop
[-1].r
= r
; /* save register value */
876 vtop
->r
= vtop
[-1].r2
;
878 /* Allocate second register. Here we rely on the fact that
879 get_reg() tries first to free r2 of an SValue. */
883 /* write second register */
885 vtop
->type
.t
= original_type
;
886 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
888 /* lvalue of scalar type : need to use lvalue type
889 because of possible cast */
892 /* compute memory access type */
893 if (vtop
->r
& VT_REF
)
894 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
899 else if (vtop
->r
& VT_LVAL_BYTE
)
901 else if (vtop
->r
& VT_LVAL_SHORT
)
903 if (vtop
->r
& VT_LVAL_UNSIGNED
)
907 /* restore wanted type */
910 /* one register type load */
915 #ifdef TCC_TARGET_C67
916 /* uses register pairs for doubles */
917 if ((vtop
->type
.t
& VT_BTYPE
) == VT_DOUBLE
)
924 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
925 ST_FUNC
void gv2(int rc1
, int rc2
)
929 /* generate more generic register first. But VT_JMP or VT_CMP
930 values must be generated first in all cases to avoid possible
932 v
= vtop
[0].r
& VT_VALMASK
;
933 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
938 /* test if reload is needed for first register */
939 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
949 /* test if reload is needed for first register */
950 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
956 #ifndef TCC_TARGET_ARM64
957 /* wrapper around RC_FRET to return a register by type */
958 static int rc_fret(int t
)
960 #ifdef TCC_TARGET_X86_64
961 if (t
== VT_LDOUBLE
) {
969 /* wrapper around REG_FRET to return a register by type */
970 static int reg_fret(int t
)
972 #ifdef TCC_TARGET_X86_64
973 if (t
== VT_LDOUBLE
) {
980 /* expand long long on stack in two int registers */
981 static void lexpand(void)
985 u
= vtop
->type
.t
& (VT_DEFSIGN
| VT_UNSIGNED
);
988 vtop
[0].r
= vtop
[-1].r2
;
989 vtop
[0].r2
= VT_CONST
;
990 vtop
[-1].r2
= VT_CONST
;
991 vtop
[0].type
.t
= VT_INT
| u
;
992 vtop
[-1].type
.t
= VT_INT
| u
;
995 #ifdef TCC_TARGET_ARM
996 /* expand long long on stack */
997 ST_FUNC
void lexpand_nr(void)
1001 u
= vtop
->type
.t
& (VT_DEFSIGN
| VT_UNSIGNED
);
1003 vtop
->r2
= VT_CONST
;
1004 vtop
->type
.t
= VT_INT
| u
;
1005 v
=vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
);
1006 if (v
== VT_CONST
) {
1007 vtop
[-1].c
.ui
= vtop
->c
.ull
;
1008 vtop
->c
.ui
= vtop
->c
.ull
>> 32;
1010 } else if (v
== (VT_LVAL
|VT_CONST
) || v
== (VT_LVAL
|VT_LOCAL
)) {
1012 vtop
->r
= vtop
[-1].r
;
1013 } else if (v
> VT_CONST
) {
1017 vtop
->r
= vtop
[-1].r2
;
1018 vtop
[-1].r2
= VT_CONST
;
1019 vtop
[-1].type
.t
= VT_INT
| u
;
1023 /* build a long long from two ints */
1024 static void lbuild(int t
)
1026 gv2(RC_INT
, RC_INT
);
1027 vtop
[-1].r2
= vtop
[0].r
;
1028 vtop
[-1].type
.t
= t
;
1032 /* rotate n first stack elements to the bottom
1033 I1 ... In -> I2 ... In I1 [top is right]
1035 ST_FUNC
void vrotb(int n
)
1041 for(i
=-n
+1;i
!=0;i
++)
1042 vtop
[i
] = vtop
[i
+1];
1046 /* rotate the n elements before entry e towards the top
1047 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1049 ST_FUNC
void vrote(SValue
*e
, int n
)
1055 for(i
= 0;i
< n
- 1; i
++)
1060 /* rotate n first stack elements to the top
1061 I1 ... In -> In I1 ... I(n-1) [top is right]
1063 ST_FUNC
void vrott(int n
)
1068 /* pop stack value */
1069 ST_FUNC
void vpop(void)
1072 v
= vtop
->r
& VT_VALMASK
;
1073 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1074 /* for x86, we need to pop the FP stack */
1075 if (v
== TREG_ST0
&& !nocode_wanted
) {
1076 o(0xd8dd); /* fstp %st(0) */
1079 if (v
== VT_JMP
|| v
== VT_JMPI
) {
1080 /* need to put correct jump if && or || without test */
1086 /* convert stack entry to register and duplicate its value in another
1088 static void gv_dup(void)
1094 if ((t
& VT_BTYPE
) == VT_LLONG
) {
1101 /* stack: H L L1 H1 */
1109 /* duplicate value */
1114 #ifdef TCC_TARGET_X86_64
1115 if ((t
& VT_BTYPE
) == VT_LDOUBLE
) {
1125 load(r1
, &sv
); /* move r to r1 */
1127 /* duplicates value */
1133 /* Generate value test
1135 * Generate a test for any value (jump, comparison and integers) */
1136 ST_FUNC
int gvtst(int inv
, int t
)
1138 int v
= vtop
->r
& VT_VALMASK
;
1139 if (v
!= VT_CMP
&& v
!= VT_JMP
&& v
!= VT_JMPI
) {
1143 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
1144 /* constant jmp optimization */
1145 if ((vtop
->c
.i
!= 0) != inv
)
1150 return gtst(inv
, t
);
1153 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
1154 /* generate CPU independent (unsigned) long long operations */
1155 static void gen_opl(int op
)
1157 int t
, a
, b
, op1
, c
, i
;
1159 unsigned short reg_iret
= REG_IRET
;
1160 unsigned short reg_lret
= REG_LRET
;
1166 func
= TOK___divdi3
;
1169 func
= TOK___udivdi3
;
1172 func
= TOK___moddi3
;
1175 func
= TOK___umoddi3
;
1182 /* call generic long long function */
1183 vpush_global_sym(&func_old_type
, func
);
1188 vtop
->r2
= reg_lret
;
1201 /* stack: L1 H1 L2 H2 */
1206 vtop
[-2] = vtop
[-3];
1209 /* stack: H1 H2 L1 L2 */
1215 /* stack: H1 H2 L1 L2 ML MH */
1218 /* stack: ML MH H1 H2 L1 L2 */
1222 /* stack: ML MH H1 L2 H2 L1 */
1227 /* stack: ML MH M1 M2 */
1230 } else if (op
== '+' || op
== '-') {
1231 /* XXX: add non carry method too (for MIPS or alpha) */
1237 /* stack: H1 H2 (L1 op L2) */
1240 gen_op(op1
+ 1); /* TOK_xxxC2 */
1243 /* stack: H1 H2 (L1 op L2) */
1246 /* stack: (L1 op L2) H1 H2 */
1248 /* stack: (L1 op L2) (H1 op H2) */
1256 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
1257 t
= vtop
[-1].type
.t
;
1261 /* stack: L H shift */
1263 /* constant: simpler */
1264 /* NOTE: all comments are for SHL. the other cases are
1265 done by swaping words */
1276 if (op
!= TOK_SAR
) {
1309 /* XXX: should provide a faster fallback on x86 ? */
1312 func
= TOK___ashrdi3
;
1315 func
= TOK___lshrdi3
;
1318 func
= TOK___ashldi3
;
1324 /* compare operations */
1330 /* stack: L1 H1 L2 H2 */
1332 vtop
[-1] = vtop
[-2];
1334 /* stack: L1 L2 H1 H2 */
1337 /* when values are equal, we need to compare low words. since
1338 the jump is inverted, we invert the test too. */
1341 else if (op1
== TOK_GT
)
1343 else if (op1
== TOK_ULT
)
1345 else if (op1
== TOK_UGT
)
1350 if (op1
!= TOK_NE
) {
1354 /* generate non equal test */
1355 /* XXX: NOT PORTABLE yet */
1359 #if defined(TCC_TARGET_I386)
1360 b
= psym(0x850f, 0);
1361 #elif defined(TCC_TARGET_ARM)
1363 o(0x1A000000 | encbranch(ind
, 0, 1));
1364 #elif defined(TCC_TARGET_C67) || defined(TCC_TARGET_ARM64)
1365 tcc_error("not implemented");
1367 #error not supported
1371 /* compare low. Always unsigned */
1375 else if (op1
== TOK_LE
)
1377 else if (op1
== TOK_GT
)
1379 else if (op1
== TOK_GE
)
1390 /* handle integer constant optimizations and various machine
1392 static void gen_opic(int op
)
1394 int c1
, c2
, t1
, t2
, n
;
1397 typedef unsigned long long U
;
1401 t1
= v1
->type
.t
& VT_BTYPE
;
1402 t2
= v2
->type
.t
& VT_BTYPE
;
1406 else if (v1
->type
.t
& VT_UNSIGNED
)
1413 else if (v2
->type
.t
& VT_UNSIGNED
)
1418 /* currently, we cannot do computations with forward symbols */
1419 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1420 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1423 case '+': l1
+= l2
; break;
1424 case '-': l1
-= l2
; break;
1425 case '&': l1
&= l2
; break;
1426 case '^': l1
^= l2
; break;
1427 case '|': l1
|= l2
; break;
1428 case '*': l1
*= l2
; break;
1435 /* if division by zero, generate explicit division */
1438 tcc_error("division by zero in constant");
1442 default: l1
/= l2
; break;
1443 case '%': l1
%= l2
; break;
1444 case TOK_UDIV
: l1
= (U
)l1
/ l2
; break;
1445 case TOK_UMOD
: l1
= (U
)l1
% l2
; break;
1448 case TOK_SHL
: l1
<<= l2
; break;
1449 case TOK_SHR
: l1
= (U
)l1
>> l2
; break;
1450 case TOK_SAR
: l1
>>= l2
; break;
1452 case TOK_ULT
: l1
= (U
)l1
< (U
)l2
; break;
1453 case TOK_UGE
: l1
= (U
)l1
>= (U
)l2
; break;
1454 case TOK_EQ
: l1
= l1
== l2
; break;
1455 case TOK_NE
: l1
= l1
!= l2
; break;
1456 case TOK_ULE
: l1
= (U
)l1
<= (U
)l2
; break;
1457 case TOK_UGT
: l1
= (U
)l1
> (U
)l2
; break;
1458 case TOK_LT
: l1
= l1
< l2
; break;
1459 case TOK_GE
: l1
= l1
>= l2
; break;
1460 case TOK_LE
: l1
= l1
<= l2
; break;
1461 case TOK_GT
: l1
= l1
> l2
; break;
1463 case TOK_LAND
: l1
= l1
&& l2
; break;
1464 case TOK_LOR
: l1
= l1
|| l2
; break;
1471 /* if commutative ops, put c2 as constant */
1472 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
1473 op
== '|' || op
== '*')) {
1475 c2
= c1
; //c = c1, c1 = c2, c2 = c;
1476 l2
= l1
; //l = l1, l1 = l2, l2 = l;
1478 if (!const_wanted
&&
1480 (op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
)) ||
1481 (l1
== -1 && op
== TOK_SAR
))) {
1482 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
1484 } else if (!const_wanted
&&
1485 c2
&& ((l2
== 0 && (op
== '&' || op
== '*')) ||
1486 (l2
== -1 && op
== '|') ||
1487 (l2
== 0xffffffff && t2
!= VT_LLONG
&& op
== '|') ||
1488 (l2
== 1 && (op
== '%' || op
== TOK_UMOD
)))) {
1489 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
1494 } else if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
1497 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
1498 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
1502 /* filter out NOP operations like x*1, x-0, x&-1... */
1504 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
1505 /* try to use shifts instead of muls or divs */
1506 if (l2
> 0 && (l2
& (l2
- 1)) == 0) {
1515 else if (op
== TOK_PDIV
)
1521 } else if (c2
&& (op
== '+' || op
== '-') &&
1522 (((vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == (VT_CONST
| VT_SYM
))
1523 || (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
)) == VT_LOCAL
)) {
1524 /* symbol + constant case */
1531 if (!nocode_wanted
) {
1532 /* call low level op generator */
1533 if (t1
== VT_LLONG
|| t2
== VT_LLONG
||
1534 (PTR_SIZE
== 8 && (t1
== VT_PTR
|| t2
== VT_PTR
)))
1545 /* generate a floating point operation with constant propagation */
1546 static void gen_opif(int op
)
1554 /* currently, we cannot do computations with forward symbols */
1555 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1556 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1558 if (v1
->type
.t
== VT_FLOAT
) {
1561 } else if (v1
->type
.t
== VT_DOUBLE
) {
1569 /* NOTE: we only do constant propagation if finite number (not
1570 NaN or infinity) (ANSI spec) */
1571 if (!ieee_finite(f1
) || !ieee_finite(f2
))
1575 case '+': f1
+= f2
; break;
1576 case '-': f1
-= f2
; break;
1577 case '*': f1
*= f2
; break;
1581 tcc_error("division by zero in constant");
1586 /* XXX: also handles tests ? */
1590 /* XXX: overflow test ? */
1591 if (v1
->type
.t
== VT_FLOAT
) {
1593 } else if (v1
->type
.t
== VT_DOUBLE
) {
1601 if (!nocode_wanted
) {
1609 static int pointed_size(CType
*type
)
1612 return type_size(pointed_type(type
), &align
);
1615 static void vla_runtime_pointed_size(CType
*type
)
1618 vla_runtime_type_size(pointed_type(type
), &align
);
1621 static inline int is_null_pointer(SValue
*p
)
1623 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
1625 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& p
->c
.i
== 0) ||
1626 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.ll
== 0) ||
1627 ((p
->type
.t
& VT_BTYPE
) == VT_PTR
&& p
->c
.ptr_offset
== 0);
1630 static inline int is_integer_btype(int bt
)
1632 return (bt
== VT_BYTE
|| bt
== VT_SHORT
||
1633 bt
== VT_INT
|| bt
== VT_LLONG
);
1636 /* check types for comparison or subtraction of pointers */
1637 static void check_comparison_pointer_types(SValue
*p1
, SValue
*p2
, int op
)
1639 CType
*type1
, *type2
, tmp_type1
, tmp_type2
;
1642 /* null pointers are accepted for all comparisons as gcc */
1643 if (is_null_pointer(p1
) || is_null_pointer(p2
))
1647 bt1
= type1
->t
& VT_BTYPE
;
1648 bt2
= type2
->t
& VT_BTYPE
;
1649 /* accept comparison between pointer and integer with a warning */
1650 if ((is_integer_btype(bt1
) || is_integer_btype(bt2
)) && op
!= '-') {
1651 if (op
!= TOK_LOR
&& op
!= TOK_LAND
)
1652 tcc_warning("comparison between pointer and integer");
1656 /* both must be pointers or implicit function pointers */
1657 if (bt1
== VT_PTR
) {
1658 type1
= pointed_type(type1
);
1659 } else if (bt1
!= VT_FUNC
)
1660 goto invalid_operands
;
1662 if (bt2
== VT_PTR
) {
1663 type2
= pointed_type(type2
);
1664 } else if (bt2
!= VT_FUNC
) {
1666 tcc_error("invalid operands to binary %s", get_tok_str(op
, NULL
));
1668 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
1669 (type2
->t
& VT_BTYPE
) == VT_VOID
)
1673 tmp_type1
.t
&= ~(VT_DEFSIGN
| VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
1674 tmp_type2
.t
&= ~(VT_DEFSIGN
| VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
1675 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
1676 /* gcc-like error if '-' is used */
1678 goto invalid_operands
;
1680 tcc_warning("comparison of distinct pointer types lacks a cast");
1684 /* generic gen_op: handles types problems */
1685 ST_FUNC
void gen_op(int op
)
1687 int u
, t1
, t2
, bt1
, bt2
, t
;
1690 t1
= vtop
[-1].type
.t
;
1691 t2
= vtop
[0].type
.t
;
1692 bt1
= t1
& VT_BTYPE
;
1693 bt2
= t2
& VT_BTYPE
;
1695 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
1696 /* at least one operand is a pointer */
1697 /* relationnal op: must be both pointers */
1698 if (op
>= TOK_ULT
&& op
<= TOK_LOR
) {
1699 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
1700 /* pointers are handled are unsigned */
1701 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1702 t
= VT_LLONG
| VT_UNSIGNED
;
1704 t
= VT_INT
| VT_UNSIGNED
;
1708 /* if both pointers, then it must be the '-' op */
1709 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
1711 tcc_error("cannot use pointers here");
1712 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
1713 /* XXX: check that types are compatible */
1714 if (vtop
[-1].type
.t
& VT_VLA
) {
1715 vla_runtime_pointed_size(&vtop
[-1].type
);
1717 vpushi(pointed_size(&vtop
[-1].type
));
1721 /* set to integer type */
1722 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1723 vtop
->type
.t
= VT_LLONG
;
1725 vtop
->type
.t
= VT_INT
;
1730 /* exactly one pointer : must be '+' or '-'. */
1731 if (op
!= '-' && op
!= '+')
1732 tcc_error("cannot use pointers here");
1733 /* Put pointer as first operand */
1734 if (bt2
== VT_PTR
) {
1738 type1
= vtop
[-1].type
;
1739 type1
.t
&= ~VT_ARRAY
;
1740 if (vtop
[-1].type
.t
& VT_VLA
)
1741 vla_runtime_pointed_size(&vtop
[-1].type
);
1743 u
= pointed_size(&vtop
[-1].type
);
1745 tcc_error("unknown array element size");
1746 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1749 /* XXX: cast to int ? (long long case) */
1755 /* #ifdef CONFIG_TCC_BCHECK
1756 The main reason to removing this code:
1763 fprintf(stderr, "v+i-j = %p\n", v+i-j);
1764 fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
1766 When this code is on. then the output looks like
1768 v+(i-j) = 0xbff84000
1770 /* if evaluating constant expression, no code should be
1771 generated, so no bound check */
1772 if (tcc_state
->do_bounds_check
&& !const_wanted
) {
1773 /* if bounded pointers, we generate a special code to
1780 gen_bounded_ptr_add();
1786 /* put again type if gen_opic() swaped operands */
1789 } else if (is_float(bt1
) || is_float(bt2
)) {
1790 /* compute bigger type and do implicit casts */
1791 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
1793 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
1798 /* floats can only be used for a few operations */
1799 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
1800 (op
< TOK_ULT
|| op
> TOK_GT
))
1801 tcc_error("invalid operands for binary operation");
1803 } else if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
) {
1804 t
= bt1
== VT_LLONG
? VT_LLONG
: VT_INT
;
1805 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (t
| VT_UNSIGNED
))
1808 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
1809 /* cast to biggest op */
1811 /* convert to unsigned if it does not fit in a long long */
1812 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
1813 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
1816 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
1817 tcc_error("comparison of struct");
1819 /* integer operations */
1821 /* convert to unsigned if it does not fit in an integer */
1822 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
1823 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
1826 /* XXX: currently, some unsigned operations are explicit, so
1827 we modify them here */
1828 if (t
& VT_UNSIGNED
) {
1835 else if (op
== TOK_LT
)
1837 else if (op
== TOK_GT
)
1839 else if (op
== TOK_LE
)
1841 else if (op
== TOK_GE
)
1848 /* special case for shifts and long long: we keep the shift as
1850 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
1857 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
1858 /* relationnal op: the result is an int */
1859 vtop
->type
.t
= VT_INT
;
1864 // Make sure that we have converted to an rvalue:
1865 if (vtop
->r
& VT_LVAL
&& !nocode_wanted
)
1866 gv(is_float(vtop
->type
.t
& VT_BTYPE
) ? RC_FLOAT
: RC_INT
);
1869 #ifndef TCC_TARGET_ARM
1870 /* generic itof for unsigned long long case */
1871 static void gen_cvt_itof1(int t
)
1873 #ifdef TCC_TARGET_ARM64
1876 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
1877 (VT_LLONG
| VT_UNSIGNED
)) {
1880 vpush_global_sym(&func_old_type
, TOK___floatundisf
);
1881 #if LDOUBLE_SIZE != 8
1882 else if (t
== VT_LDOUBLE
)
1883 vpush_global_sym(&func_old_type
, TOK___floatundixf
);
1886 vpush_global_sym(&func_old_type
, TOK___floatundidf
);
1890 vtop
->r
= reg_fret(t
);
1898 /* generic ftoi for unsigned long long case */
1899 static void gen_cvt_ftoi1(int t
)
1901 #ifdef TCC_TARGET_ARM64
1906 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
1907 /* not handled natively */
1908 st
= vtop
->type
.t
& VT_BTYPE
;
1910 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
1911 #if LDOUBLE_SIZE != 8
1912 else if (st
== VT_LDOUBLE
)
1913 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
1916 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
1921 vtop
->r2
= REG_LRET
;
1928 /* force char or short cast */
1929 static void force_charshort_cast(int t
)
1933 /* XXX: add optimization if lvalue : just change type and offset */
1938 if (t
& VT_UNSIGNED
) {
1939 vpushi((1 << bits
) - 1);
1945 /* result must be signed or the SAR is converted to an SHL
1946 This was not the case when "t" was a signed short
1947 and the last value on the stack was an unsigned int */
1948 vtop
->type
.t
&= ~VT_UNSIGNED
;
1954 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1955 static void gen_cast(CType
*type
)
1957 int sbt
, dbt
, sf
, df
, c
, p
;
1959 /* special delayed cast for char/short */
1960 /* XXX: in some cases (multiple cascaded casts), it may still
1962 if (vtop
->r
& VT_MUSTCAST
) {
1963 vtop
->r
&= ~VT_MUSTCAST
;
1964 force_charshort_cast(vtop
->type
.t
);
1967 /* bitfields first get cast to ints */
1968 if (vtop
->type
.t
& VT_BITFIELD
&& !nocode_wanted
) {
1972 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
1973 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
1978 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1979 p
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == (VT_CONST
| VT_SYM
);
1981 /* constant case: we can do it now */
1982 /* XXX: in ISOC, cannot do it if error in convert */
1983 if (sbt
== VT_FLOAT
)
1984 vtop
->c
.ld
= vtop
->c
.f
;
1985 else if (sbt
== VT_DOUBLE
)
1986 vtop
->c
.ld
= vtop
->c
.d
;
1989 if ((sbt
& VT_BTYPE
) == VT_LLONG
) {
1990 if (sbt
& VT_UNSIGNED
)
1991 vtop
->c
.ld
= vtop
->c
.ull
;
1993 vtop
->c
.ld
= vtop
->c
.ll
;
1995 if (sbt
& VT_UNSIGNED
)
1996 vtop
->c
.ld
= vtop
->c
.ui
;
1998 vtop
->c
.ld
= vtop
->c
.i
;
2001 if (dbt
== VT_FLOAT
)
2002 vtop
->c
.f
= (float)vtop
->c
.ld
;
2003 else if (dbt
== VT_DOUBLE
)
2004 vtop
->c
.d
= (double)vtop
->c
.ld
;
2005 } else if (sf
&& dbt
== (VT_LLONG
|VT_UNSIGNED
)) {
2006 vtop
->c
.ull
= (unsigned long long)vtop
->c
.ld
;
2007 } else if (sf
&& dbt
== VT_BOOL
) {
2008 vtop
->c
.i
= (vtop
->c
.ld
!= 0);
2011 vtop
->c
.ll
= (long long)vtop
->c
.ld
;
2012 else if (sbt
== (VT_LLONG
|VT_UNSIGNED
))
2013 vtop
->c
.ll
= vtop
->c
.ull
;
2014 else if (sbt
& VT_UNSIGNED
)
2015 vtop
->c
.ll
= vtop
->c
.ui
;
2016 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2017 else if (sbt
== VT_PTR
)
2020 else if (sbt
!= VT_LLONG
)
2021 vtop
->c
.ll
= vtop
->c
.i
;
2023 if (dbt
== (VT_LLONG
|VT_UNSIGNED
))
2024 vtop
->c
.ull
= vtop
->c
.ll
;
2025 else if (dbt
== VT_BOOL
)
2026 vtop
->c
.i
= (vtop
->c
.ll
!= 0);
2027 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2028 else if (dbt
== VT_PTR
)
2031 else if (dbt
!= VT_LLONG
) {
2033 if ((dbt
& VT_BTYPE
) == VT_BYTE
)
2035 else if ((dbt
& VT_BTYPE
) == VT_SHORT
)
2037 if(dbt
& VT_UNSIGNED
)
2038 vtop
->c
.ui
= ((unsigned int)vtop
->c
.ll
<< s
) >> s
;
2040 vtop
->c
.i
= ((int)vtop
->c
.ll
<< s
) >> s
;
2043 } else if (p
&& dbt
== VT_BOOL
) {
2046 } else if (!nocode_wanted
) {
2047 /* non constant case: generate code */
2049 /* convert from fp to fp */
2052 /* convert int to fp */
2055 /* convert fp to int */
2056 if (dbt
== VT_BOOL
) {
2060 /* we handle char/short/etc... with generic code */
2061 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
2062 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
2066 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
2067 /* additional cast for char/short... */
2072 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
2073 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
2074 if ((sbt
& VT_BTYPE
) != VT_LLONG
&& !nocode_wanted
) {
2075 /* scalar to long long */
2076 /* machine independent conversion */
2078 /* generate high word */
2079 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
2083 if (sbt
== VT_PTR
) {
2084 /* cast from pointer to int before we apply
2085 shift operation, which pointers don't support*/
2086 gen_cast(&int_type
);
2092 /* patch second register */
2093 vtop
[-1].r2
= vtop
->r
;
2097 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
||
2098 (dbt
& VT_BTYPE
) == VT_PTR
||
2099 (dbt
& VT_BTYPE
) == VT_FUNC
) {
2100 if ((sbt
& VT_BTYPE
) != VT_LLONG
&&
2101 (sbt
& VT_BTYPE
) != VT_PTR
&&
2102 (sbt
& VT_BTYPE
) != VT_FUNC
&& !nocode_wanted
) {
2103 /* need to convert from 32bit to 64bit */
2105 if (sbt
!= (VT_INT
| VT_UNSIGNED
)) {
2106 #if defined(TCC_TARGET_ARM64)
2108 #elif defined(TCC_TARGET_X86_64)
2110 /* x86_64 specific: movslq */
2112 o(0xc0 + (REG_VALUE(r
) << 3) + REG_VALUE(r
));
2119 } else if (dbt
== VT_BOOL
) {
2120 /* scalar to bool */
2123 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
2124 (dbt
& VT_BTYPE
) == VT_SHORT
) {
2125 if (sbt
== VT_PTR
) {
2126 vtop
->type
.t
= VT_INT
;
2127 tcc_warning("nonportable conversion from pointer to char/short");
2129 force_charshort_cast(dbt
);
2130 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
2132 if (sbt
== VT_LLONG
&& !nocode_wanted
) {
2133 /* from long long: just take low order word */
2137 /* if lvalue and single word type, nothing to do because
2138 the lvalue already contains the real type size (see
2139 VT_LVAL_xxx constants) */
2142 } else if ((dbt
& VT_BTYPE
) == VT_PTR
&& !(vtop
->r
& VT_LVAL
)) {
2143 /* if we are casting between pointer types,
2144 we must update the VT_LVAL_xxx size */
2145 vtop
->r
= (vtop
->r
& ~VT_LVAL_TYPE
)
2146 | (lvalue_type(type
->ref
->type
.t
) & VT_LVAL_TYPE
);
2151 /* return type size as known at compile time. Put alignment at 'a' */
2152 ST_FUNC
int type_size(CType
*type
, int *a
)
2157 bt
= type
->t
& VT_BTYPE
;
2158 if (bt
== VT_STRUCT
) {
2163 } else if (bt
== VT_PTR
) {
2164 if (type
->t
& VT_ARRAY
) {
2168 ts
= type_size(&s
->type
, a
);
2170 if (ts
< 0 && s
->c
< 0)
2178 } else if (bt
== VT_LDOUBLE
) {
2180 return LDOUBLE_SIZE
;
2181 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
2182 #ifdef TCC_TARGET_I386
2183 #ifdef TCC_TARGET_PE
2188 #elif defined(TCC_TARGET_ARM)
2198 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
2201 } else if (bt
== VT_SHORT
) {
2204 } else if (bt
== VT_QLONG
|| bt
== VT_QFLOAT
) {
2208 /* char, void, function, _Bool */
2214 /* push type size as known at runtime time on top of value stack. Put
2216 ST_FUNC
void vla_runtime_type_size(CType
*type
, int *a
)
2218 if (type
->t
& VT_VLA
) {
2219 vset(&int_type
, VT_LOCAL
|VT_LVAL
, type
->ref
->c
);
2221 vpushi(type_size(type
, a
));
2225 static void vla_sp_save(void) {
2226 if (!(vla_flags
& VLA_SP_LOC_SET
)) {
2227 *vla_sp_loc
= (loc
-= PTR_SIZE
);
2228 vla_flags
|= VLA_SP_LOC_SET
;
2230 if (!(vla_flags
& VLA_SP_SAVED
)) {
2231 gen_vla_sp_save(*vla_sp_loc
);
2232 vla_flags
|= VLA_SP_SAVED
;
2236 /* return the pointed type of t */
2237 static inline CType
*pointed_type(CType
*type
)
2239 return &type
->ref
->type
;
2242 /* modify type so that its it is a pointer to type. */
2243 ST_FUNC
void mk_pointer(CType
*type
)
2246 s
= sym_push(SYM_FIELD
, type
, 0, -1);
2247 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
2251 /* compare function types. OLD functions match any new functions */
2252 static int is_compatible_func(CType
*type1
, CType
*type2
)
2258 if (!is_compatible_types(&s1
->type
, &s2
->type
))
2260 /* check func_call */
2261 if (s1
->a
.func_call
!= s2
->a
.func_call
)
2263 /* XXX: not complete */
2264 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
2268 while (s1
!= NULL
) {
2271 if (!is_compatible_parameter_types(&s1
->type
, &s2
->type
))
2281 /* return true if type1 and type2 are the same. If unqualified is
2282 true, qualifiers on the types are ignored.
2284 - enums are not checked as gcc __builtin_types_compatible_p ()
2286 static int compare_types(CType
*type1
, CType
*type2
, int unqualified
)
2290 t1
= type1
->t
& VT_TYPE
;
2291 t2
= type2
->t
& VT_TYPE
;
2293 /* strip qualifiers before comparing */
2294 t1
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2295 t2
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2297 /* Default Vs explicit signedness only matters for char */
2298 if ((t1
& VT_BTYPE
) != VT_BYTE
) {
2302 /* XXX: bitfields ? */
2305 /* test more complicated cases */
2306 bt1
= t1
& VT_BTYPE
;
2307 if (bt1
== VT_PTR
) {
2308 type1
= pointed_type(type1
);
2309 type2
= pointed_type(type2
);
2310 return is_compatible_types(type1
, type2
);
2311 } else if (bt1
== VT_STRUCT
) {
2312 return (type1
->ref
== type2
->ref
);
2313 } else if (bt1
== VT_FUNC
) {
2314 return is_compatible_func(type1
, type2
);
2320 /* return true if type1 and type2 are exactly the same (including
2323 static int is_compatible_types(CType
*type1
, CType
*type2
)
2325 return compare_types(type1
,type2
,0);
2328 /* return true if type1 and type2 are the same (ignoring qualifiers).
2330 static int is_compatible_parameter_types(CType
*type1
, CType
*type2
)
2332 return compare_types(type1
,type2
,1);
2335 /* print a type. If 'varstr' is not NULL, then the variable is also
2336 printed in the type */
2338 /* XXX: add array and function pointers */
2339 static void type_to_str(char *buf
, int buf_size
,
2340 CType
*type
, const char *varstr
)
2347 t
= type
->t
& VT_TYPE
;
2350 if (t
& VT_CONSTANT
)
2351 pstrcat(buf
, buf_size
, "const ");
2352 if (t
& VT_VOLATILE
)
2353 pstrcat(buf
, buf_size
, "volatile ");
2354 if ((t
& (VT_DEFSIGN
| VT_UNSIGNED
)) == (VT_DEFSIGN
| VT_UNSIGNED
))
2355 pstrcat(buf
, buf_size
, "unsigned ");
2356 else if (t
& VT_DEFSIGN
)
2357 pstrcat(buf
, buf_size
, "signed ");
2387 tstr
= "long double";
2389 pstrcat(buf
, buf_size
, tstr
);
2393 if (bt
== VT_STRUCT
)
2397 pstrcat(buf
, buf_size
, tstr
);
2398 v
= type
->ref
->v
& ~SYM_STRUCT
;
2399 if (v
>= SYM_FIRST_ANOM
)
2400 pstrcat(buf
, buf_size
, "<anonymous>");
2402 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
2406 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
2407 pstrcat(buf
, buf_size
, "(");
2409 while (sa
!= NULL
) {
2410 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
2411 pstrcat(buf
, buf_size
, buf1
);
2414 pstrcat(buf
, buf_size
, ", ");
2416 pstrcat(buf
, buf_size
, ")");
2420 pstrcpy(buf1
, sizeof(buf1
), "*");
2422 pstrcat(buf1
, sizeof(buf1
), varstr
);
2423 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
2427 pstrcat(buf
, buf_size
, " ");
2428 pstrcat(buf
, buf_size
, varstr
);
2433 /* verify type compatibility to store vtop in 'dt' type, and generate
2435 static void gen_assign_cast(CType
*dt
)
2437 CType
*st
, *type1
, *type2
, tmp_type1
, tmp_type2
;
2438 char buf1
[256], buf2
[256];
2441 st
= &vtop
->type
; /* source type */
2442 dbt
= dt
->t
& VT_BTYPE
;
2443 sbt
= st
->t
& VT_BTYPE
;
2444 if (sbt
== VT_VOID
|| dbt
== VT_VOID
) {
2445 if (sbt
== VT_VOID
&& dbt
== VT_VOID
)
2447 It is Ok if both are void
2453 gcc accepts this program
2456 tcc_error("cannot cast from/to void");
2458 if (dt
->t
& VT_CONSTANT
)
2459 tcc_warning("assignment of read-only location");
2462 /* special cases for pointers */
2463 /* '0' can also be a pointer */
2464 if (is_null_pointer(vtop
))
2466 /* accept implicit pointer to integer cast with warning */
2467 if (is_integer_btype(sbt
)) {
2468 tcc_warning("assignment makes pointer from integer without a cast");
2471 type1
= pointed_type(dt
);
2472 /* a function is implicitely a function pointer */
2473 if (sbt
== VT_FUNC
) {
2474 if ((type1
->t
& VT_BTYPE
) != VT_VOID
&&
2475 !is_compatible_types(pointed_type(dt
), st
))
2476 tcc_warning("assignment from incompatible pointer type");
2481 type2
= pointed_type(st
);
2482 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
2483 (type2
->t
& VT_BTYPE
) == VT_VOID
) {
2484 /* void * can match anything */
2486 /* exact type match, except for unsigned */
2489 tmp_type1
.t
&= ~(VT_DEFSIGN
| VT_UNSIGNED
| VT_CONSTANT
|
2491 tmp_type2
.t
&= ~(VT_DEFSIGN
| VT_UNSIGNED
| VT_CONSTANT
|
2493 if (!is_compatible_types(&tmp_type1
, &tmp_type2
))
2494 tcc_warning("assignment from incompatible pointer type");
2496 /* check const and volatile */
2497 if ((!(type1
->t
& VT_CONSTANT
) && (type2
->t
& VT_CONSTANT
)) ||
2498 (!(type1
->t
& VT_VOLATILE
) && (type2
->t
& VT_VOLATILE
)))
2499 tcc_warning("assignment discards qualifiers from pointer target type");
2505 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
2506 tcc_warning("assignment makes integer from pointer without a cast");
2508 /* XXX: more tests */
2513 tmp_type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2514 tmp_type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2515 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
2517 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
2518 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
2519 tcc_error("cannot cast '%s' to '%s'", buf1
, buf2
);
2527 /* store vtop in lvalue pushed on stack */
2528 ST_FUNC
void vstore(void)
2530 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
2532 ft
= vtop
[-1].type
.t
;
2533 sbt
= vtop
->type
.t
& VT_BTYPE
;
2534 dbt
= ft
& VT_BTYPE
;
2535 if ((((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
2536 (sbt
== VT_INT
&& dbt
== VT_SHORT
))
2537 && !(vtop
->type
.t
& VT_BITFIELD
)) {
2538 /* optimize char/short casts */
2539 delayed_cast
= VT_MUSTCAST
;
2540 vtop
->type
.t
= ft
& (VT_TYPE
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
)));
2541 /* XXX: factorize */
2542 if (ft
& VT_CONSTANT
)
2543 tcc_warning("assignment of read-only location");
2546 if (!(ft
& VT_BITFIELD
))
2547 gen_assign_cast(&vtop
[-1].type
);
2550 if (sbt
== VT_STRUCT
) {
2551 /* if structure, only generate pointer */
2552 /* structure assignment : generate memcpy */
2553 /* XXX: optimize if small size */
2554 if (!nocode_wanted
) {
2555 size
= type_size(&vtop
->type
, &align
);
2559 vtop
->type
.t
= VT_PTR
;
2562 /* address of memcpy() */
2565 vpush_global_sym(&func_old_type
, TOK_memcpy8
);
2566 else if(!(align
& 3))
2567 vpush_global_sym(&func_old_type
, TOK_memcpy4
);
2570 vpush_global_sym(&func_old_type
, TOK_memcpy
);
2575 vtop
->type
.t
= VT_PTR
;
2584 /* leave source on stack */
2585 } else if (ft
& VT_BITFIELD
) {
2586 /* bitfield store handling */
2588 /* save lvalue as expression result (example: s.b = s.a = n;) */
2589 vdup(), vtop
[-1] = vtop
[-2];
2591 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
2592 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2593 /* remove bit field info to avoid loops */
2594 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2596 if((ft
& VT_BTYPE
) == VT_BOOL
) {
2597 gen_cast(&vtop
[-1].type
);
2598 vtop
[-1].type
.t
= (vtop
[-1].type
.t
& ~VT_BTYPE
) | (VT_BYTE
| VT_UNSIGNED
);
2601 /* duplicate destination */
2603 vtop
[-1] = vtop
[-2];
2605 /* mask and shift source */
2606 if((ft
& VT_BTYPE
) != VT_BOOL
) {
2607 if((ft
& VT_BTYPE
) == VT_LLONG
) {
2608 vpushll((1ULL << bit_size
) - 1ULL);
2610 vpushi((1 << bit_size
) - 1);
2616 /* load destination, mask and or with source */
2618 if((ft
& VT_BTYPE
) == VT_LLONG
) {
2619 vpushll(~(((1ULL << bit_size
) - 1ULL) << bit_pos
));
2621 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
2627 /* ... and discard */
2631 if (!nocode_wanted
) {
2632 #ifdef CONFIG_TCC_BCHECK
2633 /* bound check case */
2634 if (vtop
[-1].r
& VT_MUSTBOUND
) {
2643 #ifdef TCC_TARGET_X86_64
2644 if ((ft
& VT_BTYPE
) == VT_LDOUBLE
) {
2646 } else if ((ft
& VT_BTYPE
) == VT_QFLOAT
) {
2651 r
= gv(rc
); /* generate value */
2652 /* if lvalue was saved on stack, must read it */
2653 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
2655 t
= get_reg(RC_INT
);
2656 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2661 sv
.r
= VT_LOCAL
| VT_LVAL
;
2662 sv
.c
.ul
= vtop
[-1].c
.ul
;
2664 vtop
[-1].r
= t
| VT_LVAL
;
2666 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
2667 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2668 if (((ft
& VT_BTYPE
) == VT_QLONG
) || ((ft
& VT_BTYPE
) == VT_QFLOAT
)) {
2669 int addr_type
= VT_LLONG
, load_size
= 8, load_type
= ((vtop
->type
.t
& VT_BTYPE
) == VT_QLONG
) ? VT_LLONG
: VT_DOUBLE
;
2671 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
2672 int addr_type
= VT_INT
, load_size
= 4, load_type
= VT_INT
;
2674 vtop
[-1].type
.t
= load_type
;
2677 /* convert to int to increment easily */
2678 vtop
->type
.t
= addr_type
;
2684 vtop
[-1].type
.t
= load_type
;
2685 /* XXX: it works because r2 is spilled last ! */
2686 store(vtop
->r2
, vtop
- 1);
2692 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
2693 vtop
->r
|= delayed_cast
;
2697 /* post defines POST/PRE add. c is the token ++ or -- */
2698 ST_FUNC
void inc(int post
, int c
)
2701 vdup(); /* save lvalue */
2704 gv_dup(); /* duplicate value */
2706 vdup(); /* duplicate value */
2711 vpushi(c
- TOK_MID
);
2713 vstore(); /* store value */
2715 vpop(); /* if post op, return saved value */
2718 /* Parse GNUC __attribute__ extension. Currently, the following
2719 extensions are recognized:
2720 - aligned(n) : set data/function alignment.
2721 - packed : force data alignment to 1
2722 - section(x) : generate data/code in this section.
2723 - unused : currently ignored, but may be used someday.
2724 - regparm(n) : pass function parameters in registers (i386 only)
2726 static void parse_attribute(AttributeDef
*ad
)
2730 while (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
) {
2734 while (tok
!= ')') {
2735 if (tok
< TOK_IDENT
)
2736 expect("attribute name");
2744 expect("section name");
2745 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
2753 expect("alias(\"target\")");
2754 ad
->alias_target
= /* save string as token, for later */
2755 tok_alloc((char*)tokc
.cstr
->data
, tokc
.cstr
->size
-1)->tok
;
2759 case TOK_VISIBILITY1
:
2760 case TOK_VISIBILITY2
:
2763 expect("visibility(\"default|hidden|internal|protected\")");
2764 if (!strcmp (tokc
.cstr
->data
, "default"))
2765 ad
->a
.visibility
= STV_DEFAULT
;
2766 else if (!strcmp (tokc
.cstr
->data
, "hidden"))
2767 ad
->a
.visibility
= STV_HIDDEN
;
2768 else if (!strcmp (tokc
.cstr
->data
, "internal"))
2769 ad
->a
.visibility
= STV_INTERNAL
;
2770 else if (!strcmp (tokc
.cstr
->data
, "protected"))
2771 ad
->a
.visibility
= STV_PROTECTED
;
2773 expect("visibility(\"default|hidden|internal|protected\")");
2782 if (n
<= 0 || (n
& (n
- 1)) != 0)
2783 tcc_error("alignment must be a positive power of two");
2800 /* currently, no need to handle it because tcc does not
2801 track unused objects */
2805 /* currently, no need to handle it because tcc does not
2806 track unused objects */
2811 ad
->a
.func_call
= FUNC_CDECL
;
2816 ad
->a
.func_call
= FUNC_STDCALL
;
2818 #ifdef TCC_TARGET_I386
2828 ad
->a
.func_call
= FUNC_FASTCALL1
+ n
- 1;
2834 ad
->a
.func_call
= FUNC_FASTCALLW
;
2841 ad
->a
.mode
= VT_LLONG
+ 1;
2844 ad
->a
.mode
= VT_SHORT
+ 1;
2847 ad
->a
.mode
= VT_INT
+ 1;
2850 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok
, NULL
));
2857 ad
->a
.func_export
= 1;
2860 ad
->a
.func_import
= 1;
2863 if (tcc_state
->warn_unsupported
)
2864 tcc_warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
2865 /* skip parameters */
2867 int parenthesis
= 0;
2871 else if (tok
== ')')
2874 } while (parenthesis
&& tok
!= -1);
2887 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2888 static void struct_decl(CType
*type
, int u
, int tdef
)
2890 int a
, v
, size
, align
, maxalign
, c
, offset
, flexible
;
2891 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
, prevbt
;
2892 Sym
*s
, *ss
, *ass
, **ps
;
2896 a
= tok
; /* save decl type */
2901 /* struct already defined ? return it */
2903 expect("struct/union/enum name");
2907 tcc_error("invalid type");
2909 } else if (tok
>= TOK_IDENT
&& !tdef
)
2910 tcc_error("unknown struct/union/enum");
2916 /* we put an undefined size for struct/union */
2917 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
2918 s
->r
= 0; /* default alignment is zero as gcc */
2919 /* put struct/union/enum name in type */
2927 tcc_error("struct/union/enum already defined");
2928 /* cannot be empty */
2930 /* non empty enums are not allowed */
2931 if (a
== TOK_ENUM
) {
2935 expect("identifier");
2937 if (ss
&& !local_stack
)
2938 tcc_error("redefinition of enumerator '%s'",
2939 get_tok_str(v
, NULL
));
2945 /* enum symbols have static storage */
2946 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
2947 ss
->type
.t
|= VT_STATIC
;
2952 /* NOTE: we accept a trailing comma */
2956 s
->c
= type_size(&int_type
, &align
);
2965 while (tok
!= '}') {
2966 parse_btype(&btype
, &ad
);
2969 tcc_error("flexible array member '%s' not at the end of struct",
2970 get_tok_str(v
, NULL
));
2975 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
| TYPE_ABSTRACT
);
2977 if ((type1
.t
& VT_BTYPE
) != VT_STRUCT
)
2978 expect("identifier");
2980 int v
= btype
.ref
->v
;
2981 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
2982 if (tcc_state
->ms_extensions
== 0)
2983 expect("identifier");
2987 if (type_size(&type1
, &align
) < 0) {
2988 if ((a
== TOK_STRUCT
) && (type1
.t
& VT_ARRAY
) && c
)
2991 tcc_error("field '%s' has incomplete type",
2992 get_tok_str(v
, NULL
));
2994 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
2995 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
| VT_INLINE
)))
2996 tcc_error("invalid type for '%s'",
2997 get_tok_str(v
, NULL
));
3001 bit_size
= expr_const();
3002 /* XXX: handle v = 0 case for messages */
3004 tcc_error("negative width in bit-field '%s'",
3005 get_tok_str(v
, NULL
));
3006 if (v
&& bit_size
== 0)
3007 tcc_error("zero width for bit-field '%s'",
3008 get_tok_str(v
, NULL
));
3010 size
= type_size(&type1
, &align
);
3012 if (align
< ad
.a
.aligned
)
3013 align
= ad
.a
.aligned
;
3014 } else if (ad
.a
.packed
) {
3016 } else if (*tcc_state
->pack_stack_ptr
) {
3017 if (align
> *tcc_state
->pack_stack_ptr
)
3018 align
= *tcc_state
->pack_stack_ptr
;
3021 if (bit_size
>= 0) {
3022 bt
= type1
.t
& VT_BTYPE
;
3029 tcc_error("bitfields must have scalar type");
3031 if (bit_size
> bsize
) {
3032 tcc_error("width of '%s' exceeds its type",
3033 get_tok_str(v
, NULL
));
3034 } else if (bit_size
== bsize
) {
3035 /* no need for bit fields */
3037 } else if (bit_size
== 0) {
3038 /* XXX: what to do if only padding in a
3040 /* zero size: means to pad */
3043 /* we do not have enough room ?
3044 did the type change?
3046 if ((bit_pos
+ bit_size
) > bsize
||
3047 bt
!= prevbt
|| a
== TOK_UNION
)
3050 /* XXX: handle LSB first */
3051 type1
.t
|= VT_BITFIELD
|
3052 (bit_pos
<< VT_STRUCT_SHIFT
) |
3053 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
3054 bit_pos
+= bit_size
;
3060 if (v
!= 0 || (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
3061 /* add new memory data only if starting
3063 if (lbit_pos
== 0) {
3064 if (a
== TOK_STRUCT
) {
3065 c
= (c
+ align
- 1) & -align
;
3074 if (align
> maxalign
)
3078 printf("add field %s offset=%d",
3079 get_tok_str(v
, NULL
), offset
);
3080 if (type1
.t
& VT_BITFIELD
) {
3081 printf(" pos=%d size=%d",
3082 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
3083 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
3088 if (v
== 0 && (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
3090 while ((ass
= ass
->next
) != NULL
) {
3091 ss
= sym_push(ass
->v
, &ass
->type
, 0, offset
+ ass
->c
);
3096 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
3100 if (tok
== ';' || tok
== TOK_EOF
)
3107 /* store size and alignment */
3108 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
3114 /* return 1 if basic type is a type size (short, long, long long) */
3115 ST_FUNC
int is_btype_size(int bt
)
3117 return bt
== VT_SHORT
|| bt
== VT_LONG
|| bt
== VT_LLONG
;
3120 /* return 0 if no type declaration. otherwise, return the basic type
3123 static int parse_btype(CType
*type
, AttributeDef
*ad
)
3125 int t
, u
, bt_size
, complete
, type_found
, typespec_found
;
3129 memset(ad
, 0, sizeof(AttributeDef
));
3137 /* currently, we really ignore extension */
3148 tcc_error("too many basic types");
3150 bt_size
= is_btype_size (u
& VT_BTYPE
);
3151 if (u
== VT_INT
|| (!bt_size
&& !(t
& VT_TYPEDEF
)))
3166 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
3167 #ifndef TCC_TARGET_PE
3168 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
3170 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
3171 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
3177 #ifdef TCC_TARGET_ARM64
3179 /* GCC's __uint128_t appears in some Linux header files. Make it a
3180 synonym for long double to get the size and alignment right. */
3192 if ((t
& VT_BTYPE
) == VT_LONG
) {
3193 #ifdef TCC_TARGET_PE
3194 t
= (t
& ~VT_BTYPE
) | VT_DOUBLE
;
3196 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
3204 struct_decl(&type1
, VT_ENUM
, t
& (VT_TYPEDEF
| VT_EXTERN
));
3207 type
->ref
= type1
.ref
;
3211 struct_decl(&type1
, VT_STRUCT
, t
& (VT_TYPEDEF
| VT_EXTERN
));
3214 /* type modifiers */
3230 if ((t
& (VT_DEFSIGN
|VT_UNSIGNED
)) == (VT_DEFSIGN
|VT_UNSIGNED
))
3231 tcc_error("signed and unsigned modifier");
3244 if ((t
& (VT_DEFSIGN
|VT_UNSIGNED
)) == VT_DEFSIGN
)
3245 tcc_error("signed and unsigned modifier");
3246 t
|= VT_DEFSIGN
| VT_UNSIGNED
;
3271 /* GNUC attribute */
3272 case TOK_ATTRIBUTE1
:
3273 case TOK_ATTRIBUTE2
:
3274 parse_attribute(ad
);
3277 t
= (t
& ~VT_BTYPE
) | u
;
3285 parse_expr_type(&type1
);
3286 /* remove all storage modifiers except typedef */
3287 type1
.t
&= ~(VT_STORAGE
&~VT_TYPEDEF
);
3293 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
3295 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
3296 type
->ref
= s
->type
.ref
;
3298 /* get attributes from typedef */
3299 if (0 == ad
->a
.aligned
)
3300 ad
->a
.aligned
= s
->a
.aligned
;
3301 if (0 == ad
->a
.func_call
)
3302 ad
->a
.func_call
= s
->a
.func_call
;
3303 ad
->a
.packed
|= s
->a
.packed
;
3312 if (tcc_state
->char_is_unsigned
) {
3313 if ((t
& (VT_DEFSIGN
|VT_BTYPE
)) == VT_BYTE
)
3317 /* long is never used as type */
3318 if ((t
& VT_BTYPE
) == VT_LONG
)
3319 #if (!defined TCC_TARGET_X86_64 && !defined TCC_TARGET_ARM64) || \
3320 defined TCC_TARGET_PE
3321 t
= (t
& ~VT_BTYPE
) | VT_INT
;
3323 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
3329 /* convert a function parameter type (array to pointer and function to
3330 function pointer) */
3331 static inline void convert_parameter_type(CType
*pt
)
3333 /* remove const and volatile qualifiers (XXX: const could be used
3334 to indicate a const function parameter */
3335 pt
->t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
3336 /* array must be transformed to pointer according to ANSI C */
3338 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
3343 ST_FUNC
void parse_asm_str(CString
*astr
)
3346 /* read the string */
3348 expect("string constant");
3350 while (tok
== TOK_STR
) {
3351 /* XXX: add \0 handling too ? */
3352 cstr_cat(astr
, tokc
.cstr
->data
);
3355 cstr_ccat(astr
, '\0');
3358 /* Parse an asm label and return the label
3359 * Don't forget to free the CString in the caller! */
3360 static void asm_label_instr(CString
*astr
)
3363 parse_asm_str(astr
);
3366 printf("asm_alias: \"%s\"\n", (char *)astr
->data
);
3370 static void post_type(CType
*type
, AttributeDef
*ad
)
3372 int n
, l
, t1
, arg_size
, align
;
3373 Sym
**plast
, *s
, *first
;
3378 /* function declaration */
3386 /* read param name and compute offset */
3387 if (l
!= FUNC_OLD
) {
3388 if (!parse_btype(&pt
, &ad1
)) {
3390 tcc_error("invalid type");
3397 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
3399 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
3400 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
3401 tcc_error("parameter declared as void");
3402 arg_size
+= (type_size(&pt
, &align
) + PTR_SIZE
- 1) / PTR_SIZE
;
3407 expect("identifier");
3411 convert_parameter_type(&pt
);
3412 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
3418 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
3425 /* if no parameters, then old type prototype */
3429 /* NOTE: const is ignored in returned type as it has a special
3430 meaning in gcc / C++ */
3431 type
->t
&= ~VT_CONSTANT
;
3432 /* some ancient pre-K&R C allows a function to return an array
3433 and the array brackets to be put after the arguments, such
3434 that "int c()[]" means something like "int[] c()" */
3437 skip(']'); /* only handle simple "[]" */
3440 /* we push a anonymous symbol which will contain the function prototype */
3441 ad
->a
.func_args
= arg_size
;
3442 s
= sym_push(SYM_FIELD
, type
, 0, l
);
3447 } else if (tok
== '[') {
3448 /* array definition */
3450 if (tok
== TOK_RESTRICT1
)
3455 if (!local_stack
|| nocode_wanted
)
3456 vpushi(expr_const());
3458 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3461 tcc_error("invalid array size");
3463 if (!is_integer_btype(vtop
->type
.t
& VT_BTYPE
))
3464 tcc_error("size of variable length array should be an integer");
3469 /* parse next post type */
3470 post_type(type
, ad
);
3471 if (type
->t
== VT_FUNC
)
3472 tcc_error("declaration of an array of functions");
3473 t1
|= type
->t
& VT_VLA
;
3476 loc
-= type_size(&int_type
, &align
);
3480 vla_runtime_type_size(type
, &align
);
3482 vset(&int_type
, VT_LOCAL
|VT_LVAL
, loc
);
3489 /* we push an anonymous symbol which will contain the array
3491 s
= sym_push(SYM_FIELD
, type
, 0, n
);
3492 type
->t
= (t1
? VT_VLA
: VT_ARRAY
) | VT_PTR
;
3497 /* Parse a type declaration (except basic type), and return the type
3498 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3499 expected. 'type' should contain the basic type. 'ad' is the
3500 attribute definition of the basic type. It can be modified by
3503 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
3506 CType type1
, *type2
;
3507 int qualifiers
, storage
;
3509 while (tok
== '*') {
3517 qualifiers
|= VT_CONSTANT
;
3522 qualifiers
|= VT_VOLATILE
;
3530 type
->t
|= qualifiers
;
3533 /* XXX: clarify attribute handling */
3534 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
3535 parse_attribute(ad
);
3537 /* recursive type */
3538 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3539 type1
.t
= 0; /* XXX: same as int */
3542 /* XXX: this is not correct to modify 'ad' at this point, but
3543 the syntax is not clear */
3544 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
3545 parse_attribute(ad
);
3546 type_decl(&type1
, ad
, v
, td
);
3549 /* type identifier */
3550 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
3554 if (!(td
& TYPE_ABSTRACT
))
3555 expect("identifier");
3559 storage
= type
->t
& VT_STORAGE
;
3560 type
->t
&= ~VT_STORAGE
;
3561 if (storage
& VT_STATIC
) {
3562 int saved_nocode_wanted
= nocode_wanted
;
3564 post_type(type
, ad
);
3565 nocode_wanted
= saved_nocode_wanted
;
3567 post_type(type
, ad
);
3569 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
3570 parse_attribute(ad
);
3574 /* append type at the end of type1 */
3587 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3588 ST_FUNC
int lvalue_type(int t
)
3593 if (bt
== VT_BYTE
|| bt
== VT_BOOL
)
3595 else if (bt
== VT_SHORT
)
3599 if (t
& VT_UNSIGNED
)
3600 r
|= VT_LVAL_UNSIGNED
;
3604 /* indirection with full error checking and bound check */
3605 ST_FUNC
void indir(void)
3607 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
) {
3608 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
3612 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
3614 vtop
->type
= *pointed_type(&vtop
->type
);
3615 /* Arrays and functions are never lvalues */
3616 if (!(vtop
->type
.t
& VT_ARRAY
) && !(vtop
->type
.t
& VT_VLA
)
3617 && (vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
3618 vtop
->r
|= lvalue_type(vtop
->type
.t
);
3619 /* if bound checking, the referenced pointer must be checked */
3620 #ifdef CONFIG_TCC_BCHECK
3621 if (tcc_state
->do_bounds_check
)
3622 vtop
->r
|= VT_MUSTBOUND
;
3627 /* pass a parameter to a function and do type checking and casting */
3628 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
3633 func_type
= func
->c
;
3634 if (func_type
== FUNC_OLD
||
3635 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
3636 /* default casting : only need to convert float to double */
3637 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
3640 } else if (vtop
->type
.t
& VT_BITFIELD
) {
3641 type
.t
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
3644 } else if (arg
== NULL
) {
3645 tcc_error("too many arguments to function");
3648 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
3649 gen_assign_cast(&type
);
3653 /* parse an expression of the form '(type)' or '(expr)' and return its
3655 static void parse_expr_type(CType
*type
)
3661 if (parse_btype(type
, &ad
)) {
3662 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
3669 static void parse_type(CType
*type
)
3674 if (!parse_btype(type
, &ad
)) {
3677 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
3680 static void vpush_tokc(int t
)
3685 vsetc(&type
, VT_CONST
, &tokc
);
3688 ST_FUNC
void unary(void)
3690 int n
, t
, align
, size
, r
, sizeof_caller
;
3694 static int in_sizeof
= 0;
3696 sizeof_caller
= in_sizeof
;
3698 /* XXX: GCC 2.95.3 does not generate a table although it should be
3712 vpush_tokc(VT_INT
| VT_UNSIGNED
);
3716 vpush_tokc(VT_LLONG
);
3720 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
3724 vpush_tokc(VT_FLOAT
);
3728 vpush_tokc(VT_DOUBLE
);
3732 vpush_tokc(VT_LDOUBLE
);
3735 case TOK___FUNCTION__
:
3737 goto tok_identifier
;
3743 /* special function name identifier */
3744 len
= strlen(funcname
) + 1;
3745 /* generate char[len] type */
3750 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
3751 ptr
= section_ptr_add(data_section
, len
);
3752 memcpy(ptr
, funcname
, len
);
3757 #ifdef TCC_TARGET_PE
3758 t
= VT_SHORT
| VT_UNSIGNED
;
3764 /* string parsing */
3767 if (tcc_state
->warn_write_strings
)
3772 memset(&ad
, 0, sizeof(AttributeDef
));
3773 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, NULL
, 0);
3778 if (parse_btype(&type
, &ad
)) {
3779 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
3781 /* check ISOC99 compound literal */
3783 /* data is allocated locally by default */
3788 /* all except arrays are lvalues */
3789 if (!(type
.t
& VT_ARRAY
))
3790 r
|= lvalue_type(type
.t
);
3791 memset(&ad
, 0, sizeof(AttributeDef
));
3792 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, NULL
, 0);
3794 if (sizeof_caller
) {
3801 } else if (tok
== '{') {
3804 tcc_error("statement expression in global scope"); */
3805 /* this check breaks compilation of the linux 2.4.26 with the meesage:
3806 linux/include/net/tcp.h:945: error: statement expression in global scope */
3808 /* save all registers */
3810 /* statement expression : we do not accept break/continue
3811 inside as GCC does */
3812 block(NULL
, NULL
, NULL
, NULL
, 0, 1);
3827 /* functions names must be treated as function pointers,
3828 except for unary '&' and sizeof. Since we consider that
3829 functions are not lvalues, we only have to handle it
3830 there and in function calls. */
3831 /* arrays can also be used although they are not lvalues */
3832 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
3833 !(vtop
->type
.t
& VT_ARRAY
) && !(vtop
->type
.t
& VT_LLOCAL
))
3835 mk_pointer(&vtop
->type
);
3841 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3843 boolean
.t
= VT_BOOL
;
3845 vtop
->c
.i
= !vtop
->c
.i
;
3846 } else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
3847 vtop
->c
.i
= vtop
->c
.i
^ 1;
3848 else if (!nocode_wanted
) {
3850 vseti(VT_JMP
, gvtst(1, 0));
3864 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
3865 tcc_error("pointer not accepted for unary plus");
3866 /* In order to force cast, we add zero, except for floating point
3867 where we really need an noop (otherwise -0.0 will be transformed
3869 if (!is_float(vtop
->type
.t
)) {
3880 unary_type(&type
); // Perform a in_sizeof = 0;
3881 size
= type_size(&type
, &align
);
3882 if (t
== TOK_SIZEOF
) {
3883 if (!(type
.t
& VT_VLA
)) {
3885 tcc_error("sizeof applied to an incomplete type");
3888 vla_runtime_type_size(&type
, &align
);
3893 vtop
->type
.t
|= VT_UNSIGNED
;
3896 case TOK_builtin_types_compatible_p
:
3905 type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
3906 type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
3907 vpushi(is_compatible_types(&type1
, &type2
));
3910 case TOK_builtin_constant_p
:
3912 int saved_nocode_wanted
, res
;
3915 saved_nocode_wanted
= nocode_wanted
;
3918 res
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3920 nocode_wanted
= saved_nocode_wanted
;
3925 case TOK_builtin_frame_address
:
3926 case TOK_builtin_return_address
:
3933 if (tok
!= TOK_CINT
|| tokc
.i
< 0) {
3934 tcc_error("%s only takes positive integers",
3935 tok1
== TOK_builtin_return_address
?
3936 "__builtin_return_address" :
3937 "__builtin_frame_address");
3944 vset(&type
, VT_LOCAL
, 0); /* local frame */
3946 mk_pointer(&vtop
->type
);
3947 indir(); /* -> parent frame */
3949 if (tok1
== TOK_builtin_return_address
) {
3950 // assume return address is just above frame pointer on stack
3953 mk_pointer(&vtop
->type
);
3958 #ifdef TCC_TARGET_X86_64
3959 #ifdef TCC_TARGET_PE
3960 case TOK_builtin_va_start
:
3968 if ((vtop
->r
& VT_VALMASK
) != VT_LOCAL
)
3969 tcc_error("__builtin_va_start expects a local variable");
3970 vtop
->r
&= ~(VT_LVAL
| VT_REF
);
3971 vtop
->type
= char_pointer_type
;
3976 case TOK_builtin_va_arg_types
:
3983 vpushi(classify_x86_64_va_arg(&type
));
3989 #ifdef TCC_TARGET_ARM64
3990 case TOK___va_start
: {
3992 tcc_error("statement in global scope");
4002 vtop
->type
.t
= VT_VOID
;
4005 case TOK___va_arg
: {
4007 tcc_error("statement in global scope");
4020 case TOK___arm64_clear_cache
: {
4029 vtop
->type
.t
= VT_VOID
;
4033 /* pre operations */
4044 t
= vtop
->type
.t
& VT_BTYPE
;
4046 /* In IEEE negate(x) isn't subtract(0,x), but rather
4051 else if (t
== VT_DOUBLE
)
4062 goto tok_identifier
;
4064 /* allow to take the address of a label */
4065 if (tok
< TOK_UIDENT
)
4066 expect("label identifier");
4067 s
= label_find(tok
);
4069 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
4071 if (s
->r
== LABEL_DECLARED
)
4072 s
->r
= LABEL_FORWARD
;
4075 s
->type
.t
= VT_VOID
;
4076 mk_pointer(&s
->type
);
4077 s
->type
.t
|= VT_STATIC
;
4079 vpushsym(&s
->type
, s
);
4083 // special qnan , snan and infinity values
4085 vpush64(VT_DOUBLE
, 0x7ff8000000000000ULL
);
4089 vpush64(VT_DOUBLE
, 0x7ff0000000000001ULL
);
4093 vpush64(VT_DOUBLE
, 0x7ff0000000000000ULL
);
4102 expect("identifier");
4105 const char *name
= get_tok_str(t
, NULL
);
4107 tcc_error("'%s' undeclared", name
);
4108 /* for simple function calls, we tolerate undeclared
4109 external reference to int() function */
4110 if (tcc_state
->warn_implicit_function_declaration
4111 #ifdef TCC_TARGET_PE
4112 /* people must be warned about using undeclared WINAPI functions
4113 (which usually start with uppercase letter) */
4114 || (name
[0] >= 'A' && name
[0] <= 'Z')
4117 tcc_warning("implicit declaration of function '%s'", name
);
4118 s
= external_global_sym(t
, &func_old_type
, 0);
4120 if ((s
->type
.t
& (VT_STATIC
| VT_INLINE
| VT_BTYPE
)) ==
4121 (VT_STATIC
| VT_INLINE
| VT_FUNC
)) {
4122 /* if referencing an inline function, then we generate a
4123 symbol to it if not already done. It will have the
4124 effect to generate code for it at the end of the
4125 compilation unit. Inline function as always
4126 generated in the text section. */
4128 put_extern_sym(s
, text_section
, 0, 0);
4129 r
= VT_SYM
| VT_CONST
;
4133 vset(&s
->type
, r
, s
->c
);
4134 /* if forward reference, we must point to s */
4135 if (vtop
->r
& VT_SYM
) {
4137 vtop
->c
.ptr_offset
= 0;
4142 /* post operations */
4144 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
4147 } else if (tok
== '.' || tok
== TOK_ARROW
) {
4150 if (tok
== TOK_ARROW
)
4152 qualifiers
= vtop
->type
.t
& (VT_CONSTANT
| VT_VOLATILE
);
4156 /* expect pointer on structure */
4157 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
4158 expect("struct or union");
4162 while ((s
= s
->next
) != NULL
) {
4167 tcc_error("field not found: %s", get_tok_str(tok
& ~SYM_FIELD
, NULL
));
4168 /* add field offset to pointer */
4169 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
4172 /* change type to field type, and set to lvalue */
4173 vtop
->type
= s
->type
;
4174 vtop
->type
.t
|= qualifiers
;
4175 /* an array is never an lvalue */
4176 if (!(vtop
->type
.t
& VT_ARRAY
)) {
4177 vtop
->r
|= lvalue_type(vtop
->type
.t
);
4178 #ifdef CONFIG_TCC_BCHECK
4179 /* if bound checking, the referenced pointer must be checked */
4180 if (tcc_state
->do_bounds_check
)
4181 vtop
->r
|= VT_MUSTBOUND
;
4185 } else if (tok
== '[') {
4191 } else if (tok
== '(') {
4194 int nb_args
, ret_nregs
, ret_align
, regsize
, variadic
;
4197 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
4198 /* pointer test (no array accepted) */
4199 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
4200 vtop
->type
= *pointed_type(&vtop
->type
);
4201 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
4205 expect("function pointer");
4208 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
4210 /* get return type */
4213 sa
= s
->next
; /* first parameter */
4216 /* compute first implicit argument if a structure is returned */
4217 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
4218 variadic
= (s
->c
== FUNC_ELLIPSIS
);
4219 ret_nregs
= gfunc_sret(&s
->type
, variadic
, &ret
.type
,
4220 &ret_align
, ®size
);
4222 /* get some space for the returned structure */
4223 size
= type_size(&s
->type
, &align
);
4224 #ifdef TCC_TARGET_ARM64
4225 /* On arm64, a small struct is return in registers.
4226 It is much easier to write it to memory if we know
4227 that we are allowed to write some extra bytes, so
4228 round the allocated space up to a power of 2: */
4230 while (size
& (size
- 1))
4231 size
= (size
| (size
- 1)) + 1;
4233 loc
= (loc
- size
) & -align
;
4235 ret
.r
= VT_LOCAL
| VT_LVAL
;
4236 /* pass it as 'int' to avoid structure arg passing
4238 vseti(VT_LOCAL
, loc
);
4248 /* return in register */
4249 if (is_float(ret
.type
.t
)) {
4250 ret
.r
= reg_fret(ret
.type
.t
);
4251 #ifdef TCC_TARGET_X86_64
4252 if ((ret
.type
.t
& VT_BTYPE
) == VT_QFLOAT
)
4256 #ifndef TCC_TARGET_ARM64
4257 #ifdef TCC_TARGET_X86_64
4258 if ((ret
.type
.t
& VT_BTYPE
) == VT_QLONG
)
4260 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
4271 gfunc_param_typed(s
, sa
);
4281 tcc_error("too few arguments to function");
4283 if (!nocode_wanted
) {
4284 gfunc_call(nb_args
);
4286 vtop
-= (nb_args
+ 1);
4290 for (r
= ret
.r
+ ret_nregs
+ !ret_nregs
; r
-- > ret
.r
;) {
4291 vsetc(&ret
.type
, r
, &ret
.c
);
4292 vtop
->r2
= ret
.r2
; /* Loop only happens when r2 is VT_CONST */
4295 /* handle packed struct return */
4296 if (((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) && ret_nregs
) {
4299 size
= type_size(&s
->type
, &align
);
4300 /* We're writing whole regs often, make sure there's enough
4301 space. Assume register size is power of 2. */
4302 if (regsize
> align
)
4304 loc
= (loc
- size
) & -align
;
4308 vset(&ret
.type
, VT_LOCAL
| VT_LVAL
, addr
+ offset
);
4312 if (--ret_nregs
== 0)
4316 vset(&s
->type
, VT_LOCAL
| VT_LVAL
, addr
);
4324 ST_FUNC
void expr_prod(void)
4329 while (tok
== '*' || tok
== '/' || tok
== '%') {
4337 ST_FUNC
void expr_sum(void)
4342 while (tok
== '+' || tok
== '-') {
4350 static void expr_shift(void)
4355 while (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
4363 static void expr_cmp(void)
4368 while ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
4369 tok
== TOK_ULT
|| tok
== TOK_UGE
) {
4377 static void expr_cmpeq(void)
4382 while (tok
== TOK_EQ
|| tok
== TOK_NE
) {
4390 static void expr_and(void)
4393 while (tok
== '&') {
4400 static void expr_xor(void)
4403 while (tok
== '^') {
4410 static void expr_or(void)
4413 while (tok
== '|') {
4420 /* XXX: fix this mess */
4421 static void expr_land_const(void)
4424 while (tok
== TOK_LAND
) {
4431 /* XXX: fix this mess */
4432 static void expr_lor_const(void)
4435 while (tok
== TOK_LOR
) {
4442 /* only used if non constant */
4443 static void expr_land(void)
4448 if (tok
== TOK_LAND
) {
4453 if (tok
!= TOK_LAND
) {
4463 static void expr_lor(void)
4468 if (tok
== TOK_LOR
) {
4473 if (tok
!= TOK_LOR
) {
4483 /* XXX: better constant handling */
4484 static void expr_cond(void)
4486 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
4488 CType type
, type1
, type2
;
4495 boolean
.t
= VT_BOOL
;
4501 if (tok
!= ':' || !gnu_ext
) {
4516 if (vtop
!= vstack
) {
4517 /* needed to avoid having different registers saved in
4519 if (is_float(vtop
->type
.t
)) {
4521 #ifdef TCC_TARGET_X86_64
4522 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LDOUBLE
) {
4532 if (tok
== ':' && gnu_ext
) {
4540 sv
= *vtop
; /* save value to handle it later */
4541 vtop
--; /* no vpop so that FP stack is not flushed */
4549 bt1
= t1
& VT_BTYPE
;
4551 bt2
= t2
& VT_BTYPE
;
4552 /* cast operands to correct type according to ISOC rules */
4553 if (is_float(bt1
) || is_float(bt2
)) {
4554 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
4555 type
.t
= VT_LDOUBLE
;
4556 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
4561 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
4562 /* cast to biggest op */
4564 /* convert to unsigned if it does not fit in a long long */
4565 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
4566 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
4567 type
.t
|= VT_UNSIGNED
;
4568 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
4569 /* If one is a null ptr constant the result type
4571 if (is_null_pointer (vtop
))
4573 else if (is_null_pointer (&sv
))
4575 /* XXX: test pointer compatibility, C99 has more elaborate
4579 } else if (bt1
== VT_FUNC
|| bt2
== VT_FUNC
) {
4580 /* XXX: test function pointer compatibility */
4581 type
= bt1
== VT_FUNC
? type1
: type2
;
4582 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
4583 /* XXX: test structure compatibility */
4584 type
= bt1
== VT_STRUCT
? type1
: type2
;
4585 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
4586 /* NOTE: as an extension, we accept void on only one side */
4589 /* integer operations */
4591 /* convert to unsigned if it does not fit in an integer */
4592 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
4593 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
4594 type
.t
|= VT_UNSIGNED
;
4597 /* now we convert second operand */
4599 if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
4602 if (is_float(type
.t
)) {
4604 #ifdef TCC_TARGET_X86_64
4605 if ((type
.t
& VT_BTYPE
) == VT_LDOUBLE
) {
4609 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
4610 /* for long longs, we use fixed registers to avoid having
4611 to handle a complicated move */
4616 /* this is horrible, but we must also convert first
4620 /* put again first value and cast it */
4623 if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
4626 move_reg(r2
, r1
, type
.t
);
4633 static void expr_eq(void)
4639 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
4640 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
4641 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
4656 ST_FUNC
void gexpr(void)
4667 /* parse an expression and return its type without any side effect. */
4668 static void expr_type(CType
*type
)
4670 int saved_nocode_wanted
;
4672 saved_nocode_wanted
= nocode_wanted
;
4677 nocode_wanted
= saved_nocode_wanted
;
4680 /* parse a unary expression and return its type without any side
4682 static void unary_type(CType
*type
)
4694 /* parse a constant expression and return value in vtop. */
4695 static void expr_const1(void)
4704 /* parse an integer constant and return its value. */
4705 ST_FUNC
int expr_const(void)
4709 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
4710 expect("constant expression");
4716 /* return the label token if current token is a label, otherwise
4718 static int is_label(void)
4722 /* fast test first */
4723 if (tok
< TOK_UIDENT
)
4725 /* no need to save tokc because tok is an identifier */
4732 unget_tok(last_tok
);
4737 static void label_or_decl(int l
)
4741 /* fast test first */
4742 if (tok
>= TOK_UIDENT
)
4744 /* no need to save tokc because tok is an identifier */
4748 unget_tok(last_tok
);
4751 unget_tok(last_tok
);
4756 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
4757 int case_reg
, int is_expr
)
4760 Sym
*s
, *frame_bottom
;
4762 /* generate line number info */
4763 if (tcc_state
->do_debug
&&
4764 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
4765 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
4767 last_line_num
= file
->line_num
;
4771 /* default return value is (void) */
4773 vtop
->type
.t
= VT_VOID
;
4776 if (tok
== TOK_IF
) {
4783 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
4785 if (c
== TOK_ELSE
) {
4789 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
4790 gsym(d
); /* patch else jmp */
4793 } else if (tok
== TOK_WHILE
) {
4801 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
4805 } else if (tok
== '{') {
4807 int block_vla_sp_loc
, *saved_vla_sp_loc
, saved_vla_flags
;
4810 /* record local declaration stack position */
4812 frame_bottom
= sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
4813 frame_bottom
->next
= scope_stack_bottom
;
4814 scope_stack_bottom
= frame_bottom
;
4815 llabel
= local_label_stack
;
4817 /* save VLA state */
4818 block_vla_sp_loc
= *(saved_vla_sp_loc
= vla_sp_loc
);
4819 if (saved_vla_sp_loc
!= &vla_sp_root_loc
)
4820 vla_sp_loc
= &block_vla_sp_loc
;
4822 saved_vla_flags
= vla_flags
;
4823 vla_flags
|= VLA_NEED_NEW_FRAME
;
4825 /* handle local labels declarations */
4826 if (tok
== TOK_LABEL
) {
4829 if (tok
< TOK_UIDENT
)
4830 expect("label identifier");
4831 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
4841 while (tok
!= '}') {
4842 label_or_decl(VT_LOCAL
);
4846 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
4849 /* pop locally defined labels */
4850 label_pop(&local_label_stack
, llabel
);
4852 /* XXX: this solution makes only valgrind happy...
4853 triggered by gcc.c-torture/execute/20000917-1.c */
4855 switch(vtop
->type
.t
& VT_BTYPE
) {
4857 /* this breaks a compilation of the linux kernel v2.4.26 */
4858 /* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */
4859 /* Look a commit a80acab: Display error on statement expressions with complex return type */
4860 /* A pointer is not a complex return type */
4864 for(p
=vtop
->type
.ref
;p
;p
=p
->prev
)
4866 tcc_error("unsupported expression type");
4869 /* pop locally defined symbols */
4870 scope_stack_bottom
= scope_stack_bottom
->next
;
4871 sym_pop(&local_stack
, s
);
4873 /* Pop VLA frames and restore stack pointer if required */
4874 if (saved_vla_sp_loc
!= &vla_sp_root_loc
)
4875 *saved_vla_sp_loc
= block_vla_sp_loc
;
4876 if (vla_sp_loc
!= (saved_vla_sp_loc
== &vla_sp_root_loc
? &vla_sp_root_loc
: &block_vla_sp_loc
)) {
4877 vla_sp_loc
= saved_vla_sp_loc
;
4878 gen_vla_sp_restore(*vla_sp_loc
);
4880 vla_flags
= (vla_flags
& ~VLA_SCOPE_FLAGS
) | (saved_vla_flags
& VLA_SCOPE_FLAGS
);
4883 } else if (tok
== TOK_RETURN
) {
4887 gen_assign_cast(&func_vt
);
4888 #ifdef TCC_TARGET_ARM64
4889 // Perhaps it would be better to use this for all backends:
4892 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
4893 CType type
, ret_type
;
4894 int ret_align
, ret_nregs
, regsize
;
4895 ret_nregs
= gfunc_sret(&func_vt
, func_var
, &ret_type
,
4896 &ret_align
, ®size
);
4897 if (0 == ret_nregs
) {
4898 /* if returning structure, must copy it to implicit
4899 first pointer arg location */
4902 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
4905 /* copy structure value to pointer */
4908 /* returning structure packed into registers */
4909 int r
, size
, addr
, align
;
4910 size
= type_size(&func_vt
,&align
);
4911 if ((vtop
->r
!= (VT_LOCAL
| VT_LVAL
) || (vtop
->c
.i
& (ret_align
-1)))
4912 && (align
& (ret_align
-1))) {
4913 loc
= (loc
- size
) & -align
;
4916 vset(&type
, VT_LOCAL
| VT_LVAL
, addr
);
4919 vset(&ret_type
, VT_LOCAL
| VT_LVAL
, addr
);
4921 vtop
->type
= ret_type
;
4922 if (is_float(ret_type
.t
))
4923 r
= rc_fret(ret_type
.t
);
4929 if (--ret_nregs
== 0)
4931 /* We assume that when a structure is returned in multiple
4932 registers, their classes are consecutive values of the
4935 vtop
->c
.i
+= regsize
;
4936 vtop
->r
= VT_LOCAL
| VT_LVAL
;
4939 } else if (is_float(func_vt
.t
)) {
4940 gv(rc_fret(func_vt
.t
));
4945 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4948 rsym
= gjmp(rsym
); /* jmp */
4949 } else if (tok
== TOK_BREAK
) {
4952 tcc_error("cannot break");
4953 *bsym
= gjmp(*bsym
);
4956 } else if (tok
== TOK_CONTINUE
) {
4959 tcc_error("cannot continue");
4960 *csym
= gjmp(*csym
);
4963 } else if (tok
== TOK_FOR
) {
4968 frame_bottom
= sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
4969 frame_bottom
->next
= scope_stack_bottom
;
4970 scope_stack_bottom
= frame_bottom
;
4972 /* c99 for-loop init decl? */
4973 if (!decl0(VT_LOCAL
, 1)) {
4974 /* no, regular for-loop init expr */
4998 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
5002 scope_stack_bottom
= scope_stack_bottom
->next
;
5003 sym_pop(&local_stack
, s
);
5005 if (tok
== TOK_DO
) {
5010 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
5021 if (tok
== TOK_SWITCH
) {
5025 /* XXX: other types than integer */
5026 case_reg
= gv(RC_INT
);
5030 b
= gjmp(0); /* jump to first case */
5032 block(&a
, csym
, &b
, &c
, case_reg
, 0);
5033 /* if no default, jmp after switch */
5041 if (tok
== TOK_CASE
) {
5048 if (gnu_ext
&& tok
== TOK_DOTS
) {
5052 tcc_warning("empty case range");
5054 /* since a case is like a label, we must skip it with a jmp */
5062 *case_sym
= gtst(1, 0);
5065 *case_sym
= gtst(1, 0);
5069 *case_sym
= gtst(1, *case_sym
);
5071 case_reg
= gv(RC_INT
);
5076 goto block_after_label
;
5078 if (tok
== TOK_DEFAULT
) {
5084 tcc_error("too many 'default'");
5087 goto block_after_label
;
5089 if (tok
== TOK_GOTO
) {
5091 if (tok
== '*' && gnu_ext
) {
5095 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
5098 } else if (tok
>= TOK_UIDENT
) {
5099 s
= label_find(tok
);
5100 /* put forward definition if needed */
5102 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
5104 if (s
->r
== LABEL_DECLARED
)
5105 s
->r
= LABEL_FORWARD
;
5107 /* label already defined */
5108 if (vla_flags
& VLA_IN_SCOPE
) {
5109 /* If VLAs are in use, save the current stack pointer and
5110 reset the stack pointer to what it was at function entry
5111 (label will restore stack pointer in inner scopes) */
5113 gen_vla_sp_restore(vla_sp_root_loc
);
5115 if (s
->r
& LABEL_FORWARD
)
5116 s
->jnext
= gjmp(s
->jnext
);
5118 gjmp_addr(s
->jnext
);
5121 expect("label identifier");
5124 } else if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
5130 if (vla_flags
& VLA_IN_SCOPE
) {
5131 /* save/restore stack pointer across label
5132 this is a no-op when combined with the load immediately
5133 after the label unless we arrive via goto */
5138 if (s
->r
== LABEL_DEFINED
)
5139 tcc_error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
5141 s
->r
= LABEL_DEFINED
;
5143 s
= label_push(&global_label_stack
, b
, LABEL_DEFINED
);
5146 if (vla_flags
& VLA_IN_SCOPE
) {
5147 gen_vla_sp_restore(*vla_sp_loc
);
5148 vla_flags
|= VLA_NEED_NEW_FRAME
;
5150 /* we accept this, but it is a mistake */
5153 tcc_warning("deprecated use of label at end of compound statement");
5157 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
5160 /* expression case */
5175 /* t is the array or struct type. c is the array or struct
5176 address. cur_index/cur_field is the pointer to the current
5177 value. 'size_only' is true if only size info is needed (only used
5179 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
5180 int *cur_index
, Sym
**cur_field
,
5184 int notfirst
, index
, index_last
, align
, l
, nb_elems
, elem_size
;
5190 if (gnu_ext
&& (l
= is_label()) != 0)
5192 while (tok
== '[' || tok
== '.') {
5194 if (!(type
->t
& VT_ARRAY
))
5195 expect("array type");
5198 index
= expr_const();
5199 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
5200 expect("invalid index");
5201 if (tok
== TOK_DOTS
&& gnu_ext
) {
5203 index_last
= expr_const();
5204 if (index_last
< 0 ||
5205 (s
->c
>= 0 && index_last
>= s
->c
) ||
5207 expect("invalid index");
5213 *cur_index
= index_last
;
5214 type
= pointed_type(type
);
5215 elem_size
= type_size(type
, &align
);
5216 c
+= index
* elem_size
;
5217 /* NOTE: we only support ranges for last designator */
5218 nb_elems
= index_last
- index
+ 1;
5219 if (nb_elems
!= 1) {
5228 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
5229 expect("struct/union type");
5242 /* XXX: fix this mess by using explicit storage field */
5244 type1
.t
|= (type
->t
& ~VT_TYPE
);
5258 if (type
->t
& VT_ARRAY
) {
5260 type
= pointed_type(type
);
5261 c
+= index
* type_size(type
, &align
);
5265 tcc_error("too many field init");
5266 /* XXX: fix this mess by using explicit storage field */
5268 type1
.t
|= (type
->t
& ~VT_TYPE
);
5273 decl_initializer(type
, sec
, c
, 0, size_only
);
5275 /* XXX: make it more general */
5276 if (!size_only
&& nb_elems
> 1) {
5277 unsigned long c_end
;
5282 tcc_error("range init not supported yet for dynamic storage");
5283 c_end
= c
+ nb_elems
* elem_size
;
5284 if (c_end
> sec
->data_allocated
)
5285 section_realloc(sec
, c_end
);
5286 src
= sec
->data
+ c
;
5288 for(i
= 1; i
< nb_elems
; i
++) {
5290 memcpy(dst
, src
, elem_size
);
5296 #define EXPR_CONST 1
5299 /* store a value or an expression directly in global data or in local array */
5300 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
5301 int v
, int expr_type
)
5303 int saved_global_expr
, bt
, bit_pos
, bit_size
;
5305 unsigned long long bit_mask
;
5313 /* compound literals must be allocated globally in this case */
5314 saved_global_expr
= global_expr
;
5317 global_expr
= saved_global_expr
;
5318 /* NOTE: symbols are accepted */
5319 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
5320 tcc_error("initializer element is not constant");
5328 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
5331 /* XXX: not portable */
5332 /* XXX: generate error if incorrect relocation */
5333 gen_assign_cast(&dtype
);
5334 bt
= type
->t
& VT_BTYPE
;
5335 /* we'll write at most 16 bytes */
5336 if (c
+ 16 > sec
->data_allocated
) {
5337 section_realloc(sec
, c
+ 16);
5339 ptr
= sec
->data
+ c
;
5340 /* XXX: make code faster ? */
5341 if (!(type
->t
& VT_BITFIELD
)) {
5346 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
5347 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
5348 bit_mask
= (1LL << bit_size
) - 1;
5350 if ((vtop
->r
& VT_SYM
) &&
5356 (bt
== VT_INT
&& bit_size
!= 32)))
5357 tcc_error("initializer element is not computable at load time");
5359 /* XXX: when cross-compiling we assume that each type has the
5360 same representation on host and target, which is likely to
5361 be wrong in the case of long double */
5363 vtop
->c
.i
= (vtop
->c
.i
!= 0);
5365 *(char *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
5368 *(short *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
5371 *(double *)ptr
= vtop
->c
.d
;
5374 *(long double *)ptr
= vtop
->c
.ld
;
5377 *(long long *)ptr
|= (vtop
->c
.ll
& bit_mask
) << bit_pos
;
5380 addr_t val
= (vtop
->c
.ptr_offset
& bit_mask
) << bit_pos
;
5381 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5382 if (vtop
->r
& VT_SYM
)
5383 greloca(sec
, vtop
->sym
, c
, R_DATA_PTR
, val
);
5385 *(addr_t
*)ptr
|= val
;
5387 if (vtop
->r
& VT_SYM
)
5388 greloc(sec
, vtop
->sym
, c
, R_DATA_PTR
);
5389 *(addr_t
*)ptr
|= val
;
5394 int val
= (vtop
->c
.i
& bit_mask
) << bit_pos
;
5395 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5396 if (vtop
->r
& VT_SYM
)
5397 greloca(sec
, vtop
->sym
, c
, R_DATA_PTR
, val
);
5401 if (vtop
->r
& VT_SYM
)
5402 greloc(sec
, vtop
->sym
, c
, R_DATA_PTR
);
5410 vset(&dtype
, VT_LOCAL
|VT_LVAL
, c
);
5417 /* put zeros for variable based init */
5418 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
5421 /* nothing to do because globals are already set to zero */
5423 vpush_global_sym(&func_old_type
, TOK_memset
);
5425 #ifdef TCC_TARGET_ARM
5436 /* 't' contains the type and storage info. 'c' is the offset of the
5437 object in section 'sec'. If 'sec' is NULL, it means stack based
5438 allocation. 'first' is true if array '{' must be read (multi
5439 dimension implicit array init handling). 'size_only' is true if
5440 size only evaluation is wanted (only for arrays). */
5441 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
5442 int first
, int size_only
)
5444 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, parlevel1
, i
;
5445 int size1
, align1
, expr_type
;
5449 if (type
->t
& VT_VLA
) {
5452 /* save current stack pointer */
5453 if (vla_flags
& VLA_NEED_NEW_FRAME
) {
5455 vla_flags
= VLA_IN_SCOPE
;
5456 vla_sp_loc
= &vla_sp_loc_tmp
;
5459 vla_runtime_type_size(type
, &a
);
5460 gen_vla_alloc(type
, a
);
5461 vset(type
, VT_LOCAL
|VT_LVAL
, c
);
5465 } else if (type
->t
& VT_ARRAY
) {
5469 t1
= pointed_type(type
);
5470 size1
= type_size(t1
, &align1
);
5473 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
5476 tcc_error("character array initializer must be a literal,"
5477 " optionally enclosed in braces");
5482 /* only parse strings here if correct type (otherwise: handle
5483 them as ((w)char *) expressions */
5484 if ((tok
== TOK_LSTR
&&
5485 #ifdef TCC_TARGET_PE
5486 (t1
->t
& VT_BTYPE
) == VT_SHORT
&& (t1
->t
& VT_UNSIGNED
)
5488 (t1
->t
& VT_BTYPE
) == VT_INT
5490 ) || (tok
== TOK_STR
&& (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
5491 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5496 /* compute maximum number of chars wanted */
5498 cstr_len
= cstr
->size
;
5500 cstr_len
= cstr
->size
/ sizeof(nwchar_t
);
5503 if (n
>= 0 && nb
> (n
- array_length
))
5504 nb
= n
- array_length
;
5507 tcc_warning("initializer-string for array is too long");
5508 /* in order to go faster for common case (char
5509 string in global variable, we handle it
5511 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
5512 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
5516 ch
= ((unsigned char *)cstr
->data
)[i
];
5518 ch
= ((nwchar_t
*)cstr
->data
)[i
];
5519 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
5527 /* only add trailing zero if enough storage (no
5528 warning in this case since it is standard) */
5529 if (n
< 0 || array_length
< n
) {
5531 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
5537 while (tok
!= '}') {
5538 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
5539 if (n
>= 0 && index
>= n
)
5540 tcc_error("index too large");
5541 /* must put zero in holes (note that doing it that way
5542 ensures that it even works with designators) */
5543 if (!size_only
&& array_length
< index
) {
5544 init_putz(t1
, sec
, c
+ array_length
* size1
,
5545 (index
- array_length
) * size1
);
5548 if (index
> array_length
)
5549 array_length
= index
;
5550 /* special test for multi dimensional arrays (may not
5551 be strictly correct if designators are used at the
5553 if (index
>= n
&& no_oblock
)
5562 /* put zeros at the end */
5563 if (!size_only
&& n
>= 0 && array_length
< n
) {
5564 init_putz(t1
, sec
, c
+ array_length
* size1
,
5565 (n
- array_length
) * size1
);
5567 /* patch type size if needed */
5569 s
->c
= array_length
;
5570 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&&
5571 (sec
|| !first
|| tok
== '{')) {
5573 /* NOTE: the previous test is a specific case for automatic
5574 struct/union init */
5575 /* XXX: union needs only one init */
5582 if (tcc_state
->old_struct_init_code
) {
5583 /* an old version of struct initialization.
5584 It have a problems. But with a new version
5585 linux 2.4.26 can't load ramdisk.
5587 while (tok
== '(') {
5591 if (!parse_btype(&type1
, &ad1
))
5593 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
5595 if (!is_assignable_types(type
, &type1
))
5596 tcc_error("invalid type for cast");
5603 if (!parse_btype(&type1
, &ad1
))
5605 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
5607 if (!is_assignable_types(type
, &type1
))
5608 tcc_error("invalid type for cast");
5617 if (first
|| tok
== '{') {
5626 while (tok
!= '}') {
5627 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
5629 if (!size_only
&& array_length
< index
) {
5630 init_putz(type
, sec
, c
+ array_length
,
5631 index
- array_length
);
5633 index
= index
+ type_size(&f
->type
, &align1
);
5634 if (index
> array_length
)
5635 array_length
= index
;
5637 /* gr: skip fields from same union - ugly. */
5640 int f_size
= type_size(&f
->type
, &align
);
5641 int f_type
= (f
->type
.t
& VT_BTYPE
);
5643 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5644 /* test for same offset */
5645 if (f
->next
->c
!= f
->c
)
5647 if ((f_type
== VT_STRUCT
) && (f_size
== 0)) {
5649 Lets assume a structure of size 0 can't be a member of the union.
5650 This allow to compile the following code from a linux kernel v2.4.26
5651 typedef struct { } rwlock_t;
5657 struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, };
5658 tcc-0.9.23 can succesfully compile this version of the kernel.
5659 gcc don't have problems with this code too.
5663 /* if yes, test for bitfield shift */
5664 if ((f
->type
.t
& VT_BITFIELD
) && (f
->next
->type
.t
& VT_BITFIELD
)) {
5665 int bit_pos_1
= (f
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
5666 int bit_pos_2
= (f
->next
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
5667 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5668 if (bit_pos_1
!= bit_pos_2
)
5675 if (no_oblock
&& f
== NULL
)
5681 /* put zeros at the end */
5682 if (!size_only
&& array_length
< n
) {
5683 init_putz(type
, sec
, c
+ array_length
,
5692 } else if (tok
== '{') {
5694 decl_initializer(type
, sec
, c
, first
, size_only
);
5696 } else if (size_only
) {
5697 /* just skip expression */
5698 parlevel
= parlevel1
= 0;
5699 while ((parlevel
> 0 || parlevel1
> 0 ||
5700 (tok
!= '}' && tok
!= ',')) && tok
!= -1) {
5703 else if (tok
== ')') {
5704 if (parlevel
== 0 && parlevel1
== 0)
5708 else if (tok
== '{')
5710 else if (tok
== '}') {
5711 if (parlevel
== 0 && parlevel1
== 0)
5718 /* currently, we always use constant expression for globals
5719 (may change for scripting case) */
5720 expr_type
= EXPR_CONST
;
5722 expr_type
= EXPR_ANY
;
5723 init_putv(type
, sec
, c
, 0, expr_type
);
5727 /* parse an initializer for type 't' if 'has_init' is non zero, and
5728 allocate space in local or global data space ('r' is either
5729 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5730 variable 'v' with an associated name represented by 'asm_label' of
5731 scope 'scope' is declared before initializers are parsed. If 'v' is
5732 zero, then a reference to the new object is put in the value stack.
5733 If 'has_init' is 2, a special parsing is done to handle string
5735 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
5736 int has_init
, int v
, char *asm_label
,
5739 int size
, align
, addr
, data_offset
;
5741 ParseState saved_parse_state
= {0};
5742 TokenString init_str
;
5744 Sym
*flexible_array
;
5746 flexible_array
= NULL
;
5747 if ((type
->t
& VT_BTYPE
) == VT_STRUCT
) {
5748 Sym
*field
= type
->ref
->next
;
5751 field
= field
->next
;
5752 if (field
->type
.t
& VT_ARRAY
&& field
->type
.ref
->c
< 0)
5753 flexible_array
= field
;
5757 size
= type_size(type
, &align
);
5758 /* If unknown size, we must evaluate it before
5759 evaluating initializers because
5760 initializers can generate global data too
5761 (e.g. string pointers or ISOC99 compound
5762 literals). It also simplifies local
5763 initializers handling */
5764 tok_str_new(&init_str
);
5765 if (size
< 0 || (flexible_array
&& has_init
)) {
5767 tcc_error("unknown type size");
5768 /* get all init string */
5769 if (has_init
== 2) {
5770 /* only get strings */
5771 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5772 tok_str_add_tok(&init_str
);
5777 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
5779 tcc_error("unexpected end of file in initializer");
5780 tok_str_add_tok(&init_str
);
5783 else if (tok
== '}') {
5793 tok_str_add(&init_str
, -1);
5794 tok_str_add(&init_str
, 0);
5797 save_parse_state(&saved_parse_state
);
5799 macro_ptr
= init_str
.str
;
5801 decl_initializer(type
, NULL
, 0, 1, 1);
5802 /* prepare second initializer parsing */
5803 macro_ptr
= init_str
.str
;
5806 /* if still unknown size, error */
5807 size
= type_size(type
, &align
);
5809 tcc_error("unknown type size");
5812 size
+= flexible_array
->type
.ref
->c
* pointed_size(&flexible_array
->type
);
5813 /* take into account specified alignment if bigger */
5814 if (ad
->a
.aligned
) {
5815 if (ad
->a
.aligned
> align
)
5816 align
= ad
->a
.aligned
;
5817 } else if (ad
->a
.packed
) {
5820 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
5822 #ifdef CONFIG_TCC_BCHECK
5823 if (tcc_state
->do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
5827 loc
= (loc
- size
) & -align
;
5829 #ifdef CONFIG_TCC_BCHECK
5830 /* handles bounds */
5831 /* XXX: currently, since we do only one pass, we cannot track
5832 '&' operators, so we add only arrays */
5833 if (tcc_state
->do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
5835 /* add padding between regions */
5837 /* then add local bound info */
5838 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(addr_t
));
5839 bounds_ptr
[0] = addr
;
5840 bounds_ptr
[1] = size
;
5844 /* local variable */
5845 sym_push(v
, type
, r
, addr
);
5847 /* push local reference */
5848 vset(type
, r
, addr
);
5854 if (v
&& scope
== VT_CONST
) {
5855 /* see if the symbol was already defined */
5858 if (!is_compatible_types(&sym
->type
, type
))
5859 tcc_error("incompatible types for redefinition of '%s'",
5860 get_tok_str(v
, NULL
));
5861 if (sym
->type
.t
& VT_EXTERN
) {
5862 /* if the variable is extern, it was not allocated */
5863 sym
->type
.t
&= ~VT_EXTERN
;
5864 /* set array size if it was omitted in extern
5866 if ((sym
->type
.t
& VT_ARRAY
) &&
5867 sym
->type
.ref
->c
< 0 &&
5869 sym
->type
.ref
->c
= type
->ref
->c
;
5871 /* we accept several definitions of the same
5872 global variable. this is tricky, because we
5873 must play with the SHN_COMMON type of the symbol */
5874 /* XXX: should check if the variable was already
5875 initialized. It is incorrect to initialized it
5877 /* no init data, we won't add more to the symbol */
5884 /* allocate symbol in corresponding section */
5889 else if (tcc_state
->nocommon
)
5893 data_offset
= sec
->data_offset
;
5894 data_offset
= (data_offset
+ align
- 1) & -align
;
5896 /* very important to increment global pointer at this time
5897 because initializers themselves can create new initializers */
5898 data_offset
+= size
;
5899 #ifdef CONFIG_TCC_BCHECK
5900 /* add padding if bound check */
5901 if (tcc_state
->do_bounds_check
)
5904 sec
->data_offset
= data_offset
;
5905 /* allocate section space to put the data */
5906 if (sec
->sh_type
!= SHT_NOBITS
&&
5907 data_offset
> sec
->data_allocated
)
5908 section_realloc(sec
, data_offset
);
5909 /* align section if needed */
5910 if (align
> sec
->sh_addralign
)
5911 sec
->sh_addralign
= align
;
5913 addr
= 0; /* avoid warning */
5917 if (scope
!= VT_CONST
|| !sym
) {
5918 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
5919 sym
->asm_label
= asm_label
;
5921 /* update symbol definition */
5923 put_extern_sym(sym
, sec
, addr
, size
);
5926 /* put a common area */
5927 put_extern_sym(sym
, NULL
, align
, size
);
5928 /* XXX: find a nicer way */
5929 esym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym
->c
];
5930 esym
->st_shndx
= SHN_COMMON
;
5933 /* push global reference */
5934 sym
= get_sym_ref(type
, sec
, addr
, size
);
5935 vpushsym(type
, sym
);
5937 /* patch symbol weakness */
5938 if (type
->t
& VT_WEAK
)
5940 apply_visibility(sym
, type
);
5941 #ifdef CONFIG_TCC_BCHECK
5942 /* handles bounds now because the symbol must be defined
5943 before for the relocation */
5944 if (tcc_state
->do_bounds_check
) {
5947 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_PTR
);
5948 /* then add global bound info */
5949 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(addr_t
));
5950 bounds_ptr
[0] = 0; /* relocated */
5951 bounds_ptr
[1] = size
;
5955 if (has_init
|| (type
->t
& VT_VLA
)) {
5956 decl_initializer(type
, sec
, addr
, 1, 0);
5957 /* restore parse state if needed */
5959 tok_str_free(init_str
.str
);
5960 restore_parse_state(&saved_parse_state
);
5962 /* patch flexible array member size back to -1, */
5963 /* for possible subsequent similar declarations */
5965 flexible_array
->type
.ref
->c
= -1;
5970 static void put_func_debug(Sym
*sym
)
5975 /* XXX: we put here a dummy type */
5976 snprintf(buf
, sizeof(buf
), "%s:%c1",
5977 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
5978 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
5979 cur_text_section
, sym
->c
);
5980 /* //gr gdb wants a line at the function */
5981 put_stabn(N_SLINE
, 0, file
->line_num
, 0);
5986 /* parse an old style function declaration list */
5987 /* XXX: check multiple parameter */
5988 static void func_decl_list(Sym
*func_sym
)
5995 /* parse each declaration */
5996 while (tok
!= '{' && tok
!= ';' && tok
!= ',' && tok
!= TOK_EOF
&&
5997 tok
!= TOK_ASM1
&& tok
!= TOK_ASM2
&& tok
!= TOK_ASM3
) {
5998 if (!parse_btype(&btype
, &ad
))
5999 expect("declaration list");
6000 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
6001 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
6003 /* we accept no variable after */
6007 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
6008 /* find parameter in function parameter list */
6011 if ((s
->v
& ~SYM_FIELD
) == v
)
6015 tcc_error("declaration for parameter '%s' but no such parameter",
6016 get_tok_str(v
, NULL
));
6018 /* check that no storage specifier except 'register' was given */
6019 if (type
.t
& VT_STORAGE
)
6020 tcc_error("storage class specified for '%s'", get_tok_str(v
, NULL
));
6021 convert_parameter_type(&type
);
6022 /* we can add the type (NOTE: it could be local to the function) */
6024 /* accept other parameters */
6035 /* parse a function defined by symbol 'sym' and generate its code in
6036 'cur_text_section' */
6037 static void gen_function(Sym
*sym
)
6039 int saved_nocode_wanted
= nocode_wanted
;
6041 ind
= cur_text_section
->data_offset
;
6042 /* NOTE: we patch the symbol size later */
6043 put_extern_sym(sym
, cur_text_section
, ind
, 0);
6044 funcname
= get_tok_str(sym
->v
, NULL
);
6046 /* Initialize VLA state */
6047 vla_sp_loc
= &vla_sp_root_loc
;
6048 vla_flags
= VLA_NEED_NEW_FRAME
;
6049 /* put debug symbol */
6050 if (tcc_state
->do_debug
)
6051 put_func_debug(sym
);
6052 /* push a dummy symbol to enable local sym storage */
6053 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
6054 gfunc_prolog(&sym
->type
);
6055 #ifdef CONFIG_TCC_BCHECK
6056 if (tcc_state
->do_bounds_check
6057 && !strcmp(get_tok_str(sym
->v
, NULL
), "main")) {
6061 for (i
= 0, sym
= local_stack
; i
< 2; i
++, sym
= sym
->prev
) {
6062 if (sym
->v
& SYM_FIELD
|| sym
->prev
->v
& SYM_FIELD
)
6064 vpush_global_sym(&func_old_type
, TOK___bound_main_arg
);
6065 vset(&sym
->type
, sym
->r
, sym
->c
);
6071 block(NULL
, NULL
, NULL
, NULL
, 0, 0);
6074 cur_text_section
->data_offset
= ind
;
6075 label_pop(&global_label_stack
, NULL
);
6076 /* reset local stack */
6077 scope_stack_bottom
= NULL
;
6078 sym_pop(&local_stack
, NULL
);
6079 /* end of function */
6080 /* patch symbol size */
6081 ((ElfW(Sym
) *)symtab_section
->data
)[sym
->c
].st_size
=
6083 /* patch symbol weakness (this definition overrules any prototype) */
6084 if (sym
->type
.t
& VT_WEAK
)
6086 apply_visibility(sym
, &sym
->type
);
6087 if (tcc_state
->do_debug
) {
6088 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
6090 /* It's better to crash than to generate wrong code */
6091 cur_text_section
= NULL
;
6092 funcname
= ""; /* for safety */
6093 func_vt
.t
= VT_VOID
; /* for safety */
6094 func_var
= 0; /* for safety */
6095 ind
= 0; /* for safety */
6096 nocode_wanted
= saved_nocode_wanted
;
6099 ST_FUNC
void gen_inline_functions(void)
6102 int *str
, inline_generated
, i
;
6103 struct InlineFunc
*fn
;
6105 /* iterate while inline function are referenced */
6107 inline_generated
= 0;
6108 for (i
= 0; i
< tcc_state
->nb_inline_fns
; ++i
) {
6109 fn
= tcc_state
->inline_fns
[i
];
6111 if (sym
&& sym
->c
) {
6112 /* the function was used: generate its code and
6113 convert it to a normal function */
6114 str
= fn
->token_str
;
6117 pstrcpy(file
->filename
, sizeof file
->filename
, fn
->filename
);
6118 sym
->r
= VT_SYM
| VT_CONST
;
6119 sym
->type
.t
&= ~VT_INLINE
;
6123 cur_text_section
= text_section
;
6125 macro_ptr
= NULL
; /* fail safe */
6127 inline_generated
= 1;
6130 if (!inline_generated
)
6133 for (i
= 0; i
< tcc_state
->nb_inline_fns
; ++i
) {
6134 fn
= tcc_state
->inline_fns
[i
];
6135 str
= fn
->token_str
;
6138 dynarray_reset(&tcc_state
->inline_fns
, &tcc_state
->nb_inline_fns
);
6141 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6142 static int decl0(int l
, int is_for_loop_init
)
6150 if (!parse_btype(&btype
, &ad
)) {
6151 if (is_for_loop_init
)
6153 /* skip redundant ';' */
6154 /* XXX: find more elegant solution */
6159 if (l
== VT_CONST
&&
6160 (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
6161 /* global asm block */
6165 /* special test for old K&R protos without explicit int
6166 type. Only accepted when defining global data */
6167 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
6171 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
6172 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
6174 if ((btype
.t
& VT_BTYPE
) == VT_STRUCT
) {
6175 int v
= btype
.ref
->v
;
6176 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
)
6177 tcc_warning("unnamed struct/union that defines no instances");
6182 while (1) { /* iterate thru each declaration */
6183 char *asm_label
; // associated asm label
6185 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
6189 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
6190 printf("type = '%s'\n", buf
);
6193 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
6194 if ((type
.t
& VT_STATIC
) && (l
== VT_LOCAL
)) {
6195 tcc_error("function without file scope cannot be static");
6197 /* if old style function prototype, we accept a
6200 if (sym
->c
== FUNC_OLD
)
6201 func_decl_list(sym
);
6205 if (gnu_ext
&& (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
6208 asm_label_instr(&astr
);
6209 asm_label
= tcc_strdup(astr
.data
);
6212 /* parse one last attribute list, after asm label */
6213 parse_attribute(&ad
);
6218 #ifdef TCC_TARGET_PE
6219 if (ad
.a
.func_import
)
6220 type
.t
|= VT_IMPORT
;
6221 if (ad
.a
.func_export
)
6222 type
.t
|= VT_EXPORT
;
6224 type
.t
|= ad
.a
.visibility
<< VT_VIS_SHIFT
;
6228 tcc_error("cannot use local functions");
6229 if ((type
.t
& VT_BTYPE
) != VT_FUNC
)
6230 expect("function definition");
6232 /* reject abstract declarators in function definition */
6234 while ((sym
= sym
->next
) != NULL
)
6235 if (!(sym
->v
& ~SYM_FIELD
))
6236 expect("identifier");
6238 /* XXX: cannot do better now: convert extern line to static inline */
6239 if ((type
.t
& (VT_EXTERN
| VT_INLINE
)) == (VT_EXTERN
| VT_INLINE
))
6240 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
6245 if ((sym
->type
.t
& VT_BTYPE
) != VT_FUNC
)
6248 ref
= sym
->type
.ref
;
6249 if (0 == ref
->a
.func_proto
)
6250 tcc_error("redefinition of '%s'", get_tok_str(v
, NULL
));
6252 /* use func_call from prototype if not defined */
6253 if (ref
->a
.func_call
!= FUNC_CDECL
6254 && type
.ref
->a
.func_call
== FUNC_CDECL
)
6255 type
.ref
->a
.func_call
= ref
->a
.func_call
;
6257 /* use export from prototype */
6258 if (ref
->a
.func_export
)
6259 type
.ref
->a
.func_export
= 1;
6261 /* use static from prototype */
6262 if (sym
->type
.t
& VT_STATIC
)
6263 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
6265 /* If the definition has no visibility use the
6266 one from prototype. */
6267 if (! (type
.t
& VT_VIS_MASK
))
6268 type
.t
|= sym
->type
.t
& VT_VIS_MASK
;
6270 if (!is_compatible_types(&sym
->type
, &type
)) {
6272 tcc_error("incompatible types for redefinition of '%s'",
6273 get_tok_str(v
, NULL
));
6275 type
.ref
->a
.func_proto
= 0;
6276 /* if symbol is already defined, then put complete type */
6279 /* put function symbol */
6280 sym
= global_identifier_push(v
, type
.t
, 0);
6281 sym
->type
.ref
= type
.ref
;
6284 /* static inline functions are just recorded as a kind
6285 of macro. Their code will be emitted at the end of
6286 the compilation unit only if they are used */
6287 if ((type
.t
& (VT_INLINE
| VT_STATIC
)) ==
6288 (VT_INLINE
| VT_STATIC
)) {
6289 TokenString func_str
;
6291 struct InlineFunc
*fn
;
6292 const char *filename
;
6294 tok_str_new(&func_str
);
6300 tcc_error("unexpected end of file");
6301 tok_str_add_tok(&func_str
);
6306 } else if (t
== '}') {
6308 if (block_level
== 0)
6312 tok_str_add(&func_str
, -1);
6313 tok_str_add(&func_str
, 0);
6314 filename
= file
? file
->filename
: "";
6315 fn
= tcc_malloc(sizeof *fn
+ strlen(filename
));
6316 strcpy(fn
->filename
, filename
);
6318 fn
->token_str
= func_str
.str
;
6319 dynarray_add((void ***)&tcc_state
->inline_fns
, &tcc_state
->nb_inline_fns
, fn
);
6322 /* compute text section */
6323 cur_text_section
= ad
.section
;
6324 if (!cur_text_section
)
6325 cur_text_section
= text_section
;
6326 sym
->r
= VT_SYM
| VT_CONST
;
6331 if (btype
.t
& VT_TYPEDEF
) {
6332 /* save typedefed type */
6333 /* XXX: test storage specifiers ? */
6334 sym
= sym_push(v
, &type
, 0, 0);
6336 sym
->type
.t
|= VT_TYPEDEF
;
6339 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
6340 /* external function definition */
6341 /* specific case for func_call attribute */
6342 ad
.a
.func_proto
= 1;
6344 } else if (!(type
.t
& VT_ARRAY
)) {
6345 /* not lvalue if array */
6346 r
|= lvalue_type(type
.t
);
6348 has_init
= (tok
== '=');
6349 if (has_init
&& (type
.t
& VT_VLA
))
6350 tcc_error("Variable length array cannot be initialized");
6351 if ((btype
.t
& VT_EXTERN
) || ((type
.t
& VT_BTYPE
) == VT_FUNC
) ||
6352 ((type
.t
& VT_ARRAY
) && (type
.t
& VT_STATIC
) &&
6353 !has_init
&& l
== VT_CONST
&& type
.ref
->c
< 0)) {
6354 /* external variable or function */
6355 /* NOTE: as GCC, uninitialized global static
6356 arrays of null size are considered as
6358 sym
= external_sym(v
, &type
, r
, asm_label
);
6360 if (ad
.alias_target
) {
6365 alias_target
= sym_find(ad
.alias_target
);
6366 if (!alias_target
|| !alias_target
->c
)
6367 tcc_error("unsupported forward __alias__ attribute");
6368 esym
= &((Elf32_Sym
*)symtab_section
->data
)[alias_target
->c
];
6369 tsec
.sh_num
= esym
->st_shndx
;
6370 put_extern_sym2(sym
, &tsec
, esym
->st_value
, esym
->st_size
, 0);
6373 type
.t
|= (btype
.t
& VT_STATIC
); /* Retain "static". */
6374 if (type
.t
& VT_STATIC
)
6380 decl_initializer_alloc(&type
, &ad
, r
, has_init
, v
, asm_label
, l
);
6384 if (is_for_loop_init
)
6397 ST_FUNC
void decl(int l
)