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
*define_stack
;
54 ST_DATA Sym
*global_label_stack
;
55 ST_DATA Sym
*local_label_stack
;
56 static int local_scope
;
58 ST_DATA
int vlas_in_scope
; /* number of VLAs that are currently in scope */
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 */
62 ST_DATA SValue __vstack
[1+VSTACK_SIZE
], *vtop
, *pvtop
;
64 ST_DATA
int const_wanted
; /* true if constant wanted */
65 ST_DATA
int nocode_wanted
; /* true if no code generation wanted for an expression */
66 ST_DATA
int global_expr
; /* true if compound literals must be allocated globally (used during initializers parsing */
67 ST_DATA CType func_vt
; /* current function return type (used by return instruction) */
68 ST_DATA
int func_var
; /* true if current function is variadic (used by return instruction) */
70 ST_DATA
int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
71 ST_DATA
const char *funcname
;
73 ST_DATA CType char_pointer_type
, func_old_type
, int_type
, size_type
;
75 ST_DATA
struct switch_t
{
78 } **p
; int n
; /* list of case ranges */
79 int def_sym
; /* default symbol */
80 } *cur_switch
; /* current switch */
82 /* ------------------------------------------------------------------------- */
83 static void gen_cast(CType
*type
);
84 static inline CType
*pointed_type(CType
*type
);
85 static int is_compatible_types(CType
*type1
, CType
*type2
);
86 static int parse_btype(CType
*type
, AttributeDef
*ad
);
87 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
88 static void parse_expr_type(CType
*type
);
89 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
, int first
, int size_only
);
90 static void block(int *bsym
, int *csym
, int is_expr
);
91 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
, int has_init
, int v
, int scope
);
92 static int decl0(int l
, int is_for_loop_init
);
93 static void expr_eq(void);
94 static void expr_lor_const(void);
95 static void unary_type(CType
*type
);
96 static void vla_runtime_type_size(CType
*type
, int *a
);
97 static void vla_sp_restore(void);
98 static void vla_sp_restore_root(void);
99 static int is_compatible_parameter_types(CType
*type1
, CType
*type2
);
100 static void expr_type(CType
*type
);
101 ST_FUNC
void vpush64(int ty
, unsigned long long v
);
102 ST_FUNC
void vpush(CType
*type
);
103 ST_FUNC
int gvtst(int inv
, int t
);
104 ST_FUNC
int is_btype_size(int bt
);
106 ST_INLN
int is_float(int t
)
110 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
|| bt
== VT_QFLOAT
;
113 /* we use our own 'finite' function to avoid potential problems with
114 non standard math libs */
115 /* XXX: endianness dependent */
116 ST_FUNC
int ieee_finite(double d
)
119 memcpy(p
, &d
, sizeof(double));
120 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
123 ST_FUNC
void test_lvalue(void)
125 if (!(vtop
->r
& VT_LVAL
))
129 ST_FUNC
void check_vstack(void)
132 tcc_error("internal compiler error: vstack leak (%d)", vtop
- pvtop
);
135 /* ------------------------------------------------------------------------- */
136 /* symbol allocator */
137 static Sym
*__sym_malloc(void)
139 Sym
*sym_pool
, *sym
, *last_sym
;
142 sym_pool
= tcc_malloc(SYM_POOL_NB
* sizeof(Sym
));
143 dynarray_add(&sym_pools
, &nb_sym_pools
, sym_pool
);
145 last_sym
= sym_free_first
;
147 for(i
= 0; i
< SYM_POOL_NB
; i
++) {
148 sym
->next
= last_sym
;
152 sym_free_first
= last_sym
;
156 static inline Sym
*sym_malloc(void)
159 sym
= sym_free_first
;
161 sym
= __sym_malloc();
162 sym_free_first
= sym
->next
;
166 ST_INLN
void sym_free(Sym
*sym
)
168 sym
->next
= sym_free_first
;
169 sym_free_first
= sym
;
172 /* push, without hashing */
173 ST_FUNC Sym
*sym_push2(Sym
**ps
, int v
, int t
, long c
)
193 /* find a symbol and return its associated structure. 's' is the top
194 of the symbol stack */
195 ST_FUNC Sym
*sym_find2(Sym
*s
, int v
)
207 /* structure lookup */
208 ST_INLN Sym
*struct_find(int v
)
211 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
213 return table_ident
[v
]->sym_struct
;
216 /* find an identifier */
217 ST_INLN Sym
*sym_find(int v
)
220 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
222 return table_ident
[v
]->sym_identifier
;
225 /* push a given symbol on the symbol stack */
226 ST_FUNC Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
235 s
= sym_push2(ps
, v
, type
->t
, c
);
236 s
->type
.ref
= type
->ref
;
238 /* don't record fields or anonymous symbols */
240 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
241 /* record symbol in token array */
242 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
244 ps
= &ts
->sym_struct
;
246 ps
= &ts
->sym_identifier
;
249 s
->scope
= local_scope
;
250 if (s
->prev_tok
&& s
->prev_tok
->scope
== s
->scope
)
251 tcc_error("redeclaration of '%s'",
252 get_tok_str(v
& ~SYM_STRUCT
, NULL
));
257 /* push a global identifier */
258 ST_FUNC Sym
*global_identifier_push(int v
, int t
, int c
)
261 s
= sym_push2(&global_stack
, v
, t
, c
);
262 /* don't record anonymous symbol */
263 if (v
< SYM_FIRST_ANOM
) {
264 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
265 /* modify the top most local identifier, so that
266 sym_identifier will point to 's' when popped */
268 ps
= &(*ps
)->prev_tok
;
275 /* pop symbols until top reaches 'b' */
276 ST_FUNC
void sym_pop(Sym
**ptop
, Sym
*b
)
286 /* remove symbol in token array */
288 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
289 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
291 ps
= &ts
->sym_struct
;
293 ps
= &ts
->sym_identifier
;
302 static void weaken_symbol(Sym
*sym
)
304 sym
->type
.t
|= VT_WEAK
;
309 esym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym
->c
];
310 esym_type
= ELFW(ST_TYPE
)(esym
->st_info
);
311 esym
->st_info
= ELFW(ST_INFO
)(STB_WEAK
, esym_type
);
315 static void apply_visibility(Sym
*sym
, CType
*type
)
317 int vis
= sym
->type
.t
& VT_VIS_MASK
;
318 int vis2
= type
->t
& VT_VIS_MASK
;
319 if (vis
== (STV_DEFAULT
<< VT_VIS_SHIFT
))
321 else if (vis2
== (STV_DEFAULT
<< VT_VIS_SHIFT
))
324 vis
= (vis
< vis2
) ? vis
: vis2
;
325 sym
->type
.t
&= ~VT_VIS_MASK
;
331 esym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym
->c
];
332 vis
>>= VT_VIS_SHIFT
;
333 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1)) | vis
;
337 /* ------------------------------------------------------------------------- */
339 ST_FUNC
void swap(int *p
, int *q
)
347 static void vsetc(CType
*type
, int r
, CValue
*vc
)
351 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
352 tcc_error("memory full (vstack)");
353 /* cannot let cpu flags if other instruction are generated. Also
354 avoid leaving VT_JMP anywhere except on the top of the stack
355 because it would complicate the code generator. */
356 if (vtop
>= vstack
) {
357 v
= vtop
->r
& VT_VALMASK
;
358 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
368 /* push constant of type "type" with useless value */
369 ST_FUNC
void vpush(CType
*type
)
372 vsetc(type
, VT_CONST
, &cval
);
375 /* push integer constant */
376 ST_FUNC
void vpushi(int v
)
380 vsetc(&int_type
, VT_CONST
, &cval
);
383 /* push a pointer sized constant */
384 static void vpushs(addr_t v
)
388 vsetc(&size_type
, VT_CONST
, &cval
);
391 /* push arbitrary 64bit constant */
392 ST_FUNC
void vpush64(int ty
, unsigned long long v
)
399 vsetc(&ctype
, VT_CONST
, &cval
);
402 /* push long long constant */
403 static inline void vpushll(long long v
)
405 vpush64(VT_LLONG
, v
);
408 /* push a symbol value of TYPE */
409 static inline void vpushsym(CType
*type
, Sym
*sym
)
413 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
417 /* Return a static symbol pointing to a section */
418 ST_FUNC Sym
*get_sym_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
424 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
425 sym
->type
.ref
= type
->ref
;
426 sym
->r
= VT_CONST
| VT_SYM
;
427 put_extern_sym(sym
, sec
, offset
, size
);
431 /* push a reference to a section offset by adding a dummy symbol */
432 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
434 vpushsym(type
, get_sym_ref(type
, sec
, offset
, size
));
437 /* define a new external reference to a symbol 'v' of type 'u' */
438 ST_FUNC Sym
*external_global_sym(int v
, CType
*type
, int r
)
444 /* push forward reference */
445 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
446 s
->type
.ref
= type
->ref
;
447 s
->r
= r
| VT_CONST
| VT_SYM
;
452 /* define a new external reference to a symbol 'v' */
453 static Sym
*external_sym(int v
, CType
*type
, int r
)
459 /* push forward reference */
460 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
461 s
->type
.t
|= VT_EXTERN
;
462 } else if (s
->type
.ref
== func_old_type
.ref
) {
463 s
->type
.ref
= type
->ref
;
464 s
->r
= r
| VT_CONST
| VT_SYM
;
465 s
->type
.t
|= VT_EXTERN
;
466 } else if (!is_compatible_types(&s
->type
, type
)) {
467 tcc_error("incompatible types for redefinition of '%s'",
468 get_tok_str(v
, NULL
));
470 /* Merge some storage attributes. */
471 if (type
->t
& VT_WEAK
)
474 if (type
->t
& VT_VIS_MASK
)
475 apply_visibility(s
, type
);
480 /* push a reference to global symbol v */
481 ST_FUNC
void vpush_global_sym(CType
*type
, int v
)
483 vpushsym(type
, external_global_sym(v
, type
, 0));
486 ST_FUNC
void vset(CType
*type
, int r
, int v
)
491 vsetc(type
, r
, &cval
);
494 static void vseti(int r
, int v
)
502 ST_FUNC
void vswap(void)
505 /* cannot let cpu flags if other instruction are generated. Also
506 avoid leaving VT_JMP anywhere except on the top of the stack
507 because it would complicate the code generator. */
508 if (vtop
>= vstack
) {
509 int v
= vtop
->r
& VT_VALMASK
;
510 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
517 /* XXX: +2% overall speed possible with optimized memswap
519 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
523 ST_FUNC
void vpushv(SValue
*v
)
525 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
526 tcc_error("memory full (vstack)");
531 static void vdup(void)
536 /* save r to the memory stack, and mark it as being free */
537 ST_FUNC
void save_reg(int r
)
539 int l
, saved
, size
, align
;
543 /* modify all stack values */
546 for(p
=vstack
;p
<=vtop
;p
++) {
547 if ((p
->r
& VT_VALMASK
) == r
||
548 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& (p
->r2
& VT_VALMASK
) == r
)) {
549 /* must save value on stack if not already done */
551 /* NOTE: must reload 'r' because r might be equal to r2 */
552 r
= p
->r
& VT_VALMASK
;
553 /* store register in the stack */
555 if ((p
->r
& VT_LVAL
) ||
556 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
557 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
558 type
= &char_pointer_type
;
562 size
= type_size(type
, &align
);
563 loc
= (loc
- size
) & -align
;
565 sv
.r
= VT_LOCAL
| VT_LVAL
;
568 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
569 /* x86 specific: need to pop fp register ST0 if saved */
571 o(0xd8dd); /* fstp %st(0) */
574 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
575 /* special long long case */
576 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
584 /* mark that stack entry as being saved on the stack */
585 if (p
->r
& VT_LVAL
) {
586 /* also clear the bounded flag because the
587 relocation address of the function was stored in
589 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
591 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
599 #ifdef TCC_TARGET_ARM
600 /* find a register of class 'rc2' with at most one reference on stack.
601 * If none, call get_reg(rc) */
602 ST_FUNC
int get_reg_ex(int rc
, int rc2
)
607 for(r
=0;r
<NB_REGS
;r
++) {
608 if (reg_classes
[r
] & rc2
) {
611 for(p
= vstack
; p
<= vtop
; p
++) {
612 if ((p
->r
& VT_VALMASK
) == r
||
613 (p
->r2
& VT_VALMASK
) == r
)
624 /* find a free register of class 'rc'. If none, save one register */
625 ST_FUNC
int get_reg(int rc
)
630 /* find a free register */
631 for(r
=0;r
<NB_REGS
;r
++) {
632 if (reg_classes
[r
] & rc
) {
633 for(p
=vstack
;p
<=vtop
;p
++) {
634 if ((p
->r
& VT_VALMASK
) == r
||
635 (p
->r2
& VT_VALMASK
) == r
)
643 /* no register left : free the first one on the stack (VERY
644 IMPORTANT to start from the bottom to ensure that we don't
645 spill registers used in gen_opi()) */
646 for(p
=vstack
;p
<=vtop
;p
++) {
647 /* look at second register (if long long) */
648 r
= p
->r2
& VT_VALMASK
;
649 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
651 r
= p
->r
& VT_VALMASK
;
652 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
658 /* Should never comes here */
662 /* save registers up to (vtop - n) stack entry */
663 ST_FUNC
void save_regs(int n
)
668 for(p
= vstack
;p
<= p1
; p
++) {
669 r
= p
->r
& VT_VALMASK
;
676 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
678 static void move_reg(int r
, int s
, int t
)
692 /* get address of vtop (vtop MUST BE an lvalue) */
693 ST_FUNC
void gaddrof(void)
695 if (vtop
->r
& VT_REF
&& !nocode_wanted
)
698 /* tricky: if saved lvalue, then we can go back to lvalue */
699 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
700 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
705 #ifdef CONFIG_TCC_BCHECK
706 /* generate lvalue bound code */
707 static void gbound(void)
712 vtop
->r
&= ~VT_MUSTBOUND
;
713 /* if lvalue, then use checking code before dereferencing */
714 if (vtop
->r
& VT_LVAL
) {
715 /* if not VT_BOUNDED value, then make one */
716 if (!(vtop
->r
& VT_BOUNDED
)) {
717 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
718 /* must save type because we must set it to int to get pointer */
720 vtop
->type
.t
= VT_PTR
;
723 gen_bounded_ptr_add();
724 vtop
->r
|= lval_type
;
727 /* then check for dereferencing */
728 gen_bounded_ptr_deref();
733 /* store vtop a register belonging to class 'rc'. lvalues are
734 converted to values. Cannot be used if cannot be converted to
735 register value (such as structures). */
736 ST_FUNC
int gv(int rc
)
738 int r
, bit_pos
, bit_size
, size
, align
, i
;
741 /* NOTE: get_reg can modify vstack[] */
742 if (vtop
->type
.t
& VT_BITFIELD
) {
745 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
746 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
747 /* remove bit field info to avoid loops */
748 vtop
->type
.t
&= ~VT_BITFIELD
& ((1 << VT_STRUCT_SHIFT
) - 1);
749 /* cast to int to propagate signedness in following ops */
750 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
755 if((vtop
->type
.t
& VT_UNSIGNED
) ||
756 (vtop
->type
.t
& VT_BTYPE
) == VT_BOOL
)
757 type
.t
|= VT_UNSIGNED
;
759 /* generate shifts */
760 vpushi(bits
- (bit_pos
+ bit_size
));
762 vpushi(bits
- bit_size
);
763 /* NOTE: transformed to SHR if unsigned */
767 if (is_float(vtop
->type
.t
) &&
768 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
771 unsigned long offset
;
772 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
776 /* XXX: unify with initializers handling ? */
777 /* CPUs usually cannot use float constants, so we store them
778 generically in data segment */
779 size
= type_size(&vtop
->type
, &align
);
780 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
781 data_section
->data_offset
= offset
;
782 /* XXX: not portable yet */
783 #if defined(__i386__) || defined(__x86_64__)
784 /* Zero pad x87 tenbyte long doubles */
785 if (size
== LDOUBLE_SIZE
) {
786 vtop
->c
.tab
[2] &= 0xffff;
787 #if LDOUBLE_SIZE == 16
792 ptr
= section_ptr_add(data_section
, size
);
794 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
798 ptr
[i
] = vtop
->c
.tab
[size
-1-i
];
802 ptr
[i
] = vtop
->c
.tab
[i
];
803 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
804 vtop
->r
|= VT_LVAL
| VT_SYM
;
808 #ifdef CONFIG_TCC_BCHECK
809 if (vtop
->r
& VT_MUSTBOUND
)
813 r
= vtop
->r
& VT_VALMASK
;
814 rc2
= (rc
& RC_FLOAT
) ? RC_FLOAT
: RC_INT
;
815 #ifndef TCC_TARGET_ARM64
818 #ifdef TCC_TARGET_X86_64
819 else if (rc
== RC_FRET
)
824 /* need to reload if:
826 - lvalue (need to dereference pointer)
827 - already a register, but not in the right class */
829 || (vtop
->r
& VT_LVAL
)
830 || !(reg_classes
[r
] & rc
)
831 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
832 || ((vtop
->type
.t
& VT_BTYPE
) == VT_QLONG
&& !(reg_classes
[vtop
->r2
] & rc2
))
833 || ((vtop
->type
.t
& VT_BTYPE
) == VT_QFLOAT
&& !(reg_classes
[vtop
->r2
] & rc2
))
835 || ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&& !(reg_classes
[vtop
->r2
] & rc2
))
840 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
841 if (((vtop
->type
.t
& VT_BTYPE
) == VT_QLONG
) || ((vtop
->type
.t
& VT_BTYPE
) == VT_QFLOAT
)) {
842 int addr_type
= VT_LLONG
, load_size
= 8, load_type
= ((vtop
->type
.t
& VT_BTYPE
) == VT_QLONG
) ? VT_LLONG
: VT_DOUBLE
;
844 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
845 int addr_type
= VT_INT
, load_size
= 4, load_type
= VT_INT
;
846 unsigned long long ll
;
848 int r2
, original_type
;
849 original_type
= vtop
->type
.t
;
850 /* two register type load : expand to two words
852 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
853 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
856 vtop
->c
.i
= ll
; /* first word */
858 vtop
->r
= r
; /* save register value */
859 vpushi(ll
>> 32); /* second word */
862 if (r
>= VT_CONST
|| /* XXX: test to VT_CONST incorrect ? */
863 (vtop
->r
& VT_LVAL
)) {
864 /* We do not want to modifier the long long
865 pointer here, so the safest (and less
866 efficient) is to save all the other registers
867 in the stack. XXX: totally inefficient. */
869 /* load from memory */
870 vtop
->type
.t
= load_type
;
873 vtop
[-1].r
= r
; /* save register value */
874 /* increment pointer to get second word */
875 vtop
->type
.t
= addr_type
;
880 vtop
->type
.t
= load_type
;
885 vtop
[-1].r
= r
; /* save register value */
886 vtop
->r
= vtop
[-1].r2
;
888 /* Allocate second register. Here we rely on the fact that
889 get_reg() tries first to free r2 of an SValue. */
893 /* write second register */
895 vtop
->type
.t
= original_type
;
896 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
898 /* lvalue of scalar type : need to use lvalue type
899 because of possible cast */
902 /* compute memory access type */
903 if (vtop
->r
& VT_REF
)
904 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
909 else if (vtop
->r
& VT_LVAL_BYTE
)
911 else if (vtop
->r
& VT_LVAL_SHORT
)
913 if (vtop
->r
& VT_LVAL_UNSIGNED
)
917 /* restore wanted type */
920 /* one register type load */
925 #ifdef TCC_TARGET_C67
926 /* uses register pairs for doubles */
927 if ((vtop
->type
.t
& VT_BTYPE
) == VT_DOUBLE
)
934 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
935 ST_FUNC
void gv2(int rc1
, int rc2
)
939 /* generate more generic register first. But VT_JMP or VT_CMP
940 values must be generated first in all cases to avoid possible
942 v
= vtop
[0].r
& VT_VALMASK
;
943 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
948 /* test if reload is needed for first register */
949 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
959 /* test if reload is needed for first register */
960 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
966 #ifndef TCC_TARGET_ARM64
967 /* wrapper around RC_FRET to return a register by type */
968 static int rc_fret(int t
)
970 #ifdef TCC_TARGET_X86_64
971 if (t
== VT_LDOUBLE
) {
979 /* wrapper around REG_FRET to return a register by type */
980 static int reg_fret(int t
)
982 #ifdef TCC_TARGET_X86_64
983 if (t
== VT_LDOUBLE
) {
990 /* expand long long on stack in two int registers */
991 static void lexpand(void)
995 u
= vtop
->type
.t
& (VT_DEFSIGN
| VT_UNSIGNED
);
998 vtop
[0].r
= vtop
[-1].r2
;
999 vtop
[0].r2
= VT_CONST
;
1000 vtop
[-1].r2
= VT_CONST
;
1001 vtop
[0].type
.t
= VT_INT
| u
;
1002 vtop
[-1].type
.t
= VT_INT
| u
;
1005 #ifdef TCC_TARGET_ARM
1006 /* expand long long on stack */
1007 ST_FUNC
void lexpand_nr(void)
1011 u
= vtop
->type
.t
& (VT_DEFSIGN
| VT_UNSIGNED
);
1013 vtop
->r2
= VT_CONST
;
1014 vtop
->type
.t
= VT_INT
| u
;
1015 v
=vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
);
1016 if (v
== VT_CONST
) {
1017 vtop
[-1].c
.i
= vtop
->c
.i
;
1018 vtop
->c
.i
= vtop
->c
.i
>> 32;
1020 } else if (v
== (VT_LVAL
|VT_CONST
) || v
== (VT_LVAL
|VT_LOCAL
)) {
1022 vtop
->r
= vtop
[-1].r
;
1023 } else if (v
> VT_CONST
) {
1027 vtop
->r
= vtop
[-1].r2
;
1028 vtop
[-1].r2
= VT_CONST
;
1029 vtop
[-1].type
.t
= VT_INT
| u
;
1033 /* build a long long from two ints */
1034 static void lbuild(int t
)
1036 gv2(RC_INT
, RC_INT
);
1037 vtop
[-1].r2
= vtop
[0].r
;
1038 vtop
[-1].type
.t
= t
;
1042 /* rotate n first stack elements to the bottom
1043 I1 ... In -> I2 ... In I1 [top is right]
1045 ST_FUNC
void vrotb(int n
)
1051 for(i
=-n
+1;i
!=0;i
++)
1052 vtop
[i
] = vtop
[i
+1];
1056 /* rotate the n elements before entry e towards the top
1057 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1059 ST_FUNC
void vrote(SValue
*e
, int n
)
1065 for(i
= 0;i
< n
- 1; i
++)
1070 /* rotate n first stack elements to the top
1071 I1 ... In -> In I1 ... I(n-1) [top is right]
1073 ST_FUNC
void vrott(int n
)
1078 /* pop stack value */
1079 ST_FUNC
void vpop(void)
1082 v
= vtop
->r
& VT_VALMASK
;
1083 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1084 /* for x86, we need to pop the FP stack */
1085 if (v
== TREG_ST0
&& !nocode_wanted
) {
1086 o(0xd8dd); /* fstp %st(0) */
1089 if (v
== VT_JMP
|| v
== VT_JMPI
) {
1090 /* need to put correct jump if && or || without test */
1096 /* convert stack entry to register and duplicate its value in another
1098 static void gv_dup(void)
1104 if ((t
& VT_BTYPE
) == VT_LLONG
) {
1111 /* stack: H L L1 H1 */
1119 /* duplicate value */
1124 #ifdef TCC_TARGET_X86_64
1125 if ((t
& VT_BTYPE
) == VT_LDOUBLE
) {
1135 load(r1
, &sv
); /* move r to r1 */
1137 /* duplicates value */
1143 /* Generate value test
1145 * Generate a test for any value (jump, comparison and integers) */
1146 ST_FUNC
int gvtst(int inv
, int t
)
1148 int v
= vtop
->r
& VT_VALMASK
;
1149 if (v
!= VT_CMP
&& v
!= VT_JMP
&& v
!= VT_JMPI
) {
1153 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
1154 /* constant jmp optimization */
1155 if ((vtop
->c
.i
!= 0) != inv
)
1160 return gtst(inv
, t
);
1163 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
1164 /* generate CPU independent (unsigned) long long operations */
1165 static void gen_opl(int op
)
1167 int t
, a
, b
, op1
, c
, i
;
1169 unsigned short reg_iret
= REG_IRET
;
1170 unsigned short reg_lret
= REG_LRET
;
1176 func
= TOK___divdi3
;
1179 func
= TOK___udivdi3
;
1182 func
= TOK___moddi3
;
1185 func
= TOK___umoddi3
;
1192 /* call generic long long function */
1193 vpush_global_sym(&func_old_type
, func
);
1198 vtop
->r2
= reg_lret
;
1211 /* stack: L1 H1 L2 H2 */
1216 vtop
[-2] = vtop
[-3];
1219 /* stack: H1 H2 L1 L2 */
1225 /* stack: H1 H2 L1 L2 ML MH */
1228 /* stack: ML MH H1 H2 L1 L2 */
1232 /* stack: ML MH H1 L2 H2 L1 */
1237 /* stack: ML MH M1 M2 */
1240 } else if (op
== '+' || op
== '-') {
1241 /* XXX: add non carry method too (for MIPS or alpha) */
1247 /* stack: H1 H2 (L1 op L2) */
1250 gen_op(op1
+ 1); /* TOK_xxxC2 */
1253 /* stack: H1 H2 (L1 op L2) */
1256 /* stack: (L1 op L2) H1 H2 */
1258 /* stack: (L1 op L2) (H1 op H2) */
1266 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
1267 t
= vtop
[-1].type
.t
;
1271 /* stack: L H shift */
1273 /* constant: simpler */
1274 /* NOTE: all comments are for SHL. the other cases are
1275 done by swaping words */
1286 if (op
!= TOK_SAR
) {
1319 /* XXX: should provide a faster fallback on x86 ? */
1322 func
= TOK___ashrdi3
;
1325 func
= TOK___lshrdi3
;
1328 func
= TOK___ashldi3
;
1334 /* compare operations */
1340 /* stack: L1 H1 L2 H2 */
1342 vtop
[-1] = vtop
[-2];
1344 /* stack: L1 L2 H1 H2 */
1347 /* when values are equal, we need to compare low words. since
1348 the jump is inverted, we invert the test too. */
1351 else if (op1
== TOK_GT
)
1353 else if (op1
== TOK_ULT
)
1355 else if (op1
== TOK_UGT
)
1360 if (op1
!= TOK_NE
) {
1364 /* generate non equal test */
1365 /* XXX: NOT PORTABLE yet */
1369 #if defined(TCC_TARGET_I386)
1370 b
= psym(0x850f, 0);
1371 #elif defined(TCC_TARGET_ARM)
1373 o(0x1A000000 | encbranch(ind
, 0, 1));
1374 #elif defined(TCC_TARGET_C67) || defined(TCC_TARGET_ARM64)
1375 tcc_error("not implemented");
1377 #error not supported
1381 /* compare low. Always unsigned */
1385 else if (op1
== TOK_LE
)
1387 else if (op1
== TOK_GT
)
1389 else if (op1
== TOK_GE
)
1400 static uint64_t gen_opic_sdiv(uint64_t a
, uint64_t b
)
1402 uint64_t x
= (a
>> 63 ? -a
: a
) / (b
>> 63 ? -b
: b
);
1403 return (a
^ b
) >> 63 ? -x
: x
;
1406 static int gen_opic_lt(uint64_t a
, uint64_t b
)
1408 return (a
^ (uint64_t)1 << 63) < (b
^ (uint64_t)1 << 63);
1411 /* handle integer constant optimizations and various machine
1413 static void gen_opic(int op
)
1415 SValue
*v1
= vtop
- 1;
1417 int t1
= v1
->type
.t
& VT_BTYPE
;
1418 int t2
= v2
->type
.t
& VT_BTYPE
;
1419 int c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1420 int c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1421 uint64_t l1
= c1
? v1
->c
.i
: 0;
1422 uint64_t l2
= c2
? v2
->c
.i
: 0;
1423 int shm
= (t1
== VT_LLONG
) ? 63 : 31;
1426 l1
= ((uint32_t)l1
|
1427 (v1
->type
.t
& VT_UNSIGNED
? 0 : -(l1
& 0x80000000)));
1429 l2
= ((uint32_t)l2
|
1430 (v2
->type
.t
& VT_UNSIGNED
? 0 : -(l2
& 0x80000000)));
1434 case '+': l1
+= l2
; break;
1435 case '-': l1
-= l2
; break;
1436 case '&': l1
&= l2
; break;
1437 case '^': l1
^= l2
; break;
1438 case '|': l1
|= l2
; break;
1439 case '*': l1
*= l2
; break;
1446 /* if division by zero, generate explicit division */
1449 tcc_error("division by zero in constant");
1453 default: l1
= gen_opic_sdiv(l1
, l2
); break;
1454 case '%': l1
= l1
- l2
* gen_opic_sdiv(l1
, l2
); break;
1455 case TOK_UDIV
: l1
= l1
/ l2
; break;
1456 case TOK_UMOD
: l1
= l1
% l2
; break;
1459 case TOK_SHL
: l1
<<= (l2
& shm
); break;
1460 case TOK_SHR
: l1
>>= (l2
& shm
); break;
1462 l1
= (l1
>> 63) ? ~(~l1
>> (l2
& shm
)) : l1
>> (l2
& shm
);
1465 case TOK_ULT
: l1
= l1
< l2
; break;
1466 case TOK_UGE
: l1
= l1
>= l2
; break;
1467 case TOK_EQ
: l1
= l1
== l2
; break;
1468 case TOK_NE
: l1
= l1
!= l2
; break;
1469 case TOK_ULE
: l1
= l1
<= l2
; break;
1470 case TOK_UGT
: l1
= l1
> l2
; break;
1471 case TOK_LT
: l1
= gen_opic_lt(l1
, l2
); break;
1472 case TOK_GE
: l1
= !gen_opic_lt(l1
, l2
); break;
1473 case TOK_LE
: l1
= !gen_opic_lt(l2
, l1
); break;
1474 case TOK_GT
: l1
= gen_opic_lt(l2
, l1
); break;
1476 case TOK_LAND
: l1
= l1
&& l2
; break;
1477 case TOK_LOR
: l1
= l1
|| l2
; break;
1484 /* if commutative ops, put c2 as constant */
1485 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
1486 op
== '|' || op
== '*')) {
1488 c2
= c1
; //c = c1, c1 = c2, c2 = c;
1489 l2
= l1
; //l = l1, l1 = l2, l2 = l;
1491 if (!const_wanted
&&
1493 (op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
)) ||
1494 (l1
== -1 && op
== TOK_SAR
))) {
1495 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
1497 } else if (!const_wanted
&&
1498 c2
&& ((l2
== 0 && (op
== '&' || op
== '*')) ||
1499 (l2
== -1 && op
== '|') ||
1500 (l2
== 0xffffffff && t2
!= VT_LLONG
&& op
== '|') ||
1501 (l2
== 1 && (op
== '%' || op
== TOK_UMOD
)))) {
1502 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
1507 } else if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
1510 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
1511 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
1515 /* filter out NOP operations like x*1, x-0, x&-1... */
1517 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
1518 /* try to use shifts instead of muls or divs */
1519 if (l2
> 0 && (l2
& (l2
- 1)) == 0) {
1528 else if (op
== TOK_PDIV
)
1534 } else if (c2
&& (op
== '+' || op
== '-') &&
1535 (((vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == (VT_CONST
| VT_SYM
))
1536 || (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
)) == VT_LOCAL
)) {
1537 /* symbol + constant case */
1544 if (!nocode_wanted
) {
1545 /* call low level op generator */
1546 if (t1
== VT_LLONG
|| t2
== VT_LLONG
||
1547 (PTR_SIZE
== 8 && (t1
== VT_PTR
|| t2
== VT_PTR
)))
1558 /* generate a floating point operation with constant propagation */
1559 static void gen_opif(int op
)
1567 /* currently, we cannot do computations with forward symbols */
1568 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1569 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1571 if (v1
->type
.t
== VT_FLOAT
) {
1574 } else if (v1
->type
.t
== VT_DOUBLE
) {
1582 /* NOTE: we only do constant propagation if finite number (not
1583 NaN or infinity) (ANSI spec) */
1584 if (!ieee_finite(f1
) || !ieee_finite(f2
))
1588 case '+': f1
+= f2
; break;
1589 case '-': f1
-= f2
; break;
1590 case '*': f1
*= f2
; break;
1594 tcc_error("division by zero in constant");
1599 /* XXX: also handles tests ? */
1603 /* XXX: overflow test ? */
1604 if (v1
->type
.t
== VT_FLOAT
) {
1606 } else if (v1
->type
.t
== VT_DOUBLE
) {
1614 if (!nocode_wanted
) {
1622 static int pointed_size(CType
*type
)
1625 return type_size(pointed_type(type
), &align
);
1628 static void vla_runtime_pointed_size(CType
*type
)
1631 vla_runtime_type_size(pointed_type(type
), &align
);
1634 static inline int is_null_pointer(SValue
*p
)
1636 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
1638 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& (uint32_t)p
->c
.i
== 0) ||
1639 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.i
== 0) ||
1640 ((p
->type
.t
& VT_BTYPE
) == VT_PTR
&&
1641 (PTR_SIZE
== 4 ? (uint32_t)p
->c
.i
== 0 : p
->c
.i
== 0));
1644 static inline int is_integer_btype(int bt
)
1646 return (bt
== VT_BYTE
|| bt
== VT_SHORT
||
1647 bt
== VT_INT
|| bt
== VT_LLONG
);
1650 /* check types for comparison or subtraction of pointers */
1651 static void check_comparison_pointer_types(SValue
*p1
, SValue
*p2
, int op
)
1653 CType
*type1
, *type2
, tmp_type1
, tmp_type2
;
1656 /* null pointers are accepted for all comparisons as gcc */
1657 if (is_null_pointer(p1
) || is_null_pointer(p2
))
1661 bt1
= type1
->t
& VT_BTYPE
;
1662 bt2
= type2
->t
& VT_BTYPE
;
1663 /* accept comparison between pointer and integer with a warning */
1664 if ((is_integer_btype(bt1
) || is_integer_btype(bt2
)) && op
!= '-') {
1665 if (op
!= TOK_LOR
&& op
!= TOK_LAND
)
1666 tcc_warning("comparison between pointer and integer");
1670 /* both must be pointers or implicit function pointers */
1671 if (bt1
== VT_PTR
) {
1672 type1
= pointed_type(type1
);
1673 } else if (bt1
!= VT_FUNC
)
1674 goto invalid_operands
;
1676 if (bt2
== VT_PTR
) {
1677 type2
= pointed_type(type2
);
1678 } else if (bt2
!= VT_FUNC
) {
1680 tcc_error("invalid operands to binary %s", get_tok_str(op
, NULL
));
1682 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
1683 (type2
->t
& VT_BTYPE
) == VT_VOID
)
1687 tmp_type1
.t
&= ~(VT_DEFSIGN
| VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
1688 tmp_type2
.t
&= ~(VT_DEFSIGN
| VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
1689 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
1690 /* gcc-like error if '-' is used */
1692 goto invalid_operands
;
1694 tcc_warning("comparison of distinct pointer types lacks a cast");
1698 /* generic gen_op: handles types problems */
1699 ST_FUNC
void gen_op(int op
)
1701 int u
, t1
, t2
, bt1
, bt2
, t
;
1704 t1
= vtop
[-1].type
.t
;
1705 t2
= vtop
[0].type
.t
;
1706 bt1
= t1
& VT_BTYPE
;
1707 bt2
= t2
& VT_BTYPE
;
1709 if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
1710 tcc_error("operation on a struct");
1711 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
1712 /* at least one operand is a pointer */
1713 /* relationnal op: must be both pointers */
1714 if (op
>= TOK_ULT
&& op
<= TOK_LOR
) {
1715 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
1716 /* pointers are handled are unsigned */
1717 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1718 t
= VT_LLONG
| VT_UNSIGNED
;
1720 t
= VT_INT
| VT_UNSIGNED
;
1724 /* if both pointers, then it must be the '-' op */
1725 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
1727 tcc_error("cannot use pointers here");
1728 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
1729 /* XXX: check that types are compatible */
1730 if (vtop
[-1].type
.t
& VT_VLA
) {
1731 vla_runtime_pointed_size(&vtop
[-1].type
);
1733 vpushi(pointed_size(&vtop
[-1].type
));
1737 /* set to integer type */
1738 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1739 vtop
->type
.t
= VT_LLONG
;
1741 vtop
->type
.t
= VT_INT
;
1746 /* exactly one pointer : must be '+' or '-'. */
1747 if (op
!= '-' && op
!= '+')
1748 tcc_error("cannot use pointers here");
1749 /* Put pointer as first operand */
1750 if (bt2
== VT_PTR
) {
1754 type1
= vtop
[-1].type
;
1755 type1
.t
&= ~VT_ARRAY
;
1756 if (vtop
[-1].type
.t
& VT_VLA
)
1757 vla_runtime_pointed_size(&vtop
[-1].type
);
1759 u
= pointed_size(&vtop
[-1].type
);
1761 tcc_error("unknown array element size");
1762 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1765 /* XXX: cast to int ? (long long case) */
1771 /* #ifdef CONFIG_TCC_BCHECK
1772 The main reason to removing this code:
1779 fprintf(stderr, "v+i-j = %p\n", v+i-j);
1780 fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
1782 When this code is on. then the output looks like
1784 v+(i-j) = 0xbff84000
1786 /* if evaluating constant expression, no code should be
1787 generated, so no bound check */
1788 if (tcc_state
->do_bounds_check
&& !const_wanted
) {
1789 /* if bounded pointers, we generate a special code to
1796 gen_bounded_ptr_add();
1802 /* put again type if gen_opic() swaped operands */
1805 } else if (is_float(bt1
) || is_float(bt2
)) {
1806 /* compute bigger type and do implicit casts */
1807 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
1809 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
1814 /* floats can only be used for a few operations */
1815 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
1816 (op
< TOK_ULT
|| op
> TOK_GT
))
1817 tcc_error("invalid operands for binary operation");
1819 } else if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
) {
1820 t
= bt1
== VT_LLONG
? VT_LLONG
: VT_INT
;
1821 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (t
| VT_UNSIGNED
))
1824 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
1825 /* cast to biggest op */
1827 /* convert to unsigned if it does not fit in a long long */
1828 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
1829 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
1833 /* integer operations */
1835 /* convert to unsigned if it does not fit in an integer */
1836 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
1837 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
1840 /* XXX: currently, some unsigned operations are explicit, so
1841 we modify them here */
1842 if (t
& VT_UNSIGNED
) {
1849 else if (op
== TOK_LT
)
1851 else if (op
== TOK_GT
)
1853 else if (op
== TOK_LE
)
1855 else if (op
== TOK_GE
)
1862 /* special case for shifts and long long: we keep the shift as
1864 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
1871 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
1872 /* relationnal op: the result is an int */
1873 vtop
->type
.t
= VT_INT
;
1878 // Make sure that we have converted to an rvalue:
1879 if (vtop
->r
& VT_LVAL
&& !nocode_wanted
)
1880 gv(is_float(vtop
->type
.t
& VT_BTYPE
) ? RC_FLOAT
: RC_INT
);
1883 #ifndef TCC_TARGET_ARM
1884 /* generic itof for unsigned long long case */
1885 static void gen_cvt_itof1(int t
)
1887 #ifdef TCC_TARGET_ARM64
1890 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
1891 (VT_LLONG
| VT_UNSIGNED
)) {
1894 vpush_global_sym(&func_old_type
, TOK___floatundisf
);
1895 #if LDOUBLE_SIZE != 8
1896 else if (t
== VT_LDOUBLE
)
1897 vpush_global_sym(&func_old_type
, TOK___floatundixf
);
1900 vpush_global_sym(&func_old_type
, TOK___floatundidf
);
1904 vtop
->r
= reg_fret(t
);
1912 /* generic ftoi for unsigned long long case */
1913 static void gen_cvt_ftoi1(int t
)
1915 #ifdef TCC_TARGET_ARM64
1920 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
1921 /* not handled natively */
1922 st
= vtop
->type
.t
& VT_BTYPE
;
1924 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
1925 #if LDOUBLE_SIZE != 8
1926 else if (st
== VT_LDOUBLE
)
1927 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
1930 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
1935 vtop
->r2
= REG_LRET
;
1942 /* force char or short cast */
1943 static void force_charshort_cast(int t
)
1947 /* XXX: add optimization if lvalue : just change type and offset */
1952 if (t
& VT_UNSIGNED
) {
1953 vpushi((1 << bits
) - 1);
1959 /* result must be signed or the SAR is converted to an SHL
1960 This was not the case when "t" was a signed short
1961 and the last value on the stack was an unsigned int */
1962 vtop
->type
.t
&= ~VT_UNSIGNED
;
1968 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1969 static void gen_cast(CType
*type
)
1971 int sbt
, dbt
, sf
, df
, c
, p
;
1973 /* special delayed cast for char/short */
1974 /* XXX: in some cases (multiple cascaded casts), it may still
1976 if (vtop
->r
& VT_MUSTCAST
) {
1977 vtop
->r
&= ~VT_MUSTCAST
;
1978 force_charshort_cast(vtop
->type
.t
);
1981 /* bitfields first get cast to ints */
1982 if (vtop
->type
.t
& VT_BITFIELD
&& !nocode_wanted
) {
1986 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
1987 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
1992 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1993 p
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == (VT_CONST
| VT_SYM
);
1995 /* constant case: we can do it now */
1996 /* XXX: in ISOC, cannot do it if error in convert */
1997 if (sbt
== VT_FLOAT
)
1998 vtop
->c
.ld
= vtop
->c
.f
;
1999 else if (sbt
== VT_DOUBLE
)
2000 vtop
->c
.ld
= vtop
->c
.d
;
2003 if ((sbt
& VT_BTYPE
) == VT_LLONG
) {
2004 if ((sbt
& VT_UNSIGNED
) || !(vtop
->c
.i
>> 63))
2005 vtop
->c
.ld
= vtop
->c
.i
;
2007 vtop
->c
.ld
= -(long double)-vtop
->c
.i
;
2009 if ((sbt
& VT_UNSIGNED
) || !(vtop
->c
.i
>> 31))
2010 vtop
->c
.ld
= (uint32_t)vtop
->c
.i
;
2012 vtop
->c
.ld
= -(long double)-(uint32_t)vtop
->c
.i
;
2015 if (dbt
== VT_FLOAT
)
2016 vtop
->c
.f
= (float)vtop
->c
.ld
;
2017 else if (dbt
== VT_DOUBLE
)
2018 vtop
->c
.d
= (double)vtop
->c
.ld
;
2019 } else if (sf
&& dbt
== (VT_LLONG
|VT_UNSIGNED
)) {
2020 vtop
->c
.i
= vtop
->c
.ld
;
2021 } else if (sf
&& dbt
== VT_BOOL
) {
2022 vtop
->c
.i
= (vtop
->c
.ld
!= 0);
2025 vtop
->c
.i
= vtop
->c
.ld
;
2026 else if (sbt
== (VT_LLONG
|VT_UNSIGNED
))
2028 else if (sbt
& VT_UNSIGNED
)
2029 vtop
->c
.i
= (uint32_t)vtop
->c
.i
;
2030 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2031 else if (sbt
== VT_PTR
)
2034 else if (sbt
!= VT_LLONG
)
2035 vtop
->c
.i
= ((uint32_t)vtop
->c
.i
|
2036 -(vtop
->c
.i
& 0x80000000));
2038 if (dbt
== (VT_LLONG
|VT_UNSIGNED
))
2040 else if (dbt
== VT_BOOL
)
2041 vtop
->c
.i
= (vtop
->c
.i
!= 0);
2042 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2043 else if (dbt
== VT_PTR
)
2046 else if (dbt
!= VT_LLONG
) {
2047 uint32_t m
= ((dbt
& VT_BTYPE
) == VT_BYTE
? 0xff :
2048 (dbt
& VT_BTYPE
) == VT_SHORT
? 0xffff :
2051 if (!(dbt
& VT_UNSIGNED
))
2052 vtop
->c
.i
|= -(vtop
->c
.i
& ((m
>> 1) + 1));
2055 } else if (p
&& dbt
== VT_BOOL
) {
2058 } else if (!nocode_wanted
) {
2059 /* non constant case: generate code */
2061 /* convert from fp to fp */
2064 /* convert int to fp */
2067 /* convert fp to int */
2068 if (dbt
== VT_BOOL
) {
2072 /* we handle char/short/etc... with generic code */
2073 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
2074 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
2078 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
2079 /* additional cast for char/short... */
2084 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
2085 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
2086 if ((sbt
& VT_BTYPE
) != VT_LLONG
&& !nocode_wanted
) {
2087 /* scalar to long long */
2088 /* machine independent conversion */
2090 /* generate high word */
2091 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
2095 if (sbt
== VT_PTR
) {
2096 /* cast from pointer to int before we apply
2097 shift operation, which pointers don't support*/
2098 gen_cast(&int_type
);
2104 /* patch second register */
2105 vtop
[-1].r2
= vtop
->r
;
2109 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
||
2110 (dbt
& VT_BTYPE
) == VT_PTR
||
2111 (dbt
& VT_BTYPE
) == VT_FUNC
) {
2112 if ((sbt
& VT_BTYPE
) != VT_LLONG
&&
2113 (sbt
& VT_BTYPE
) != VT_PTR
&&
2114 (sbt
& VT_BTYPE
) != VT_FUNC
&& !nocode_wanted
) {
2115 /* need to convert from 32bit to 64bit */
2117 if (sbt
!= (VT_INT
| VT_UNSIGNED
)) {
2118 #if defined(TCC_TARGET_ARM64)
2120 #elif defined(TCC_TARGET_X86_64)
2122 /* x86_64 specific: movslq */
2124 o(0xc0 + (REG_VALUE(r
) << 3) + REG_VALUE(r
));
2131 } else if (dbt
== VT_BOOL
) {
2132 /* scalar to bool */
2135 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
2136 (dbt
& VT_BTYPE
) == VT_SHORT
) {
2137 if (sbt
== VT_PTR
) {
2138 vtop
->type
.t
= VT_INT
;
2139 tcc_warning("nonportable conversion from pointer to char/short");
2141 force_charshort_cast(dbt
);
2142 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
2144 if (sbt
== VT_LLONG
&& !nocode_wanted
) {
2145 /* from long long: just take low order word */
2149 /* if lvalue and single word type, nothing to do because
2150 the lvalue already contains the real type size (see
2151 VT_LVAL_xxx constants) */
2154 } else if ((dbt
& VT_BTYPE
) == VT_PTR
&& !(vtop
->r
& VT_LVAL
)) {
2155 /* if we are casting between pointer types,
2156 we must update the VT_LVAL_xxx size */
2157 vtop
->r
= (vtop
->r
& ~VT_LVAL_TYPE
)
2158 | (lvalue_type(type
->ref
->type
.t
) & VT_LVAL_TYPE
);
2163 /* return type size as known at compile time. Put alignment at 'a' */
2164 ST_FUNC
int type_size(CType
*type
, int *a
)
2169 bt
= type
->t
& VT_BTYPE
;
2170 if (bt
== VT_STRUCT
) {
2175 } else if (bt
== VT_PTR
) {
2176 if (type
->t
& VT_ARRAY
) {
2180 ts
= type_size(&s
->type
, a
);
2182 if (ts
< 0 && s
->c
< 0)
2190 } else if (bt
== VT_LDOUBLE
) {
2192 return LDOUBLE_SIZE
;
2193 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
2194 #ifdef TCC_TARGET_I386
2195 #ifdef TCC_TARGET_PE
2200 #elif defined(TCC_TARGET_ARM)
2210 } else if (bt
== VT_INT
|| bt
== VT_FLOAT
) {
2213 } else if (bt
== VT_SHORT
) {
2216 } else if (bt
== VT_QLONG
|| bt
== VT_QFLOAT
) {
2219 } else if (bt
== VT_ENUM
) {
2221 /* Enums might be incomplete, so don't just return '4' here. */
2222 return type
->ref
->c
;
2224 /* char, void, function, _Bool */
2230 /* push type size as known at runtime time on top of value stack. Put
2232 ST_FUNC
void vla_runtime_type_size(CType
*type
, int *a
)
2234 if (type
->t
& VT_VLA
) {
2235 vset(&int_type
, VT_LOCAL
|VT_LVAL
, type
->ref
->c
);
2237 vpushi(type_size(type
, a
));
2241 static void vla_sp_restore(void) {
2242 if (vlas_in_scope
) {
2243 gen_vla_sp_restore(vla_sp_loc
);
2247 static void vla_sp_restore_root(void) {
2248 if (vlas_in_scope
) {
2249 gen_vla_sp_restore(vla_sp_root_loc
);
2253 /* return the pointed type of t */
2254 static inline CType
*pointed_type(CType
*type
)
2256 return &type
->ref
->type
;
2259 /* modify type so that its it is a pointer to type. */
2260 ST_FUNC
void mk_pointer(CType
*type
)
2263 s
= sym_push(SYM_FIELD
, type
, 0, -1);
2264 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
2268 /* compare function types. OLD functions match any new functions */
2269 static int is_compatible_func(CType
*type1
, CType
*type2
)
2275 if (!is_compatible_types(&s1
->type
, &s2
->type
))
2277 /* check func_call */
2278 if (s1
->a
.func_call
!= s2
->a
.func_call
)
2280 /* XXX: not complete */
2281 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
2285 while (s1
!= NULL
) {
2288 if (!is_compatible_parameter_types(&s1
->type
, &s2
->type
))
2298 /* return true if type1 and type2 are the same. If unqualified is
2299 true, qualifiers on the types are ignored.
2301 - enums are not checked as gcc __builtin_types_compatible_p ()
2303 static int compare_types(CType
*type1
, CType
*type2
, int unqualified
)
2307 t1
= type1
->t
& VT_TYPE
;
2308 t2
= type2
->t
& VT_TYPE
;
2310 /* strip qualifiers before comparing */
2311 t1
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2312 t2
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2314 /* Default Vs explicit signedness only matters for char */
2315 if ((t1
& VT_BTYPE
) != VT_BYTE
) {
2319 /* XXX: bitfields ? */
2322 /* test more complicated cases */
2323 bt1
= t1
& VT_BTYPE
;
2324 if (bt1
== VT_PTR
) {
2325 type1
= pointed_type(type1
);
2326 type2
= pointed_type(type2
);
2327 return is_compatible_types(type1
, type2
);
2328 } else if (bt1
== VT_STRUCT
) {
2329 return (type1
->ref
== type2
->ref
);
2330 } else if (bt1
== VT_FUNC
) {
2331 return is_compatible_func(type1
, type2
);
2337 /* return true if type1 and type2 are exactly the same (including
2340 static int is_compatible_types(CType
*type1
, CType
*type2
)
2342 return compare_types(type1
,type2
,0);
2345 /* return true if type1 and type2 are the same (ignoring qualifiers).
2347 static int is_compatible_parameter_types(CType
*type1
, CType
*type2
)
2349 return compare_types(type1
,type2
,1);
2352 /* print a type. If 'varstr' is not NULL, then the variable is also
2353 printed in the type */
2355 /* XXX: add array and function pointers */
2356 static void type_to_str(char *buf
, int buf_size
,
2357 CType
*type
, const char *varstr
)
2364 t
= type
->t
& VT_TYPE
;
2367 if (t
& VT_CONSTANT
)
2368 pstrcat(buf
, buf_size
, "const ");
2369 if (t
& VT_VOLATILE
)
2370 pstrcat(buf
, buf_size
, "volatile ");
2371 if ((t
& (VT_DEFSIGN
| VT_UNSIGNED
)) == (VT_DEFSIGN
| VT_UNSIGNED
))
2372 pstrcat(buf
, buf_size
, "unsigned ");
2373 else if (t
& VT_DEFSIGN
)
2374 pstrcat(buf
, buf_size
, "signed ");
2404 tstr
= "long double";
2406 pstrcat(buf
, buf_size
, tstr
);
2410 if (bt
== VT_STRUCT
)
2414 pstrcat(buf
, buf_size
, tstr
);
2415 v
= type
->ref
->v
& ~SYM_STRUCT
;
2416 if (v
>= SYM_FIRST_ANOM
)
2417 pstrcat(buf
, buf_size
, "<anonymous>");
2419 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
2423 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
2424 pstrcat(buf
, buf_size
, "(");
2426 while (sa
!= NULL
) {
2427 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
2428 pstrcat(buf
, buf_size
, buf1
);
2431 pstrcat(buf
, buf_size
, ", ");
2433 pstrcat(buf
, buf_size
, ")");
2438 snprintf(buf1
, sizeof(buf1
), "%s[%ld]", varstr
? varstr
: "", s
->c
);
2439 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
2442 pstrcpy(buf1
, sizeof(buf1
), "*");
2443 if (t
& VT_CONSTANT
)
2444 pstrcat(buf1
, buf_size
, "const ");
2445 if (t
& VT_VOLATILE
)
2446 pstrcat(buf1
, buf_size
, "volatile ");
2448 pstrcat(buf1
, sizeof(buf1
), varstr
);
2449 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
2453 pstrcat(buf
, buf_size
, " ");
2454 pstrcat(buf
, buf_size
, varstr
);
2459 /* verify type compatibility to store vtop in 'dt' type, and generate
2461 static void gen_assign_cast(CType
*dt
)
2463 CType
*st
, *type1
, *type2
, tmp_type1
, tmp_type2
;
2464 char buf1
[256], buf2
[256];
2467 st
= &vtop
->type
; /* source type */
2468 dbt
= dt
->t
& VT_BTYPE
;
2469 sbt
= st
->t
& VT_BTYPE
;
2470 if (sbt
== VT_VOID
|| dbt
== VT_VOID
) {
2471 if (sbt
== VT_VOID
&& dbt
== VT_VOID
)
2473 It is Ok if both are void
2479 gcc accepts this program
2482 tcc_error("cannot cast from/to void");
2484 if (dt
->t
& VT_CONSTANT
)
2485 tcc_warning("assignment of read-only location");
2488 /* special cases for pointers */
2489 /* '0' can also be a pointer */
2490 if (is_null_pointer(vtop
))
2492 /* accept implicit pointer to integer cast with warning */
2493 if (is_integer_btype(sbt
)) {
2494 tcc_warning("assignment makes pointer from integer without a cast");
2497 type1
= pointed_type(dt
);
2498 /* a function is implicitely a function pointer */
2499 if (sbt
== VT_FUNC
) {
2500 if ((type1
->t
& VT_BTYPE
) != VT_VOID
&&
2501 !is_compatible_types(pointed_type(dt
), st
))
2502 tcc_warning("assignment from incompatible pointer type");
2507 type2
= pointed_type(st
);
2508 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
2509 (type2
->t
& VT_BTYPE
) == VT_VOID
) {
2510 /* void * can match anything */
2512 /* exact type match, except for unsigned */
2515 tmp_type1
.t
&= ~(VT_DEFSIGN
| VT_UNSIGNED
| VT_CONSTANT
|
2517 tmp_type2
.t
&= ~(VT_DEFSIGN
| VT_UNSIGNED
| VT_CONSTANT
|
2519 if (!is_compatible_types(&tmp_type1
, &tmp_type2
))
2520 tcc_warning("assignment from incompatible pointer type");
2522 /* check const and volatile */
2523 if ((!(type1
->t
& VT_CONSTANT
) && (type2
->t
& VT_CONSTANT
)) ||
2524 (!(type1
->t
& VT_VOLATILE
) && (type2
->t
& VT_VOLATILE
)))
2525 tcc_warning("assignment discards qualifiers from pointer target type");
2531 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
2532 tcc_warning("assignment makes integer from pointer without a cast");
2533 } else if (sbt
== VT_STRUCT
) {
2534 goto case_VT_STRUCT
;
2536 /* XXX: more tests */
2542 tmp_type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2543 tmp_type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2544 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
2546 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
2547 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
2548 tcc_error("cannot cast '%s' to '%s'", buf1
, buf2
);
2556 /* store vtop in lvalue pushed on stack */
2557 ST_FUNC
void vstore(void)
2559 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
2561 ft
= vtop
[-1].type
.t
;
2562 sbt
= vtop
->type
.t
& VT_BTYPE
;
2563 dbt
= ft
& VT_BTYPE
;
2564 if ((((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
2565 (sbt
== VT_INT
&& dbt
== VT_SHORT
))
2566 && !(vtop
->type
.t
& VT_BITFIELD
)) {
2567 /* optimize char/short casts */
2568 delayed_cast
= VT_MUSTCAST
;
2569 vtop
->type
.t
= (ft
& VT_TYPE
& ~VT_BITFIELD
&
2570 ((1 << VT_STRUCT_SHIFT
) - 1));
2571 /* XXX: factorize */
2572 if (ft
& VT_CONSTANT
)
2573 tcc_warning("assignment of read-only location");
2576 if (!(ft
& VT_BITFIELD
))
2577 gen_assign_cast(&vtop
[-1].type
);
2580 if (sbt
== VT_STRUCT
) {
2581 /* if structure, only generate pointer */
2582 /* structure assignment : generate memcpy */
2583 /* XXX: optimize if small size */
2584 if (!nocode_wanted
) {
2585 size
= type_size(&vtop
->type
, &align
);
2589 vtop
->type
.t
= VT_PTR
;
2592 /* address of memcpy() */
2595 vpush_global_sym(&func_old_type
, TOK_memcpy8
);
2596 else if(!(align
& 3))
2597 vpush_global_sym(&func_old_type
, TOK_memcpy4
);
2600 /* Use memmove, rather than memcpy, as dest and src may be same: */
2601 vpush_global_sym(&func_old_type
, TOK_memmove
);
2606 vtop
->type
.t
= VT_PTR
;
2615 /* leave source on stack */
2616 } else if (ft
& VT_BITFIELD
) {
2617 /* bitfield store handling */
2619 /* save lvalue as expression result (example: s.b = s.a = n;) */
2620 vdup(), vtop
[-1] = vtop
[-2];
2622 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
2623 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2624 /* remove bit field info to avoid loops */
2625 vtop
[-1].type
.t
= ft
& ~VT_BITFIELD
& ((1 << VT_STRUCT_SHIFT
) - 1);
2627 if((ft
& VT_BTYPE
) == VT_BOOL
) {
2628 gen_cast(&vtop
[-1].type
);
2629 vtop
[-1].type
.t
= (vtop
[-1].type
.t
& ~VT_BTYPE
) | (VT_BYTE
| VT_UNSIGNED
);
2632 /* duplicate destination */
2634 vtop
[-1] = vtop
[-2];
2636 /* mask and shift source */
2637 if((ft
& VT_BTYPE
) != VT_BOOL
) {
2638 if((ft
& VT_BTYPE
) == VT_LLONG
) {
2639 vpushll((1ULL << bit_size
) - 1ULL);
2641 vpushi((1 << bit_size
) - 1);
2647 /* load destination, mask and or with source */
2649 if((ft
& VT_BTYPE
) == VT_LLONG
) {
2650 vpushll(~(((1ULL << bit_size
) - 1ULL) << bit_pos
));
2652 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
2658 /* ... and discard */
2662 if (!nocode_wanted
) {
2663 #ifdef CONFIG_TCC_BCHECK
2664 /* bound check case */
2665 if (vtop
[-1].r
& VT_MUSTBOUND
) {
2674 #ifdef TCC_TARGET_X86_64
2675 if ((ft
& VT_BTYPE
) == VT_LDOUBLE
) {
2677 } else if ((ft
& VT_BTYPE
) == VT_QFLOAT
) {
2682 r
= gv(rc
); /* generate value */
2683 /* if lvalue was saved on stack, must read it */
2684 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
2686 t
= get_reg(RC_INT
);
2687 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2692 sv
.r
= VT_LOCAL
| VT_LVAL
;
2693 sv
.c
.i
= vtop
[-1].c
.i
;
2695 vtop
[-1].r
= t
| VT_LVAL
;
2697 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
2698 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2699 if (((ft
& VT_BTYPE
) == VT_QLONG
) || ((ft
& VT_BTYPE
) == VT_QFLOAT
)) {
2700 int addr_type
= VT_LLONG
, load_size
= 8, load_type
= ((vtop
->type
.t
& VT_BTYPE
) == VT_QLONG
) ? VT_LLONG
: VT_DOUBLE
;
2702 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
2703 int addr_type
= VT_INT
, load_size
= 4, load_type
= VT_INT
;
2705 vtop
[-1].type
.t
= load_type
;
2708 /* convert to int to increment easily */
2709 vtop
->type
.t
= addr_type
;
2715 vtop
[-1].type
.t
= load_type
;
2716 /* XXX: it works because r2 is spilled last ! */
2717 store(vtop
->r2
, vtop
- 1);
2723 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
2724 vtop
->r
|= delayed_cast
;
2728 /* post defines POST/PRE add. c is the token ++ or -- */
2729 ST_FUNC
void inc(int post
, int c
)
2732 vdup(); /* save lvalue */
2735 gv_dup(); /* duplicate value */
2737 vdup(); /* duplicate value */
2742 vpushi(c
- TOK_MID
);
2744 vstore(); /* store value */
2746 vpop(); /* if post op, return saved value */
2749 /* Parse GNUC __attribute__ extension. Currently, the following
2750 extensions are recognized:
2751 - aligned(n) : set data/function alignment.
2752 - packed : force data alignment to 1
2753 - section(x) : generate data/code in this section.
2754 - unused : currently ignored, but may be used someday.
2755 - regparm(n) : pass function parameters in registers (i386 only)
2757 static void parse_attribute(AttributeDef
*ad
)
2761 while (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
) {
2765 while (tok
!= ')') {
2766 if (tok
< TOK_IDENT
)
2767 expect("attribute name");
2775 expect("section name");
2776 ad
->section
= find_section(tcc_state
, (char *)tokc
.str
.data
);
2784 expect("alias(\"target\")");
2785 ad
->alias_target
= /* save string as token, for later */
2786 tok_alloc((char*)tokc
.str
.data
, tokc
.str
.size
-1)->tok
;
2790 case TOK_VISIBILITY1
:
2791 case TOK_VISIBILITY2
:
2794 expect("visibility(\"default|hidden|internal|protected\")");
2795 if (!strcmp (tokc
.str
.data
, "default"))
2796 ad
->a
.visibility
= STV_DEFAULT
;
2797 else if (!strcmp (tokc
.str
.data
, "hidden"))
2798 ad
->a
.visibility
= STV_HIDDEN
;
2799 else if (!strcmp (tokc
.str
.data
, "internal"))
2800 ad
->a
.visibility
= STV_INTERNAL
;
2801 else if (!strcmp (tokc
.str
.data
, "protected"))
2802 ad
->a
.visibility
= STV_PROTECTED
;
2804 expect("visibility(\"default|hidden|internal|protected\")");
2813 if (n
<= 0 || (n
& (n
- 1)) != 0)
2814 tcc_error("alignment must be a positive power of two");
2831 /* currently, no need to handle it because tcc does not
2832 track unused objects */
2836 /* currently, no need to handle it because tcc does not
2837 track unused objects */
2842 ad
->a
.func_call
= FUNC_CDECL
;
2847 ad
->a
.func_call
= FUNC_STDCALL
;
2849 #ifdef TCC_TARGET_I386
2859 ad
->a
.func_call
= FUNC_FASTCALL1
+ n
- 1;
2865 ad
->a
.func_call
= FUNC_FASTCALLW
;
2872 ad
->a
.mode
= VT_LLONG
+ 1;
2875 ad
->a
.mode
= VT_SHORT
+ 1;
2878 ad
->a
.mode
= VT_INT
+ 1;
2881 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok
, NULL
));
2888 ad
->a
.func_export
= 1;
2891 ad
->a
.func_import
= 1;
2894 if (tcc_state
->warn_unsupported
)
2895 tcc_warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
2896 /* skip parameters */
2898 int parenthesis
= 0;
2902 else if (tok
== ')')
2905 } while (parenthesis
&& tok
!= -1);
2918 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2919 static void struct_decl(CType
*type
, AttributeDef
*ad
, int u
)
2921 int a
, v
, size
, align
, maxalign
, c
, offset
, flexible
;
2922 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
, prevbt
;
2923 Sym
*s
, *ss
, *ass
, **ps
;
2927 a
= tok
; /* save decl type */
2929 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
) {
2930 parse_attribute(ad
);
2936 /* struct already defined ? return it */
2938 expect("struct/union/enum name");
2940 if (s
&& (s
->scope
== local_scope
|| (tok
!= '{' && tok
!= ';'))) {
2942 tcc_error("redefinition of '%s'", get_tok_str(v
, NULL
));
2950 /* we put an undefined size for struct/union */
2951 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
2952 s
->r
= 0; /* default alignment is zero as gcc */
2953 /* put struct/union/enum name in type */
2961 tcc_error("struct/union/enum already defined");
2962 /* cannot be empty */
2964 /* non empty enums are not allowed */
2965 if (a
== TOK_ENUM
) {
2969 expect("identifier");
2971 if (ss
&& !local_stack
)
2972 tcc_error("redefinition of enumerator '%s'",
2973 get_tok_str(v
, NULL
));
2979 /* enum symbols have static storage */
2980 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
2981 ss
->type
.t
|= VT_STATIC
;
2986 /* NOTE: we accept a trailing comma */
2990 s
->c
= type_size(&int_type
, &align
);
2999 while (tok
!= '}') {
3000 parse_btype(&btype
, &ad1
);
3003 tcc_error("flexible array member '%s' not at the end of struct",
3004 get_tok_str(v
, NULL
));
3009 type_decl(&type1
, &ad1
, &v
, TYPE_DIRECT
| TYPE_ABSTRACT
);
3011 if ((type1
.t
& VT_BTYPE
) != VT_STRUCT
)
3012 expect("identifier");
3014 int v
= btype
.ref
->v
;
3015 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
3016 if (tcc_state
->ms_extensions
== 0)
3017 expect("identifier");
3021 if (type_size(&type1
, &align
) < 0) {
3022 if ((a
== TOK_STRUCT
) && (type1
.t
& VT_ARRAY
) && c
)
3025 tcc_error("field '%s' has incomplete type",
3026 get_tok_str(v
, NULL
));
3028 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
3029 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
| VT_INLINE
)))
3030 tcc_error("invalid type for '%s'",
3031 get_tok_str(v
, NULL
));
3035 bit_size
= expr_const();
3036 /* XXX: handle v = 0 case for messages */
3038 tcc_error("negative width in bit-field '%s'",
3039 get_tok_str(v
, NULL
));
3040 if (v
&& bit_size
== 0)
3041 tcc_error("zero width for bit-field '%s'",
3042 get_tok_str(v
, NULL
));
3044 size
= type_size(&type1
, &align
);
3045 if (ad1
.a
.aligned
) {
3046 if (align
< ad1
.a
.aligned
)
3047 align
= ad1
.a
.aligned
;
3048 } else if (ad1
.a
.packed
) {
3050 } else if (*tcc_state
->pack_stack_ptr
) {
3051 if (align
> *tcc_state
->pack_stack_ptr
)
3052 align
= *tcc_state
->pack_stack_ptr
;
3055 if (bit_size
>= 0) {
3056 bt
= type1
.t
& VT_BTYPE
;
3063 tcc_error("bitfields must have scalar type");
3065 if (bit_size
> bsize
) {
3066 tcc_error("width of '%s' exceeds its type",
3067 get_tok_str(v
, NULL
));
3068 } else if (bit_size
== bsize
) {
3069 /* no need for bit fields */
3071 } else if (bit_size
== 0) {
3072 /* XXX: what to do if only padding in a
3074 /* zero size: means to pad */
3077 /* we do not have enough room ?
3078 did the type change?
3080 if ((bit_pos
+ bit_size
) > bsize
||
3081 bt
!= prevbt
|| a
== TOK_UNION
)
3084 /* XXX: handle LSB first */
3085 type1
.t
|= VT_BITFIELD
|
3086 (bit_pos
<< VT_STRUCT_SHIFT
) |
3087 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
3088 bit_pos
+= bit_size
;
3094 if (v
!= 0 || (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
3095 /* add new memory data only if starting
3097 if (lbit_pos
== 0) {
3098 if (a
== TOK_STRUCT
) {
3099 c
= (c
+ align
- 1) & -align
;
3108 if (align
> maxalign
)
3112 printf("add field %s offset=%d",
3113 get_tok_str(v
, NULL
), offset
);
3114 if (type1
.t
& VT_BITFIELD
) {
3115 printf(" pos=%d size=%d",
3116 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
3117 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
3122 if (v
== 0 && (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
3124 while ((ass
= ass
->next
) != NULL
) {
3125 ss
= sym_push(ass
->v
, &ass
->type
, 0, offset
+ ass
->c
);
3130 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
3134 if (tok
== ';' || tok
== TOK_EOF
)
3141 /* store size and alignment */
3142 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
3148 /* return 1 if basic type is a type size (short, long, long long) */
3149 ST_FUNC
int is_btype_size(int bt
)
3151 return bt
== VT_SHORT
|| bt
== VT_LONG
|| bt
== VT_LLONG
;
3154 /* Add type qualifiers to a type. If the type is an array then the qualifiers
3155 are added to the element type, copied because it could be a typedef. */
3156 static void parse_btype_qualify(CType
*type
, int qualifiers
)
3158 while (type
->t
& VT_ARRAY
) {
3159 type
->ref
= sym_push(SYM_FIELD
, &type
->ref
->type
, 0, type
->ref
->c
);
3160 type
= &type
->ref
->type
;
3162 type
->t
|= qualifiers
;
3165 /* return 0 if no type declaration. otherwise, return the basic type
3168 static int parse_btype(CType
*type
, AttributeDef
*ad
)
3170 int t
, u
, bt_size
, complete
, type_found
, typespec_found
;
3174 memset(ad
, 0, sizeof(AttributeDef
));
3182 /* currently, we really ignore extension */
3193 tcc_error("too many basic types");
3195 bt_size
= is_btype_size (u
& VT_BTYPE
);
3196 if (u
== VT_INT
|| (!bt_size
&& !(t
& VT_TYPEDEF
)))
3211 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
3212 #ifndef TCC_TARGET_PE
3213 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
3215 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
3216 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
3222 #ifdef TCC_TARGET_ARM64
3224 /* GCC's __uint128_t appears in some Linux header files. Make it a
3225 synonym for long double to get the size and alignment right. */
3237 if ((t
& VT_BTYPE
) == VT_LONG
) {
3238 #ifdef TCC_TARGET_PE
3239 t
= (t
& ~VT_BTYPE
) | VT_DOUBLE
;
3241 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
3249 struct_decl(&type1
, ad
, VT_ENUM
);
3252 type
->ref
= type1
.ref
;
3256 struct_decl(&type1
, ad
, VT_STRUCT
);
3259 /* type modifiers */
3264 parse_btype_qualify(type
, VT_CONSTANT
);
3272 parse_btype_qualify(type
, VT_VOLATILE
);
3279 if ((t
& (VT_DEFSIGN
|VT_UNSIGNED
)) == (VT_DEFSIGN
|VT_UNSIGNED
))
3280 tcc_error("signed and unsigned modifier");
3293 if ((t
& (VT_DEFSIGN
|VT_UNSIGNED
)) == VT_DEFSIGN
)
3294 tcc_error("signed and unsigned modifier");
3295 t
|= VT_DEFSIGN
| VT_UNSIGNED
;
3320 /* GNUC attribute */
3321 case TOK_ATTRIBUTE1
:
3322 case TOK_ATTRIBUTE2
:
3323 parse_attribute(ad
);
3326 t
= (t
& ~VT_BTYPE
) | u
;
3334 parse_expr_type(&type1
);
3335 /* remove all storage modifiers except typedef */
3336 type1
.t
&= ~(VT_STORAGE
&~VT_TYPEDEF
);
3342 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
3345 type
->t
= ((s
->type
.t
& ~VT_TYPEDEF
) |
3346 (t
& ~(VT_CONSTANT
| VT_VOLATILE
)));
3347 type
->ref
= s
->type
.ref
;
3348 if (t
& (VT_CONSTANT
| VT_VOLATILE
))
3349 parse_btype_qualify(type
, t
& (VT_CONSTANT
| VT_VOLATILE
));
3353 /* get attributes from typedef */
3354 if (0 == ad
->a
.aligned
)
3355 ad
->a
.aligned
= s
->a
.aligned
;
3356 if (0 == ad
->a
.func_call
)
3357 ad
->a
.func_call
= s
->a
.func_call
;
3358 ad
->a
.packed
|= s
->a
.packed
;
3367 if (tcc_state
->char_is_unsigned
) {
3368 if ((t
& (VT_DEFSIGN
|VT_BTYPE
)) == VT_BYTE
)
3372 /* long is never used as type */
3373 if ((t
& VT_BTYPE
) == VT_LONG
)
3374 #if (!defined TCC_TARGET_X86_64 && !defined TCC_TARGET_ARM64) || \
3375 defined TCC_TARGET_PE
3376 t
= (t
& ~VT_BTYPE
) | VT_INT
;
3378 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
3384 /* convert a function parameter type (array to pointer and function to
3385 function pointer) */
3386 static inline void convert_parameter_type(CType
*pt
)
3388 /* remove const and volatile qualifiers (XXX: const could be used
3389 to indicate a const function parameter */
3390 pt
->t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
3391 /* array must be transformed to pointer according to ANSI C */
3393 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
3398 ST_FUNC
void parse_asm_str(CString
*astr
)
3401 /* read the string */
3403 expect("string constant");
3405 while (tok
== TOK_STR
) {
3406 /* XXX: add \0 handling too ? */
3407 cstr_cat(astr
, tokc
.str
.data
, -1);
3410 cstr_ccat(astr
, '\0');
3413 /* Parse an asm label and return the token */
3414 static int asm_label_instr(void)
3420 parse_asm_str(&astr
);
3423 printf("asm_alias: \"%s\"\n", (char *)astr
.data
);
3425 v
= tok_alloc(astr
.data
, astr
.size
- 1)->tok
;
3430 static void post_type(CType
*type
, AttributeDef
*ad
)
3432 int n
, l
, t1
, arg_size
, align
;
3433 Sym
**plast
, *s
, *first
;
3438 /* function declaration */
3446 /* read param name and compute offset */
3447 if (l
!= FUNC_OLD
) {
3448 if (!parse_btype(&pt
, &ad1
)) {
3450 tcc_error("invalid type");
3457 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
3459 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
3460 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
3461 tcc_error("parameter declared as void");
3462 arg_size
+= (type_size(&pt
, &align
) + PTR_SIZE
- 1) / PTR_SIZE
;
3467 expect("identifier");
3471 convert_parameter_type(&pt
);
3472 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
3478 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
3485 /* if no parameters, then old type prototype */
3489 /* NOTE: const is ignored in returned type as it has a special
3490 meaning in gcc / C++ */
3491 type
->t
&= ~VT_CONSTANT
;
3492 /* some ancient pre-K&R C allows a function to return an array
3493 and the array brackets to be put after the arguments, such
3494 that "int c()[]" means something like "int[] c()" */
3497 skip(']'); /* only handle simple "[]" */
3500 /* we push a anonymous symbol which will contain the function prototype */
3501 ad
->a
.func_args
= arg_size
;
3502 s
= sym_push(SYM_FIELD
, type
, 0, l
);
3507 } else if (tok
== '[') {
3508 /* array definition */
3510 if (tok
== TOK_RESTRICT1
)
3515 if (!local_stack
|| nocode_wanted
)
3516 vpushi(expr_const());
3518 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3521 tcc_error("invalid array size");
3523 if (!is_integer_btype(vtop
->type
.t
& VT_BTYPE
))
3524 tcc_error("size of variable length array should be an integer");
3529 /* parse next post type */
3530 post_type(type
, ad
);
3531 if (type
->t
== VT_FUNC
)
3532 tcc_error("declaration of an array of functions");
3533 t1
|= type
->t
& VT_VLA
;
3536 loc
-= type_size(&int_type
, &align
);
3540 vla_runtime_type_size(type
, &align
);
3542 vset(&int_type
, VT_LOCAL
|VT_LVAL
, n
);
3549 /* we push an anonymous symbol which will contain the array
3551 s
= sym_push(SYM_FIELD
, type
, 0, n
);
3552 type
->t
= (t1
? VT_VLA
: VT_ARRAY
) | VT_PTR
;
3557 /* Parse a type declaration (except basic type), and return the type
3558 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3559 expected. 'type' should contain the basic type. 'ad' is the
3560 attribute definition of the basic type. It can be modified by
3563 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
3566 CType type1
, *type2
;
3567 int qualifiers
, storage
;
3569 while (tok
== '*') {
3577 qualifiers
|= VT_CONSTANT
;
3582 qualifiers
|= VT_VOLATILE
;
3590 type
->t
|= qualifiers
;
3593 /* XXX: clarify attribute handling */
3594 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
3595 parse_attribute(ad
);
3597 /* recursive type */
3598 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3599 type1
.t
= 0; /* XXX: same as int */
3602 /* XXX: this is not correct to modify 'ad' at this point, but
3603 the syntax is not clear */
3604 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
3605 parse_attribute(ad
);
3606 type_decl(&type1
, ad
, v
, td
);
3609 /* type identifier */
3610 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
3614 if (!(td
& TYPE_ABSTRACT
))
3615 expect("identifier");
3619 storage
= type
->t
& VT_STORAGE
;
3620 type
->t
&= ~VT_STORAGE
;
3621 if (storage
& VT_STATIC
) {
3622 int saved_nocode_wanted
= nocode_wanted
;
3624 post_type(type
, ad
);
3625 nocode_wanted
= saved_nocode_wanted
;
3627 post_type(type
, ad
);
3629 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
3630 parse_attribute(ad
);
3634 /* append type at the end of type1 */
3647 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3648 ST_FUNC
int lvalue_type(int t
)
3653 if (bt
== VT_BYTE
|| bt
== VT_BOOL
)
3655 else if (bt
== VT_SHORT
)
3659 if (t
& VT_UNSIGNED
)
3660 r
|= VT_LVAL_UNSIGNED
;
3664 /* indirection with full error checking and bound check */
3665 ST_FUNC
void indir(void)
3667 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
) {
3668 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
3672 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
3674 vtop
->type
= *pointed_type(&vtop
->type
);
3675 /* Arrays and functions are never lvalues */
3676 if (!(vtop
->type
.t
& VT_ARRAY
) && !(vtop
->type
.t
& VT_VLA
)
3677 && (vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
3678 vtop
->r
|= lvalue_type(vtop
->type
.t
);
3679 /* if bound checking, the referenced pointer must be checked */
3680 #ifdef CONFIG_TCC_BCHECK
3681 if (tcc_state
->do_bounds_check
)
3682 vtop
->r
|= VT_MUSTBOUND
;
3687 /* pass a parameter to a function and do type checking and casting */
3688 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
3693 func_type
= func
->c
;
3694 if (func_type
== FUNC_OLD
||
3695 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
3696 /* default casting : only need to convert float to double */
3697 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
3700 } else if (vtop
->type
.t
& VT_BITFIELD
) {
3701 type
.t
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
3704 } else if (arg
== NULL
) {
3705 tcc_error("too many arguments to function");
3708 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
3709 gen_assign_cast(&type
);
3713 /* parse an expression of the form '(type)' or '(expr)' and return its
3715 static void parse_expr_type(CType
*type
)
3721 if (parse_btype(type
, &ad
)) {
3722 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
3729 static void parse_type(CType
*type
)
3734 if (!parse_btype(type
, &ad
)) {
3737 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
3740 static void vpush_tokc(int t
)
3745 vsetc(&type
, VT_CONST
, &tokc
);
3748 ST_FUNC
void unary(void)
3750 int n
, t
, align
, size
, r
, sizeof_caller
;
3754 static int in_sizeof
= 0;
3756 sizeof_caller
= in_sizeof
;
3758 /* XXX: GCC 2.95.3 does not generate a table although it should be
3772 vpush_tokc(VT_INT
| VT_UNSIGNED
);
3776 vpush_tokc(VT_LLONG
);
3780 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
3784 vpush_tokc(VT_FLOAT
);
3788 vpush_tokc(VT_DOUBLE
);
3792 vpush_tokc(VT_LDOUBLE
);
3795 case TOK___FUNCTION__
:
3797 goto tok_identifier
;
3803 /* special function name identifier */
3804 len
= strlen(funcname
) + 1;
3805 /* generate char[len] type */
3810 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
3811 ptr
= section_ptr_add(data_section
, len
);
3812 memcpy(ptr
, funcname
, len
);
3817 #ifdef TCC_TARGET_PE
3818 t
= VT_SHORT
| VT_UNSIGNED
;
3824 /* string parsing */
3827 if (tcc_state
->warn_write_strings
)
3832 memset(&ad
, 0, sizeof(AttributeDef
));
3833 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
3838 if (parse_btype(&type
, &ad
)) {
3839 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
3841 /* check ISOC99 compound literal */
3843 /* data is allocated locally by default */
3848 /* all except arrays are lvalues */
3849 if (!(type
.t
& VT_ARRAY
))
3850 r
|= lvalue_type(type
.t
);
3851 memset(&ad
, 0, sizeof(AttributeDef
));
3852 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
3854 if (sizeof_caller
) {
3861 } else if (tok
== '{') {
3863 tcc_error("expected constant");
3864 /* save all registers */
3867 /* statement expression : we do not accept break/continue
3868 inside as GCC does */
3869 block(NULL
, NULL
, 1);
3884 /* functions names must be treated as function pointers,
3885 except for unary '&' and sizeof. Since we consider that
3886 functions are not lvalues, we only have to handle it
3887 there and in function calls. */
3888 /* arrays can also be used although they are not lvalues */
3889 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
3890 !(vtop
->type
.t
& VT_ARRAY
) && !(vtop
->type
.t
& VT_LLOCAL
))
3892 mk_pointer(&vtop
->type
);
3898 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3900 boolean
.t
= VT_BOOL
;
3902 vtop
->c
.i
= !vtop
->c
.i
;
3903 } else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
3907 vseti(VT_JMP
, gvtst(1, 0));
3919 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
3920 tcc_error("pointer not accepted for unary plus");
3921 /* In order to force cast, we add zero, except for floating point
3922 where we really need an noop (otherwise -0.0 will be transformed
3924 if (!is_float(vtop
->type
.t
)) {
3935 unary_type(&type
); // Perform a in_sizeof = 0;
3936 size
= type_size(&type
, &align
);
3937 if (t
== TOK_SIZEOF
) {
3938 if (!(type
.t
& VT_VLA
)) {
3940 tcc_error("sizeof applied to an incomplete type");
3943 vla_runtime_type_size(&type
, &align
);
3948 vtop
->type
.t
|= VT_UNSIGNED
;
3951 case TOK_builtin_expect
:
3953 /* __builtin_expect is a no-op for now */
3954 int saved_nocode_wanted
;
3959 saved_nocode_wanted
= nocode_wanted
;
3963 nocode_wanted
= saved_nocode_wanted
;
3967 case TOK_builtin_types_compatible_p
:
3976 type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
3977 type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
3978 vpushi(is_compatible_types(&type1
, &type2
));
3981 case TOK_builtin_constant_p
:
3983 int saved_nocode_wanted
, res
;
3986 saved_nocode_wanted
= nocode_wanted
;
3989 res
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3991 nocode_wanted
= saved_nocode_wanted
;
3996 case TOK_builtin_frame_address
:
3997 case TOK_builtin_return_address
:
4004 if (tok
!= TOK_CINT
) {
4005 tcc_error("%s only takes positive integers",
4006 tok1
== TOK_builtin_return_address
?
4007 "__builtin_return_address" :
4008 "__builtin_frame_address");
4010 level
= (uint32_t)tokc
.i
;
4015 vset(&type
, VT_LOCAL
, 0); /* local frame */
4017 mk_pointer(&vtop
->type
);
4018 indir(); /* -> parent frame */
4020 if (tok1
== TOK_builtin_return_address
) {
4021 // assume return address is just above frame pointer on stack
4024 mk_pointer(&vtop
->type
);
4029 #ifdef TCC_TARGET_X86_64
4030 #ifdef TCC_TARGET_PE
4031 case TOK_builtin_va_start
:
4039 if ((vtop
->r
& VT_VALMASK
) != VT_LOCAL
)
4040 tcc_error("__builtin_va_start expects a local variable");
4041 vtop
->r
&= ~(VT_LVAL
| VT_REF
);
4042 vtop
->type
= char_pointer_type
;
4048 case TOK_builtin_va_arg_types
:
4055 vpushi(classify_x86_64_va_arg(&type
));
4061 #ifdef TCC_TARGET_ARM64
4062 case TOK___va_start
: {
4064 tcc_error("statement in global scope");
4074 vtop
->type
.t
= VT_VOID
;
4077 case TOK___va_arg
: {
4080 tcc_error("statement in global scope");
4092 case TOK___arm64_clear_cache
: {
4101 vtop
->type
.t
= VT_VOID
;
4105 /* pre operations */
4116 t
= vtop
->type
.t
& VT_BTYPE
;
4118 /* In IEEE negate(x) isn't subtract(0,x), but rather
4123 else if (t
== VT_DOUBLE
)
4134 goto tok_identifier
;
4136 /* allow to take the address of a label */
4137 if (tok
< TOK_UIDENT
)
4138 expect("label identifier");
4139 s
= label_find(tok
);
4141 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
4143 if (s
->r
== LABEL_DECLARED
)
4144 s
->r
= LABEL_FORWARD
;
4147 s
->type
.t
= VT_VOID
;
4148 mk_pointer(&s
->type
);
4149 s
->type
.t
|= VT_STATIC
;
4151 vpushsym(&s
->type
, s
);
4155 // special qnan , snan and infinity values
4157 vpush64(VT_DOUBLE
, 0x7ff8000000000000ULL
);
4161 vpush64(VT_DOUBLE
, 0x7ff0000000000001ULL
);
4165 vpush64(VT_DOUBLE
, 0x7ff0000000000000ULL
);
4174 expect("identifier");
4177 const char *name
= get_tok_str(t
, NULL
);
4179 tcc_error("'%s' undeclared", name
);
4180 /* for simple function calls, we tolerate undeclared
4181 external reference to int() function */
4182 if (tcc_state
->warn_implicit_function_declaration
4183 #ifdef TCC_TARGET_PE
4184 /* people must be warned about using undeclared WINAPI functions
4185 (which usually start with uppercase letter) */
4186 || (name
[0] >= 'A' && name
[0] <= 'Z')
4189 tcc_warning("implicit declaration of function '%s'", name
);
4190 s
= external_global_sym(t
, &func_old_type
, 0);
4192 if ((s
->type
.t
& (VT_STATIC
| VT_INLINE
| VT_BTYPE
)) ==
4193 (VT_STATIC
| VT_INLINE
| VT_FUNC
)) {
4194 /* if referencing an inline function, then we generate a
4195 symbol to it if not already done. It will have the
4196 effect to generate code for it at the end of the
4197 compilation unit. Inline function as always
4198 generated in the text section. */
4200 put_extern_sym(s
, text_section
, 0, 0);
4201 r
= VT_SYM
| VT_CONST
;
4205 vset(&s
->type
, r
, s
->c
);
4206 /* if forward reference, we must point to s */
4207 if (vtop
->r
& VT_SYM
) {
4214 /* post operations */
4216 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
4219 } else if (tok
== '.' || tok
== TOK_ARROW
|| tok
== TOK_CDOUBLE
) {
4222 if (tok
== TOK_ARROW
)
4224 qualifiers
= vtop
->type
.t
& (VT_CONSTANT
| VT_VOLATILE
);
4227 /* expect pointer on structure */
4228 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
4229 expect("struct or union");
4230 if (tok
== TOK_CDOUBLE
)
4231 expect("field name");
4233 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
4234 expect("field name");
4238 while ((s
= s
->next
) != NULL
) {
4243 tcc_error("field not found: %s", get_tok_str(tok
& ~SYM_FIELD
, &tokc
));
4244 /* add field offset to pointer */
4245 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
4248 /* change type to field type, and set to lvalue */
4249 vtop
->type
= s
->type
;
4250 vtop
->type
.t
|= qualifiers
;
4251 /* an array is never an lvalue */
4252 if (!(vtop
->type
.t
& VT_ARRAY
)) {
4253 vtop
->r
|= lvalue_type(vtop
->type
.t
);
4254 #ifdef CONFIG_TCC_BCHECK
4255 /* if bound checking, the referenced pointer must be checked */
4256 if (tcc_state
->do_bounds_check
)
4257 vtop
->r
|= VT_MUSTBOUND
;
4261 } else if (tok
== '[') {
4267 } else if (tok
== '(') {
4270 int nb_args
, ret_nregs
, ret_align
, regsize
, variadic
;
4273 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
4274 /* pointer test (no array accepted) */
4275 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
4276 vtop
->type
= *pointed_type(&vtop
->type
);
4277 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
4281 expect("function pointer");
4284 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
4286 /* get return type */
4289 sa
= s
->next
; /* first parameter */
4292 /* compute first implicit argument if a structure is returned */
4293 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
4294 variadic
= (s
->c
== FUNC_ELLIPSIS
);
4295 ret_nregs
= gfunc_sret(&s
->type
, variadic
, &ret
.type
,
4296 &ret_align
, ®size
);
4298 /* get some space for the returned structure */
4299 size
= type_size(&s
->type
, &align
);
4300 #ifdef TCC_TARGET_ARM64
4301 /* On arm64, a small struct is return in registers.
4302 It is much easier to write it to memory if we know
4303 that we are allowed to write some extra bytes, so
4304 round the allocated space up to a power of 2: */
4306 while (size
& (size
- 1))
4307 size
= (size
| (size
- 1)) + 1;
4309 loc
= (loc
- size
) & -align
;
4311 ret
.r
= VT_LOCAL
| VT_LVAL
;
4312 /* pass it as 'int' to avoid structure arg passing
4314 vseti(VT_LOCAL
, loc
);
4324 /* return in register */
4325 if (is_float(ret
.type
.t
)) {
4326 ret
.r
= reg_fret(ret
.type
.t
);
4327 #ifdef TCC_TARGET_X86_64
4328 if ((ret
.type
.t
& VT_BTYPE
) == VT_QFLOAT
)
4332 #ifndef TCC_TARGET_ARM64
4333 #ifdef TCC_TARGET_X86_64
4334 if ((ret
.type
.t
& VT_BTYPE
) == VT_QLONG
)
4336 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
4347 gfunc_param_typed(s
, sa
);
4357 tcc_error("too few arguments to function");
4359 if (!nocode_wanted
) {
4360 gfunc_call(nb_args
);
4362 vtop
-= (nb_args
+ 1);
4366 for (r
= ret
.r
+ ret_nregs
+ !ret_nregs
; r
-- > ret
.r
;) {
4367 vsetc(&ret
.type
, r
, &ret
.c
);
4368 vtop
->r2
= ret
.r2
; /* Loop only happens when r2 is VT_CONST */
4371 /* handle packed struct return */
4372 if (((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) && ret_nregs
) {
4375 size
= type_size(&s
->type
, &align
);
4376 /* We're writing whole regs often, make sure there's enough
4377 space. Assume register size is power of 2. */
4378 if (regsize
> align
)
4380 loc
= (loc
- size
) & -align
;
4384 vset(&ret
.type
, VT_LOCAL
| VT_LVAL
, addr
+ offset
);
4388 if (--ret_nregs
== 0)
4392 vset(&s
->type
, VT_LOCAL
| VT_LVAL
, addr
);
4400 ST_FUNC
void expr_prod(void)
4405 while (tok
== '*' || tok
== '/' || tok
== '%') {
4413 ST_FUNC
void expr_sum(void)
4418 while (tok
== '+' || tok
== '-') {
4426 static void expr_shift(void)
4431 while (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
4439 static void expr_cmp(void)
4444 while ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
4445 tok
== TOK_ULT
|| tok
== TOK_UGE
) {
4453 static void expr_cmpeq(void)
4458 while (tok
== TOK_EQ
|| tok
== TOK_NE
) {
4466 static void expr_and(void)
4469 while (tok
== '&') {
4476 static void expr_xor(void)
4479 while (tok
== '^') {
4486 static void expr_or(void)
4489 while (tok
== '|') {
4496 /* XXX: fix this mess */
4497 static void expr_land_const(void)
4500 while (tok
== TOK_LAND
) {
4506 static void expr_lor_const(void)
4509 while (tok
== TOK_LOR
) {
4516 static void expr_land(void)
4519 if (tok
== TOK_LAND
) {
4520 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
4531 int saved_nocode_wanted
= nocode_wanted
;
4535 nocode_wanted
= saved_nocode_wanted
;
4543 if (tok
!= TOK_LAND
) {
4554 static void expr_lor(void)
4557 if (tok
== TOK_LOR
) {
4558 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
4565 int saved_nocode_wanted
= nocode_wanted
;
4569 nocode_wanted
= saved_nocode_wanted
;
4581 if (tok
!= TOK_LOR
) {
4592 static void expr_cond(void)
4594 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
, islv
;
4596 CType type
, type1
, type2
;
4601 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
4602 int saved_nocode_wanted
= nocode_wanted
;
4605 boolean
.t
= VT_BOOL
;
4611 if (tok
!= ':' || !gnu_ext
) {
4619 nocode_wanted
= saved_nocode_wanted
;
4622 if (tok
!= ':' || !gnu_ext
) {
4626 nocode_wanted
= saved_nocode_wanted
;
4633 if (vtop
!= vstack
) {
4634 /* needed to avoid having different registers saved in
4636 if (is_float(vtop
->type
.t
)) {
4638 #ifdef TCC_TARGET_X86_64
4639 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LDOUBLE
) {
4649 if (tok
== ':' && gnu_ext
) {
4657 sv
= *vtop
; /* save value to handle it later */
4658 vtop
--; /* no vpop so that FP stack is not flushed */
4666 bt1
= t1
& VT_BTYPE
;
4668 bt2
= t2
& VT_BTYPE
;
4669 /* cast operands to correct type according to ISOC rules */
4670 if (is_float(bt1
) || is_float(bt2
)) {
4671 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
4672 type
.t
= VT_LDOUBLE
;
4673 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
4678 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
4679 /* cast to biggest op */
4681 /* convert to unsigned if it does not fit in a long long */
4682 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
4683 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
4684 type
.t
|= VT_UNSIGNED
;
4685 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
4686 /* If one is a null ptr constant the result type
4688 if (is_null_pointer (vtop
))
4690 else if (is_null_pointer (&sv
))
4692 /* XXX: test pointer compatibility, C99 has more elaborate
4696 } else if (bt1
== VT_FUNC
|| bt2
== VT_FUNC
) {
4697 /* XXX: test function pointer compatibility */
4698 type
= bt1
== VT_FUNC
? type1
: type2
;
4699 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
4700 /* XXX: test structure compatibility */
4701 type
= bt1
== VT_STRUCT
? type1
: type2
;
4702 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
4703 /* NOTE: as an extension, we accept void on only one side */
4706 /* integer operations */
4708 /* convert to unsigned if it does not fit in an integer */
4709 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
4710 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
4711 type
.t
|= VT_UNSIGNED
;
4713 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
4714 that `(expr ? a : b).mem` does not error with "lvalue expected" */
4715 islv
= (vtop
->r
& VT_LVAL
) && (sv
.r
& VT_LVAL
) && VT_STRUCT
== (type
.t
& VT_BTYPE
);
4717 /* now we convert second operand */
4720 mk_pointer(&vtop
->type
);
4723 else if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
4726 if (is_float(type
.t
)) {
4728 #ifdef TCC_TARGET_X86_64
4729 if ((type
.t
& VT_BTYPE
) == VT_LDOUBLE
) {
4733 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
4734 /* for long longs, we use fixed registers to avoid having
4735 to handle a complicated move */
4740 /* this is horrible, but we must also convert first
4744 /* put again first value and cast it */
4748 mk_pointer(&vtop
->type
);
4751 else if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
4754 move_reg(r2
, r1
, type
.t
);
4763 static void expr_eq(void)
4769 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
4770 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
4771 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
4786 ST_FUNC
void gexpr(void)
4797 /* parse an expression and return its type without any side effect. */
4798 static void expr_type(CType
*type
)
4800 int saved_nocode_wanted
;
4802 saved_nocode_wanted
= nocode_wanted
;
4807 nocode_wanted
= saved_nocode_wanted
;
4810 /* parse a unary expression and return its type without any side
4812 static void unary_type(CType
*type
)
4824 /* parse a constant expression and return value in vtop. */
4825 static void expr_const1(void)
4834 /* parse an integer constant and return its value. */
4835 ST_FUNC
int expr_const(void)
4839 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
4840 expect("constant expression");
4846 /* return the label token if current token is a label, otherwise
4848 static int is_label(void)
4852 /* fast test first */
4853 if (tok
< TOK_UIDENT
)
4855 /* no need to save tokc because tok is an identifier */
4862 unget_tok(last_tok
);
4867 static void label_or_decl(int l
)
4871 /* fast test first */
4872 if (tok
>= TOK_UIDENT
)
4874 /* no need to save tokc because tok is an identifier */
4878 unget_tok(last_tok
);
4881 unget_tok(last_tok
);
4886 static int case_cmp(const void *a
, const void *b
)
4887 { return (*(struct case_t
**) a
)->v1
- (*(struct case_t
**) b
)->v1
; }
4889 static void block(int *bsym
, int *csym
, int is_expr
)
4894 /* generate line number info */
4895 if (tcc_state
->do_debug
&&
4896 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
4897 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
4899 last_line_num
= file
->line_num
;
4903 /* default return value is (void) */
4905 vtop
->type
.t
= VT_VOID
;
4908 if (tok
== TOK_IF
) {
4915 block(bsym
, csym
, 0);
4917 if (c
== TOK_ELSE
) {
4921 block(bsym
, csym
, 0);
4922 gsym(d
); /* patch else jmp */
4925 } else if (tok
== TOK_WHILE
) {
4941 } else if (tok
== '{') {
4943 int block_vla_sp_loc
= vla_sp_loc
, saved_vlas_in_scope
= vlas_in_scope
;
4946 /* record local declaration stack position */
4948 llabel
= local_label_stack
;
4951 /* handle local labels declarations */
4952 if (tok
== TOK_LABEL
) {
4955 if (tok
< TOK_UIDENT
)
4956 expect("label identifier");
4957 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
4967 while (tok
!= '}') {
4968 label_or_decl(VT_LOCAL
);
4972 block(bsym
, csym
, is_expr
);
4975 /* pop locally defined labels */
4976 label_pop(&local_label_stack
, llabel
);
4978 /* XXX: this solution makes only valgrind happy...
4979 triggered by gcc.c-torture/execute/20000917-1.c */
4981 switch(vtop
->type
.t
& VT_BTYPE
) {
4983 /* this breaks a compilation of the linux kernel v2.4.26 */
4984 /* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */
4985 /* Look a commit a80acab: Display error on statement expressions with complex return type */
4986 /* A pointer is not a complex return type */
4990 for(p
=vtop
->type
.ref
;p
;p
=p
->prev
)
4992 tcc_error("unsupported expression type");
4995 /* pop locally defined symbols */
4997 sym_pop(&local_stack
, s
);
4999 /* Pop VLA frames and restore stack pointer if required */
5000 if (vlas_in_scope
> saved_vlas_in_scope
) {
5001 vla_sp_loc
= saved_vlas_in_scope
? block_vla_sp_loc
: vla_sp_root_loc
;
5004 vlas_in_scope
= saved_vlas_in_scope
;
5007 } else if (tok
== TOK_RETURN
) {
5011 gen_assign_cast(&func_vt
);
5012 #ifdef TCC_TARGET_ARM64
5013 // Perhaps it would be better to use this for all backends:
5016 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
5017 CType type
, ret_type
;
5018 int ret_align
, ret_nregs
, regsize
;
5019 ret_nregs
= gfunc_sret(&func_vt
, func_var
, &ret_type
,
5020 &ret_align
, ®size
);
5021 if (0 == ret_nregs
) {
5022 /* if returning structure, must copy it to implicit
5023 first pointer arg location */
5026 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
5029 /* copy structure value to pointer */
5032 /* returning structure packed into registers */
5033 int r
, size
, addr
, align
;
5034 size
= type_size(&func_vt
,&align
);
5035 if ((vtop
->r
!= (VT_LOCAL
| VT_LVAL
) ||
5036 (vtop
->c
.i
& (ret_align
-1)))
5037 && (align
& (ret_align
-1))) {
5038 loc
= (loc
- size
) & -ret_align
;
5041 vset(&type
, VT_LOCAL
| VT_LVAL
, addr
);
5045 vset(&ret_type
, VT_LOCAL
| VT_LVAL
, addr
);
5047 vtop
->type
= ret_type
;
5048 if (is_float(ret_type
.t
))
5049 r
= rc_fret(ret_type
.t
);
5055 if (--ret_nregs
== 0)
5057 /* We assume that when a structure is returned in multiple
5058 registers, their classes are consecutive values of the
5061 vtop
->c
.i
+= regsize
;
5062 vtop
->r
= VT_LOCAL
| VT_LVAL
;
5065 } else if (is_float(func_vt
.t
)) {
5066 gv(rc_fret(func_vt
.t
));
5071 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5074 /* jump unless last stmt in top-level block */
5075 if (tok
!= '}' || local_scope
!= 1)
5077 } else if (tok
== TOK_BREAK
) {
5080 tcc_error("cannot break");
5081 *bsym
= gjmp(*bsym
);
5084 } else if (tok
== TOK_CONTINUE
) {
5087 tcc_error("cannot continue");
5088 vla_sp_restore_root();
5089 *csym
= gjmp(*csym
);
5092 } else if (tok
== TOK_FOR
) {
5099 /* c99 for-loop init decl? */
5100 if (!decl0(VT_LOCAL
, 1)) {
5101 /* no, regular for-loop init expr */
5133 sym_pop(&local_stack
, s
);
5136 if (tok
== TOK_DO
) {
5153 if (tok
== TOK_SWITCH
) {
5154 struct switch_t
*saved
, sw
;
5158 /* XXX: other types than integer */
5163 b
= gjmp(0); /* jump to first case */
5164 sw
.p
= NULL
; sw
.n
= 0; sw
.def_sym
= 0;
5166 cur_switch
= &sw
; block(&a
, csym
, 0);
5168 a
= gjmp(a
); /* add implicit break */
5171 qsort(sw
.p
, sw
.n
, sizeof(void*), case_cmp
);
5172 for (b
= 0; b
< sw
.n
; b
++) {
5173 int v
= sw
.p
[b
]->v1
;
5175 tcc_error("duplicate case value");
5182 gtst_addr(0, sw
.p
[b
]->sym
);
5190 gtst_addr(0, sw
.p
[b
]->sym
);
5195 gjmp_addr(sw
.def_sym
);
5199 if (tok
== TOK_CASE
) {
5200 struct case_t
*cr
= tcc_malloc(sizeof(struct case_t
));
5204 cr
->v1
= cr
->v2
= expr_const();
5205 if (gnu_ext
&& tok
== TOK_DOTS
) {
5207 cr
->v2
= expr_const();
5208 if (cr
->v2
< cr
->v1
)
5209 tcc_warning("empty case range");
5212 dynarray_add((void***) &cur_switch
->p
, &cur_switch
->n
, cr
);
5215 goto block_after_label
;
5217 if (tok
== TOK_DEFAULT
) {
5222 if (cur_switch
->def_sym
)
5223 tcc_error("too many 'default'");
5224 cur_switch
->def_sym
= ind
;
5226 goto block_after_label
;
5228 if (tok
== TOK_GOTO
) {
5230 if (tok
== '*' && gnu_ext
) {
5234 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
5237 } else if (tok
>= TOK_UIDENT
) {
5238 s
= label_find(tok
);
5239 /* put forward definition if needed */
5241 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
5243 if (s
->r
== LABEL_DECLARED
)
5244 s
->r
= LABEL_FORWARD
;
5246 vla_sp_restore_root();
5247 if (s
->r
& LABEL_FORWARD
)
5248 s
->jnext
= gjmp(s
->jnext
);
5250 gjmp_addr(s
->jnext
);
5253 expect("label identifier");
5256 } else if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
5264 if (s
->r
== LABEL_DEFINED
)
5265 tcc_error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
5267 s
->r
= LABEL_DEFINED
;
5269 s
= label_push(&global_label_stack
, b
, LABEL_DEFINED
);
5273 /* we accept this, but it is a mistake */
5276 tcc_warning("deprecated use of label at end of compound statement");
5280 block(bsym
, csym
, is_expr
);
5283 /* expression case */
5298 /* t is the array or struct type. c is the array or struct
5299 address. cur_index/cur_field is the pointer to the current
5300 value. 'size_only' is true if only size info is needed (only used
5302 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
5303 int *cur_index
, Sym
**cur_field
,
5307 int notfirst
, index
, index_last
, align
, l
, nb_elems
, elem_size
;
5313 if (gnu_ext
&& (l
= is_label()) != 0)
5315 while (tok
== '[' || tok
== '.') {
5317 if (!(type
->t
& VT_ARRAY
))
5318 expect("array type");
5321 index
= expr_const();
5322 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
5323 expect("invalid index");
5324 if (tok
== TOK_DOTS
&& gnu_ext
) {
5326 index_last
= expr_const();
5327 if (index_last
< 0 ||
5328 (s
->c
>= 0 && index_last
>= s
->c
) ||
5330 expect("invalid index");
5336 *cur_index
= index_last
;
5337 type
= pointed_type(type
);
5338 elem_size
= type_size(type
, &align
);
5339 c
+= index
* elem_size
;
5340 /* NOTE: we only support ranges for last designator */
5341 nb_elems
= index_last
- index
+ 1;
5342 if (nb_elems
!= 1) {
5351 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
5352 expect("struct/union type");
5365 /* XXX: fix this mess by using explicit storage field */
5367 type1
.t
|= (type
->t
& ~VT_TYPE
);
5381 if (type
->t
& VT_ARRAY
) {
5383 type
= pointed_type(type
);
5384 c
+= index
* type_size(type
, &align
);
5388 tcc_error("too many field init");
5389 /* XXX: fix this mess by using explicit storage field */
5391 type1
.t
|= (type
->t
& ~VT_TYPE
);
5396 decl_initializer(type
, sec
, c
, 0, size_only
);
5398 /* XXX: make it more general */
5399 if (!size_only
&& nb_elems
> 1) {
5400 unsigned long c_end
;
5405 tcc_error("range init not supported yet for dynamic storage");
5406 c_end
= c
+ nb_elems
* elem_size
;
5407 if (c_end
> sec
->data_allocated
)
5408 section_realloc(sec
, c_end
);
5409 src
= sec
->data
+ c
;
5411 for(i
= 1; i
< nb_elems
; i
++) {
5413 memcpy(dst
, src
, elem_size
);
5419 #define EXPR_CONST 1
5422 /* store a value or an expression directly in global data or in local array */
5423 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
5424 int v
, int expr_type
)
5426 int saved_global_expr
, bt
, bit_pos
, bit_size
;
5428 unsigned long long bit_mask
;
5436 /* compound literals must be allocated globally in this case */
5437 saved_global_expr
= global_expr
;
5440 global_expr
= saved_global_expr
;
5441 /* NOTE: symbols are accepted */
5442 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
5443 tcc_error("initializer element is not constant");
5451 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
5454 /* XXX: not portable */
5455 /* XXX: generate error if incorrect relocation */
5456 gen_assign_cast(&dtype
);
5457 bt
= type
->t
& VT_BTYPE
;
5458 /* we'll write at most 16 bytes */
5459 if (c
+ 16 > sec
->data_allocated
) {
5460 section_realloc(sec
, c
+ 16);
5462 ptr
= sec
->data
+ c
;
5463 /* XXX: make code faster ? */
5464 if (!(type
->t
& VT_BITFIELD
)) {
5469 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
5470 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
5471 bit_mask
= (1LL << bit_size
) - 1;
5473 if ((vtop
->r
& VT_SYM
) &&
5479 (bt
== VT_INT
&& bit_size
!= 32)))
5480 tcc_error("initializer element is not computable at load time");
5482 /* XXX: when cross-compiling we assume that each type has the
5483 same representation on host and target, which is likely to
5484 be wrong in the case of long double */
5486 vtop
->c
.i
= (vtop
->c
.i
!= 0);
5488 *(char *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
5491 *(short *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
5494 *(double *)ptr
= vtop
->c
.d
;
5497 *(long double *)ptr
= vtop
->c
.ld
;
5500 *(long long *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
5503 addr_t val
= (vtop
->c
.i
& bit_mask
) << bit_pos
;
5504 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5505 if (vtop
->r
& VT_SYM
)
5506 greloca(sec
, vtop
->sym
, c
, R_DATA_PTR
, val
);
5508 *(addr_t
*)ptr
|= val
;
5510 if (vtop
->r
& VT_SYM
)
5511 greloc(sec
, vtop
->sym
, c
, R_DATA_PTR
);
5512 *(addr_t
*)ptr
|= val
;
5517 int val
= (vtop
->c
.i
& bit_mask
) << bit_pos
;
5518 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5519 if (vtop
->r
& VT_SYM
)
5520 greloca(sec
, vtop
->sym
, c
, R_DATA_PTR
, val
);
5524 if (vtop
->r
& VT_SYM
)
5525 greloc(sec
, vtop
->sym
, c
, R_DATA_PTR
);
5533 vset(&dtype
, VT_LOCAL
|VT_LVAL
, c
);
5540 /* put zeros for variable based init */
5541 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
5544 /* nothing to do because globals are already set to zero */
5546 vpush_global_sym(&func_old_type
, TOK_memset
);
5548 #ifdef TCC_TARGET_ARM
5559 /* 't' contains the type and storage info. 'c' is the offset of the
5560 object in section 'sec'. If 'sec' is NULL, it means stack based
5561 allocation. 'first' is true if array '{' must be read (multi
5562 dimension implicit array init handling). 'size_only' is true if
5563 size only evaluation is wanted (only for arrays). */
5564 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
5565 int first
, int size_only
)
5567 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, parlevel1
, i
;
5568 int size1
, align1
, expr_type
;
5572 if (type
->t
& VT_VLA
) {
5575 /* save current stack pointer */
5576 if (vlas_in_scope
== 0) {
5577 if (vla_sp_root_loc
== -1)
5578 vla_sp_root_loc
= (loc
-= PTR_SIZE
);
5579 gen_vla_sp_save(vla_sp_root_loc
);
5582 vla_runtime_type_size(type
, &a
);
5583 gen_vla_alloc(type
, a
);
5587 } else if (type
->t
& VT_ARRAY
) {
5591 t1
= pointed_type(type
);
5592 size1
= type_size(t1
, &align1
);
5595 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
5598 tcc_error("character array initializer must be a literal,"
5599 " optionally enclosed in braces");
5604 /* only parse strings here if correct type (otherwise: handle
5605 them as ((w)char *) expressions */
5606 if ((tok
== TOK_LSTR
&&
5607 #ifdef TCC_TARGET_PE
5608 (t1
->t
& VT_BTYPE
) == VT_SHORT
&& (t1
->t
& VT_UNSIGNED
)
5610 (t1
->t
& VT_BTYPE
) == VT_INT
5612 ) || (tok
== TOK_STR
&& (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
5613 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5616 /* compute maximum number of chars wanted */
5618 cstr_len
= tokc
.str
.size
;
5620 cstr_len
= tokc
.str
.size
/ sizeof(nwchar_t
);
5623 if (n
>= 0 && nb
> (n
- array_length
))
5624 nb
= n
- array_length
;
5627 tcc_warning("initializer-string for array is too long");
5628 /* in order to go faster for common case (char
5629 string in global variable, we handle it
5631 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
5632 memcpy(sec
->data
+ c
+ array_length
, tokc
.str
.data
, nb
);
5636 ch
= ((unsigned char *)tokc
.str
.data
)[i
];
5638 ch
= ((nwchar_t
*)tokc
.str
.data
)[i
];
5639 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
5647 /* only add trailing zero if enough storage (no
5648 warning in this case since it is standard) */
5649 if (n
< 0 || array_length
< n
) {
5651 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
5657 while (tok
!= '}') {
5658 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
5659 if (n
>= 0 && index
>= n
)
5660 tcc_error("index too large");
5661 /* must put zero in holes (note that doing it that way
5662 ensures that it even works with designators) */
5663 if (!size_only
&& array_length
< index
) {
5664 init_putz(t1
, sec
, c
+ array_length
* size1
,
5665 (index
- array_length
) * size1
);
5668 if (index
> array_length
)
5669 array_length
= index
;
5670 /* special test for multi dimensional arrays (may not
5671 be strictly correct if designators are used at the
5673 if (index
>= n
&& no_oblock
)
5682 /* put zeros at the end */
5683 if (!size_only
&& n
>= 0 && array_length
< n
) {
5684 init_putz(t1
, sec
, c
+ array_length
* size1
,
5685 (n
- array_length
) * size1
);
5687 /* patch type size if needed */
5689 s
->c
= array_length
;
5690 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&&
5691 (sec
|| !first
|| tok
== '{')) {
5693 /* NOTE: the previous test is a specific case for automatic
5694 struct/union init */
5695 /* XXX: union needs only one init */
5702 if (tcc_state
->old_struct_init_code
) {
5703 /* an old version of struct initialization.
5704 It have a problems. But with a new version
5705 linux 2.4.26 can't load ramdisk.
5707 while (tok
== '(') {
5711 if (!parse_btype(&type1
, &ad1
))
5713 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
5715 if (!is_assignable_types(type
, &type1
))
5716 tcc_error("invalid type for cast");
5723 if (!parse_btype(&type1
, &ad1
))
5725 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
5727 if (!is_assignable_types(type
, &type1
))
5728 tcc_error("invalid type for cast");
5737 if (first
|| tok
== '{') {
5746 while (tok
!= '}') {
5747 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
5749 if (!size_only
&& array_length
< index
) {
5750 init_putz(type
, sec
, c
+ array_length
,
5751 index
- array_length
);
5753 index
= index
+ type_size(&f
->type
, &align1
);
5754 if (index
> array_length
)
5755 array_length
= index
;
5757 /* gr: skip fields from same union - ugly. */
5760 int f_size
= type_size(&f
->type
, &align
);
5761 int f_type
= (f
->type
.t
& VT_BTYPE
);
5763 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5764 /* test for same offset */
5765 if (f
->next
->c
!= f
->c
)
5767 if ((f_type
== VT_STRUCT
) && (f_size
== 0)) {
5769 Lets assume a structure of size 0 can't be a member of the union.
5770 This allow to compile the following code from a linux kernel v2.4.26
5771 typedef struct { } rwlock_t;
5777 struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, };
5778 tcc-0.9.23 can succesfully compile this version of the kernel.
5779 gcc don't have problems with this code too.
5783 /* if yes, test for bitfield shift */
5784 if ((f
->type
.t
& VT_BITFIELD
) && (f
->next
->type
.t
& VT_BITFIELD
)) {
5785 int bit_pos_1
= (f
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
5786 int bit_pos_2
= (f
->next
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
5787 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5788 if (bit_pos_1
!= bit_pos_2
)
5795 if (no_oblock
&& f
== NULL
)
5801 /* put zeros at the end */
5802 if (!size_only
&& array_length
< n
) {
5803 init_putz(type
, sec
, c
+ array_length
,
5812 } else if (tok
== '{') {
5814 decl_initializer(type
, sec
, c
, first
, size_only
);
5816 } else if (size_only
) {
5817 /* just skip expression */
5818 parlevel
= parlevel1
= 0;
5819 while ((parlevel
> 0 || parlevel1
> 0 ||
5820 (tok
!= '}' && tok
!= ',')) && tok
!= -1) {
5823 else if (tok
== ')') {
5824 if (parlevel
== 0 && parlevel1
== 0)
5828 else if (tok
== '{')
5830 else if (tok
== '}') {
5831 if (parlevel
== 0 && parlevel1
== 0)
5838 /* currently, we always use constant expression for globals
5839 (may change for scripting case) */
5840 expr_type
= EXPR_CONST
;
5842 expr_type
= EXPR_ANY
;
5843 init_putv(type
, sec
, c
, 0, expr_type
);
5847 /* parse an initializer for type 't' if 'has_init' is non zero, and
5848 allocate space in local or global data space ('r' is either
5849 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5850 variable 'v' of scope 'scope' is declared before initializers
5851 are parsed. If 'v' is zero, then a reference to the new object
5852 is put in the value stack. If 'has_init' is 2, a special parsing
5853 is done to handle string constants. */
5854 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
5855 int has_init
, int v
, int scope
)
5857 int size
, align
, addr
, data_offset
;
5859 ParseState saved_parse_state
= {0};
5860 TokenString
*init_str
= NULL
;
5862 Sym
*flexible_array
;
5864 flexible_array
= NULL
;
5865 if ((type
->t
& VT_BTYPE
) == VT_STRUCT
) {
5866 Sym
*field
= type
->ref
->next
;
5869 field
= field
->next
;
5870 if (field
->type
.t
& VT_ARRAY
&& field
->type
.ref
->c
< 0)
5871 flexible_array
= field
;
5875 size
= type_size(type
, &align
);
5876 /* If unknown size, we must evaluate it before
5877 evaluating initializers because
5878 initializers can generate global data too
5879 (e.g. string pointers or ISOC99 compound
5880 literals). It also simplifies local
5881 initializers handling */
5882 if (size
< 0 || (flexible_array
&& has_init
)) {
5884 tcc_error("unknown type size");
5885 /* get all init string */
5886 init_str
= tok_str_alloc();
5887 if (has_init
== 2) {
5888 /* only get strings */
5889 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5890 tok_str_add_tok(init_str
);
5895 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
5897 tcc_error("unexpected end of file in initializer");
5898 tok_str_add_tok(init_str
);
5901 else if (tok
== '}') {
5911 tok_str_add(init_str
, -1);
5912 tok_str_add(init_str
, 0);
5915 save_parse_state(&saved_parse_state
);
5917 begin_macro(init_str
, 1);
5919 decl_initializer(type
, NULL
, 0, 1, 1);
5920 /* prepare second initializer parsing */
5921 macro_ptr
= init_str
->str
;
5924 /* if still unknown size, error */
5925 size
= type_size(type
, &align
);
5927 tcc_error("unknown type size");
5929 /* If there's a flex member and it was used in the initializer
5931 if (flexible_array
&&
5932 flexible_array
->type
.ref
->c
> 0)
5933 size
+= flexible_array
->type
.ref
->c
5934 * pointed_size(&flexible_array
->type
);
5935 /* take into account specified alignment if bigger */
5936 if (ad
->a
.aligned
) {
5937 if (ad
->a
.aligned
> align
)
5938 align
= ad
->a
.aligned
;
5939 } else if (ad
->a
.packed
) {
5942 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
5944 #ifdef CONFIG_TCC_BCHECK
5945 if (tcc_state
->do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
5949 loc
= (loc
- size
) & -align
;
5951 #ifdef CONFIG_TCC_BCHECK
5952 /* handles bounds */
5953 /* XXX: currently, since we do only one pass, we cannot track
5954 '&' operators, so we add only arrays */
5955 if (tcc_state
->do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
5957 /* add padding between regions */
5959 /* then add local bound info */
5960 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(addr_t
));
5961 bounds_ptr
[0] = addr
;
5962 bounds_ptr
[1] = size
;
5966 /* local variable */
5967 sym_push(v
, type
, r
, addr
);
5969 /* push local reference */
5970 vset(type
, r
, addr
);
5976 if (v
&& scope
== VT_CONST
) {
5977 /* see if the symbol was already defined */
5980 if (!is_compatible_types(&sym
->type
, type
))
5981 tcc_error("incompatible types for redefinition of '%s'",
5982 get_tok_str(v
, NULL
));
5983 if (sym
->type
.t
& VT_EXTERN
) {
5984 /* if the variable is extern, it was not allocated */
5985 sym
->type
.t
&= ~VT_EXTERN
;
5986 /* set array size if it was omitted in extern
5988 if ((sym
->type
.t
& VT_ARRAY
) &&
5989 sym
->type
.ref
->c
< 0 &&
5991 sym
->type
.ref
->c
= type
->ref
->c
;
5993 /* we accept several definitions of the same
5994 global variable. this is tricky, because we
5995 must play with the SHN_COMMON type of the symbol */
5996 /* XXX: should check if the variable was already
5997 initialized. It is incorrect to initialized it
5999 /* no init data, we won't add more to the symbol */
6006 /* allocate symbol in corresponding section */
6011 else if (tcc_state
->nocommon
)
6015 data_offset
= sec
->data_offset
;
6016 data_offset
= (data_offset
+ align
- 1) & -align
;
6018 /* very important to increment global pointer at this time
6019 because initializers themselves can create new initializers */
6020 data_offset
+= size
;
6021 #ifdef CONFIG_TCC_BCHECK
6022 /* add padding if bound check */
6023 if (tcc_state
->do_bounds_check
)
6026 sec
->data_offset
= data_offset
;
6027 /* allocate section space to put the data */
6028 if (sec
->sh_type
!= SHT_NOBITS
&&
6029 data_offset
> sec
->data_allocated
)
6030 section_realloc(sec
, data_offset
);
6031 /* align section if needed */
6032 if (align
> sec
->sh_addralign
)
6033 sec
->sh_addralign
= align
;
6035 addr
= 0; /* avoid warning */
6039 if (scope
!= VT_CONST
|| !sym
) {
6040 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
6041 sym
->asm_label
= ad
->asm_label
;
6043 /* update symbol definition */
6045 put_extern_sym(sym
, sec
, addr
, size
);
6048 /* put a common area */
6049 put_extern_sym(sym
, NULL
, align
, size
);
6050 /* XXX: find a nicer way */
6051 esym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym
->c
];
6052 esym
->st_shndx
= SHN_COMMON
;
6055 /* push global reference */
6056 sym
= get_sym_ref(type
, sec
, addr
, size
);
6057 vpushsym(type
, sym
);
6059 /* patch symbol weakness */
6060 if (type
->t
& VT_WEAK
)
6062 apply_visibility(sym
, type
);
6063 #ifdef CONFIG_TCC_BCHECK
6064 /* handles bounds now because the symbol must be defined
6065 before for the relocation */
6066 if (tcc_state
->do_bounds_check
) {
6069 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_PTR
);
6070 /* then add global bound info */
6071 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(addr_t
));
6072 bounds_ptr
[0] = 0; /* relocated */
6073 bounds_ptr
[1] = size
;
6077 if (has_init
|| (type
->t
& VT_VLA
)) {
6078 decl_initializer(type
, sec
, addr
, 1, 0);
6079 /* patch flexible array member size back to -1, */
6080 /* for possible subsequent similar declarations */
6082 flexible_array
->type
.ref
->c
= -1;
6085 /* restore parse state if needed */
6088 restore_parse_state(&saved_parse_state
);
6092 static void put_func_debug(Sym
*sym
)
6097 /* XXX: we put here a dummy type */
6098 snprintf(buf
, sizeof(buf
), "%s:%c1",
6099 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
6100 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
6101 cur_text_section
, sym
->c
);
6102 /* //gr gdb wants a line at the function */
6103 put_stabn(N_SLINE
, 0, file
->line_num
, 0);
6108 /* parse an old style function declaration list */
6109 /* XXX: check multiple parameter */
6110 static void func_decl_list(Sym
*func_sym
)
6117 /* parse each declaration */
6118 while (tok
!= '{' && tok
!= ';' && tok
!= ',' && tok
!= TOK_EOF
&&
6119 tok
!= TOK_ASM1
&& tok
!= TOK_ASM2
&& tok
!= TOK_ASM3
) {
6120 if (!parse_btype(&btype
, &ad
))
6121 expect("declaration list");
6122 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
6123 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
6125 /* we accept no variable after */
6129 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
6130 /* find parameter in function parameter list */
6133 if ((s
->v
& ~SYM_FIELD
) == v
)
6137 tcc_error("declaration for parameter '%s' but no such parameter",
6138 get_tok_str(v
, NULL
));
6140 /* check that no storage specifier except 'register' was given */
6141 if (type
.t
& VT_STORAGE
)
6142 tcc_error("storage class specified for '%s'", get_tok_str(v
, NULL
));
6143 convert_parameter_type(&type
);
6144 /* we can add the type (NOTE: it could be local to the function) */
6146 /* accept other parameters */
6157 /* parse a function defined by symbol 'sym' and generate its code in
6158 'cur_text_section' */
6159 static void gen_function(Sym
*sym
)
6161 int saved_nocode_wanted
= nocode_wanted
;
6164 ind
= cur_text_section
->data_offset
;
6165 /* NOTE: we patch the symbol size later */
6166 put_extern_sym(sym
, cur_text_section
, ind
, 0);
6167 funcname
= get_tok_str(sym
->v
, NULL
);
6169 /* Initialize VLA state */
6171 vla_sp_root_loc
= -1;
6172 /* put debug symbol */
6173 if (tcc_state
->do_debug
)
6174 put_func_debug(sym
);
6176 /* push a dummy symbol to enable local sym storage */
6177 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
6178 local_scope
= 1; /* for function parameters */
6179 gfunc_prolog(&sym
->type
);
6183 block(NULL
, NULL
, 0);
6186 cur_text_section
->data_offset
= ind
;
6187 label_pop(&global_label_stack
, NULL
);
6188 /* reset local stack */
6190 sym_pop(&local_stack
, NULL
);
6191 /* end of function */
6192 /* patch symbol size */
6193 ((ElfW(Sym
) *)symtab_section
->data
)[sym
->c
].st_size
=
6195 /* patch symbol weakness (this definition overrules any prototype) */
6196 if (sym
->type
.t
& VT_WEAK
)
6198 apply_visibility(sym
, &sym
->type
);
6199 if (tcc_state
->do_debug
) {
6200 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
6202 /* It's better to crash than to generate wrong code */
6203 cur_text_section
= NULL
;
6204 funcname
= ""; /* for safety */
6205 func_vt
.t
= VT_VOID
; /* for safety */
6206 func_var
= 0; /* for safety */
6207 ind
= 0; /* for safety */
6208 nocode_wanted
= saved_nocode_wanted
;
6212 ST_FUNC
void gen_inline_functions(void)
6215 int inline_generated
, i
, ln
;
6216 struct InlineFunc
*fn
;
6218 ln
= file
->line_num
;
6219 /* iterate while inline function are referenced */
6221 inline_generated
= 0;
6222 for (i
= 0; i
< tcc_state
->nb_inline_fns
; ++i
) {
6223 fn
= tcc_state
->inline_fns
[i
];
6225 if (sym
&& sym
->c
) {
6226 /* the function was used: generate its code and
6227 convert it to a normal function */
6230 pstrcpy(file
->filename
, sizeof file
->filename
, fn
->filename
);
6231 sym
->r
= VT_SYM
| VT_CONST
;
6232 sym
->type
.t
&= ~VT_INLINE
;
6234 begin_macro(&fn
->func_str
, 0);
6236 cur_text_section
= text_section
;
6240 inline_generated
= 1;
6243 if (!inline_generated
)
6246 file
->line_num
= ln
;
6247 /* free tokens of unused inline functions */
6248 for (i
= 0; i
< tcc_state
->nb_inline_fns
; ++i
) {
6249 fn
= tcc_state
->inline_fns
[i
];
6251 tok_str_free(fn
->func_str
.str
);
6253 dynarray_reset(&tcc_state
->inline_fns
, &tcc_state
->nb_inline_fns
);
6256 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6257 static int decl0(int l
, int is_for_loop_init
)
6265 if (!parse_btype(&btype
, &ad
)) {
6266 if (is_for_loop_init
)
6268 /* skip redundant ';' */
6269 /* XXX: find more elegant solution */
6274 if (l
== VT_CONST
&&
6275 (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
6276 /* global asm block */
6280 /* special test for old K&R protos without explicit int
6281 type. Only accepted when defining global data */
6282 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
6286 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
6287 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
6289 if ((btype
.t
& VT_BTYPE
) == VT_STRUCT
) {
6290 int v
= btype
.ref
->v
;
6291 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
)
6292 tcc_warning("unnamed struct/union that defines no instances");
6297 while (1) { /* iterate thru each declaration */
6299 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
6303 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
6304 printf("type = '%s'\n", buf
);
6307 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
6308 if ((type
.t
& VT_STATIC
) && (l
== VT_LOCAL
)) {
6309 tcc_error("function without file scope cannot be static");
6311 /* if old style function prototype, we accept a
6314 if (sym
->c
== FUNC_OLD
)
6315 func_decl_list(sym
);
6318 if (gnu_ext
&& (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
6319 ad
.asm_label
= asm_label_instr();
6320 /* parse one last attribute list, after asm label */
6321 parse_attribute(&ad
);
6328 #ifdef TCC_TARGET_PE
6329 if (ad
.a
.func_import
)
6330 type
.t
|= VT_IMPORT
;
6331 if (ad
.a
.func_export
)
6332 type
.t
|= VT_EXPORT
;
6334 type
.t
|= ad
.a
.visibility
<< VT_VIS_SHIFT
;
6338 tcc_error("cannot use local functions");
6339 if ((type
.t
& VT_BTYPE
) != VT_FUNC
)
6340 expect("function definition");
6342 /* reject abstract declarators in function definition */
6344 while ((sym
= sym
->next
) != NULL
)
6345 if (!(sym
->v
& ~SYM_FIELD
))
6346 expect("identifier");
6348 /* XXX: cannot do better now: convert extern line to static inline */
6349 if ((type
.t
& (VT_EXTERN
| VT_INLINE
)) == (VT_EXTERN
| VT_INLINE
))
6350 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
6355 if ((sym
->type
.t
& VT_BTYPE
) != VT_FUNC
)
6358 ref
= sym
->type
.ref
;
6359 if (0 == ref
->a
.func_proto
)
6360 tcc_error("redefinition of '%s'", get_tok_str(v
, NULL
));
6362 /* use func_call from prototype if not defined */
6363 if (ref
->a
.func_call
!= FUNC_CDECL
6364 && type
.ref
->a
.func_call
== FUNC_CDECL
)
6365 type
.ref
->a
.func_call
= ref
->a
.func_call
;
6367 /* use export from prototype */
6368 if (ref
->a
.func_export
)
6369 type
.ref
->a
.func_export
= 1;
6371 /* use static from prototype */
6372 if (sym
->type
.t
& VT_STATIC
)
6373 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
6375 /* If the definition has no visibility use the
6376 one from prototype. */
6377 if (! (type
.t
& VT_VIS_MASK
))
6378 type
.t
|= sym
->type
.t
& VT_VIS_MASK
;
6380 if (!is_compatible_types(&sym
->type
, &type
)) {
6382 tcc_error("incompatible types for redefinition of '%s'",
6383 get_tok_str(v
, NULL
));
6385 type
.ref
->a
.func_proto
= 0;
6386 /* if symbol is already defined, then put complete type */
6389 /* put function symbol */
6390 sym
= global_identifier_push(v
, type
.t
, 0);
6391 sym
->type
.ref
= type
.ref
;
6394 /* static inline functions are just recorded as a kind
6395 of macro. Their code will be emitted at the end of
6396 the compilation unit only if they are used */
6397 if ((type
.t
& (VT_INLINE
| VT_STATIC
)) ==
6398 (VT_INLINE
| VT_STATIC
)) {
6400 struct InlineFunc
*fn
;
6401 const char *filename
;
6403 filename
= file
? file
->filename
: "";
6404 fn
= tcc_malloc(sizeof *fn
+ strlen(filename
));
6405 strcpy(fn
->filename
, filename
);
6407 tok_str_new(&fn
->func_str
);
6413 tcc_error("unexpected end of file");
6414 tok_str_add_tok(&fn
->func_str
);
6419 } else if (t
== '}') {
6421 if (block_level
== 0)
6425 tok_str_add(&fn
->func_str
, -1);
6426 tok_str_add(&fn
->func_str
, 0);
6427 dynarray_add((void ***)&tcc_state
->inline_fns
, &tcc_state
->nb_inline_fns
, fn
);
6430 /* compute text section */
6431 cur_text_section
= ad
.section
;
6432 if (!cur_text_section
)
6433 cur_text_section
= text_section
;
6434 sym
->r
= VT_SYM
| VT_CONST
;
6439 if (btype
.t
& VT_TYPEDEF
) {
6440 /* save typedefed type */
6441 /* XXX: test storage specifiers ? */
6443 if (sym
&& sym
->scope
== local_scope
) {
6444 if (!is_compatible_types(&sym
->type
, &type
)
6445 || !(sym
->type
.t
& VT_TYPEDEF
))
6446 tcc_error("incompatible redefinition of '%s'",
6447 get_tok_str(v
, NULL
));
6450 sym
= sym_push(v
, &type
, 0, 0);
6453 sym
->type
.t
|= VT_TYPEDEF
;
6456 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
6457 /* external function definition */
6458 /* specific case for func_call attribute */
6459 ad
.a
.func_proto
= 1;
6461 } else if (!(type
.t
& VT_ARRAY
)) {
6462 /* not lvalue if array */
6463 r
|= lvalue_type(type
.t
);
6465 has_init
= (tok
== '=');
6466 if (has_init
&& (type
.t
& VT_VLA
))
6467 tcc_error("Variable length array cannot be initialized");
6468 if ((btype
.t
& VT_EXTERN
) || ((type
.t
& VT_BTYPE
) == VT_FUNC
) ||
6469 ((type
.t
& VT_ARRAY
) && (type
.t
& VT_STATIC
) &&
6470 !has_init
&& l
== VT_CONST
&& type
.ref
->c
< 0)) {
6471 /* external variable or function */
6472 /* NOTE: as GCC, uninitialized global static
6473 arrays of null size are considered as
6475 sym
= external_sym(v
, &type
, r
);
6476 sym
->asm_label
= ad
.asm_label
;
6478 if (ad
.alias_target
) {
6483 alias_target
= sym_find(ad
.alias_target
);
6484 if (!alias_target
|| !alias_target
->c
)
6485 tcc_error("unsupported forward __alias__ attribute");
6486 esym
= &((Elf32_Sym
*)symtab_section
->data
)[alias_target
->c
];
6487 tsec
.sh_num
= esym
->st_shndx
;
6488 put_extern_sym2(sym
, &tsec
, esym
->st_value
, esym
->st_size
, 0);
6491 type
.t
|= (btype
.t
& VT_STATIC
); /* Retain "static". */
6492 if (type
.t
& VT_STATIC
)
6498 decl_initializer_alloc(&type
, &ad
, r
, has_init
, v
, l
);
6502 if (is_for_loop_init
)
6515 ST_FUNC
void decl(int l
)