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
24 /********************************************************/
25 /* global variables */
27 /* loc : local variable index
28 ind : output code index
30 anon_sym: anonymous symbol index
32 ST_DATA
int rsym
, anon_sym
, ind
, loc
;
34 ST_DATA Sym
*global_stack
;
35 ST_DATA Sym
*local_stack
;
36 ST_DATA Sym
*define_stack
;
37 ST_DATA Sym
*global_label_stack
;
38 ST_DATA Sym
*local_label_stack
;
40 static Sym
*sym_free_first
;
41 static void **sym_pools
;
42 static int nb_sym_pools
;
44 static Sym
*all_cleanups
, *pending_gotos
;
45 static int local_scope
;
47 static int constant_p
;
48 ST_DATA
char debug_modes
;
51 static SValue _vstack
[1 + VSTACK_SIZE
];
52 #define vstack (_vstack + 1)
54 ST_DATA
int nocode_wanted
; /* no code generation wanted */
55 #define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
56 #define DATA_ONLY_WANTED 0x80000000 /* ON outside of functions and for static initializers */
58 /* no code output after unconditional jumps such as with if (0) ... */
59 #define CODE_OFF_BIT 0x20000000
60 #define CODE_OFF() if(!nocode_wanted)(nocode_wanted |= CODE_OFF_BIT)
61 #define CODE_ON() (nocode_wanted &= ~CODE_OFF_BIT)
63 /* no code output when parsing sizeof()/typeof() etc. (using nocode_wanted++/--) */
64 #define NOEVAL_MASK 0x0000FFFF
65 #define NOEVAL_WANTED (nocode_wanted & NOEVAL_MASK)
67 /* no code output when parsing constant expressions */
68 #define CONST_WANTED_BIT 0x00010000
69 #define CONST_WANTED_MASK 0x0FFF0000
70 #define CONST_WANTED (nocode_wanted & CONST_WANTED_MASK)
72 ST_DATA
int global_expr
; /* true if compound literals must be allocated globally (used during initializers parsing */
73 ST_DATA CType func_vt
; /* current function return type (used by return instruction) */
74 ST_DATA
int func_var
; /* true if current function is variadic (used by return instruction) */
77 ST_DATA
const char *funcname
;
78 ST_DATA CType int_type
, func_old_type
, char_type
, char_pointer_type
;
79 static CString initstr
;
82 #define VT_SIZE_T (VT_INT | VT_UNSIGNED)
83 #define VT_PTRDIFF_T VT_INT
85 #define VT_SIZE_T (VT_LLONG | VT_UNSIGNED)
86 #define VT_PTRDIFF_T VT_LLONG
88 #define VT_SIZE_T (VT_LONG | VT_LLONG | VT_UNSIGNED)
89 #define VT_PTRDIFF_T (VT_LONG | VT_LLONG)
92 static struct switch_t
{
96 } **p
; int n
; /* list of case ranges */
97 int def_sym
; /* default symbol */
101 struct switch_t
*prev
;
103 } *cur_switch
; /* current switch */
105 #define MAX_TEMP_LOCAL_VARIABLE_NUMBER 8
106 /*list of temporary local variables on the stack in current function. */
107 static struct temp_local_variable
{
108 int location
; //offset on stack. Svalue.c.i
111 } arr_temp_local_vars
[MAX_TEMP_LOCAL_VARIABLE_NUMBER
];
112 static int nb_temp_local_vars
;
114 static struct scope
{
116 struct { int loc
, locorig
, num
; } vla
;
117 struct { Sym
*s
; int n
; } cl
;
120 } *cur_scope
, *loop_scope
, *root_scope
;
129 #define precedence_parser
130 static void init_prec(void);
133 static void gen_cast(CType
*type
);
134 static void gen_cast_s(int t
);
135 static inline CType
*pointed_type(CType
*type
);
136 static int is_compatible_types(CType
*type1
, CType
*type2
);
137 static int parse_btype(CType
*type
, AttributeDef
*ad
, int ignore_label
);
138 static CType
*type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
139 static void parse_expr_type(CType
*type
);
140 static void init_putv(init_params
*p
, CType
*type
, unsigned long c
);
141 static void decl_initializer(init_params
*p
, CType
*type
, unsigned long c
, int flags
);
142 static void block(int is_expr
);
143 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
, int has_init
, int v
, int scope
);
144 static int decl(int l
);
145 static void expr_eq(void);
146 static void vpush_type_size(CType
*type
, int *a
);
147 static int is_compatible_unqualified_types(CType
*type1
, CType
*type2
);
148 static inline int64_t expr_const64(void);
149 static void vpush64(int ty
, unsigned long long v
);
150 static void vpush(CType
*type
);
151 static int gvtst(int inv
, int t
);
152 static void gen_inline_functions(TCCState
*s
);
153 static void free_inline_functions(TCCState
*s
);
154 static void skip_or_save_block(TokenString
**str
);
155 static void gv_dup(void);
156 static int get_temp_local_var(int size
,int align
);
157 static void clear_temp_local_var_list();
158 static void cast_error(CType
*st
, CType
*dt
);
160 /* ------------------------------------------------------------------------- */
161 /* Automagical code suppression */
163 /* Clear 'nocode_wanted' at forward label if it was used */
164 ST_FUNC
void gsym(int t
)
172 /* Clear 'nocode_wanted' if current pc is a label */
178 tcc_tcov_block_begin(tcc_state
);
182 /* Set 'nocode_wanted' after unconditional (backwards) jump */
183 static void gjmp_addr_acs(int t
)
189 /* Set 'nocode_wanted' after unconditional (forwards) jump */
190 static int gjmp_acs(int t
)
197 /* These are #undef'd at the end of this file */
198 #define gjmp_addr gjmp_addr_acs
199 #define gjmp gjmp_acs
200 /* ------------------------------------------------------------------------- */
202 ST_INLN
int is_float(int t
)
204 int bt
= t
& VT_BTYPE
;
205 return bt
== VT_LDOUBLE
211 static inline int is_integer_btype(int bt
)
220 static int btype_size(int bt
)
222 return bt
== VT_BYTE
|| bt
== VT_BOOL
? 1 :
226 bt
== VT_PTR
? PTR_SIZE
: 0;
229 /* returns function return register from type */
230 static int R_RET(int t
)
234 #ifdef TCC_TARGET_X86_64
235 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
237 #elif defined TCC_TARGET_RISCV64
238 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
244 /* returns 2nd function return register, if any */
245 static int R2_RET(int t
)
251 #elif defined TCC_TARGET_X86_64
256 #elif defined TCC_TARGET_RISCV64
263 /* returns true for two-word types */
264 #define USING_TWO_WORDS(t) (R2_RET(t) != VT_CONST)
266 /* put function return registers to stack value */
267 static void PUT_R_RET(SValue
*sv
, int t
)
269 sv
->r
= R_RET(t
), sv
->r2
= R2_RET(t
);
272 /* returns function return register class for type t */
273 static int RC_RET(int t
)
275 return reg_classes
[R_RET(t
)] & ~(RC_FLOAT
| RC_INT
);
278 /* returns generic register class for type t */
279 static int RC_TYPE(int t
)
283 #ifdef TCC_TARGET_X86_64
284 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
286 if ((t
& VT_BTYPE
) == VT_QFLOAT
)
288 #elif defined TCC_TARGET_RISCV64
289 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
295 /* returns 2nd register class corresponding to t and rc */
296 static int RC2_TYPE(int t
, int rc
)
298 if (!USING_TWO_WORDS(t
))
313 /* we use our own 'finite' function to avoid potential problems with
314 non standard math libs */
315 /* XXX: endianness dependent */
316 ST_FUNC
int ieee_finite(double d
)
319 memcpy(p
, &d
, sizeof(double));
320 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
323 /* compiling intel long double natively */
324 #if (defined __i386__ || defined __x86_64__) \
325 && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
326 # define TCC_IS_NATIVE_387
329 ST_FUNC
void test_lvalue(void)
331 if (!(vtop
->r
& VT_LVAL
))
335 ST_FUNC
void check_vstack(void)
337 if (vtop
!= vstack
- 1)
338 tcc_error("internal compiler error: vstack leak (%d)",
339 (int)(vtop
- vstack
+ 1));
342 /* vstack debugging aid */
344 void pv (const char *lbl
, int a
, int b
)
347 for (i
= a
; i
< a
+ b
; ++i
) {
348 SValue
*p
= &vtop
[-i
];
349 printf("%s vtop[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n",
350 lbl
, i
, p
->type
.t
, p
->r
, p
->r2
, (int)p
->c
.i
);
355 /* ------------------------------------------------------------------------- */
356 /* initialize vstack and types. This must be done also for tcc -E */
357 ST_FUNC
void tccgen_init(TCCState
*s1
)
360 memset(vtop
, 0, sizeof *vtop
);
362 /* define some often used types */
365 char_type
.t
= VT_BYTE
;
366 if (s1
->char_is_unsigned
)
367 char_type
.t
|= VT_UNSIGNED
;
368 char_pointer_type
= char_type
;
369 mk_pointer(&char_pointer_type
);
371 func_old_type
.t
= VT_FUNC
;
372 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, 0, 0);
373 func_old_type
.ref
->f
.func_call
= FUNC_CDECL
;
374 func_old_type
.ref
->f
.func_type
= FUNC_OLD
;
375 #ifdef precedence_parser
381 ST_FUNC
int tccgen_compile(TCCState
*s1
)
383 cur_text_section
= NULL
;
386 anon_sym
= SYM_FIRST_ANOM
;
387 nocode_wanted
= DATA_ONLY_WANTED
; /* no code outside of functions */
389 debug_modes
= (s1
->do_debug
? 1 : 0) | s1
->test_coverage
<< 1;
393 #ifdef TCC_TARGET_ARM
397 printf("%s: **** new file\n", file
->filename
);
399 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
| PARSE_FLAG_TOK_STR
;
402 gen_inline_functions(s1
);
404 /* end of translation unit info */
410 ST_FUNC
void tccgen_finish(TCCState
*s1
)
412 tcc_debug_end(s1
); /* just in case of errors: free memory */
413 free_inline_functions(s1
);
414 sym_pop(&global_stack
, NULL
, 0);
415 sym_pop(&local_stack
, NULL
, 0);
416 /* free preprocessor macros */
419 dynarray_reset(&sym_pools
, &nb_sym_pools
);
420 sym_free_first
= NULL
;
421 global_label_stack
= local_label_stack
= NULL
;
423 dynarray_reset(&stk_data
, &nb_stk_data
);
426 /* ------------------------------------------------------------------------- */
427 ST_FUNC ElfSym
*elfsym(Sym
*s
)
431 return &((ElfSym
*)symtab_section
->data
)[s
->c
];
434 /* apply storage attributes to Elf symbol */
435 ST_FUNC
void update_storage(Sym
*sym
)
438 int sym_bind
, old_sym_bind
;
444 if (sym
->a
.visibility
)
445 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
448 if (sym
->type
.t
& (VT_STATIC
| VT_INLINE
))
449 sym_bind
= STB_LOCAL
;
450 else if (sym
->a
.weak
)
453 sym_bind
= STB_GLOBAL
;
454 old_sym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
455 if (sym_bind
!= old_sym_bind
) {
456 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, ELFW(ST_TYPE
)(esym
->st_info
));
460 if (sym
->a
.dllimport
)
461 esym
->st_other
|= ST_PE_IMPORT
;
462 if (sym
->a
.dllexport
)
463 esym
->st_other
|= ST_PE_EXPORT
;
467 printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n",
468 get_tok_str(sym
->v
, NULL
),
469 sym_bind
== STB_WEAK
? 'w' : sym_bind
== STB_LOCAL
? 'l' : 'g',
477 /* ------------------------------------------------------------------------- */
478 /* update sym->c so that it points to an external symbol in section
479 'section' with value 'value' */
481 ST_FUNC
void put_extern_sym2(Sym
*sym
, int sh_num
,
482 addr_t value
, unsigned long size
,
483 int can_add_underscore
)
485 int sym_type
, sym_bind
, info
, other
, t
;
491 name
= get_tok_str(sym
->v
, NULL
);
493 if ((t
& VT_BTYPE
) == VT_FUNC
) {
495 } else if ((t
& VT_BTYPE
) == VT_VOID
) {
496 sym_type
= STT_NOTYPE
;
497 if ((t
& (VT_BTYPE
|VT_ASM_FUNC
)) == VT_ASM_FUNC
)
500 sym_type
= STT_OBJECT
;
502 if (t
& (VT_STATIC
| VT_INLINE
))
503 sym_bind
= STB_LOCAL
;
505 sym_bind
= STB_GLOBAL
;
509 if (sym_type
== STT_FUNC
&& sym
->type
.ref
) {
510 Sym
*ref
= sym
->type
.ref
;
511 if (ref
->a
.nodecorate
) {
512 can_add_underscore
= 0;
514 if (ref
->f
.func_call
== FUNC_STDCALL
&& can_add_underscore
) {
515 sprintf(buf1
, "_%s@%d", name
, ref
->f
.func_args
* PTR_SIZE
);
517 other
|= ST_PE_STDCALL
;
518 can_add_underscore
= 0;
523 if (sym
->asm_label
) {
524 name
= get_tok_str(sym
->asm_label
, NULL
);
525 can_add_underscore
= 0;
528 if (tcc_state
->leading_underscore
&& can_add_underscore
) {
530 pstrcpy(buf1
+ 1, sizeof(buf1
) - 1, name
);
534 info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
535 sym
->c
= put_elf_sym(symtab_section
, value
, size
, info
, other
, sh_num
, name
);
538 tcc_debug_extern_sym(tcc_state
, sym
, sh_num
, sym_bind
, sym_type
);
542 esym
->st_value
= value
;
543 esym
->st_size
= size
;
544 esym
->st_shndx
= sh_num
;
549 ST_FUNC
void put_extern_sym(Sym
*sym
, Section
*s
, addr_t value
, unsigned long size
)
551 if (nocode_wanted
&& (NODATA_WANTED
|| (s
&& s
== cur_text_section
)))
553 put_extern_sym2(sym
, s
? s
->sh_num
: SHN_UNDEF
, value
, size
, 1);
556 /* add a new relocation entry to symbol 'sym' in section 's' */
557 ST_FUNC
void greloca(Section
*s
, Sym
*sym
, unsigned long offset
, int type
,
562 if (nocode_wanted
&& s
== cur_text_section
)
567 put_extern_sym(sym
, NULL
, 0, 0);
571 /* now we can add ELF relocation info */
572 put_elf_reloca(symtab_section
, s
, offset
, type
, c
, addend
);
576 ST_FUNC
void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
578 greloca(s
, sym
, offset
, type
, 0);
582 /* ------------------------------------------------------------------------- */
583 /* symbol allocator */
584 static Sym
*__sym_malloc(void)
586 Sym
*sym_pool
, *sym
, *last_sym
;
589 sym_pool
= tcc_malloc(SYM_POOL_NB
* sizeof(Sym
));
590 dynarray_add(&sym_pools
, &nb_sym_pools
, sym_pool
);
592 last_sym
= sym_free_first
;
594 for(i
= 0; i
< SYM_POOL_NB
; i
++) {
595 sym
->next
= last_sym
;
599 sym_free_first
= last_sym
;
603 static inline Sym
*sym_malloc(void)
607 sym
= sym_free_first
;
609 sym
= __sym_malloc();
610 sym_free_first
= sym
->next
;
613 sym
= tcc_malloc(sizeof(Sym
));
618 ST_INLN
void sym_free(Sym
*sym
)
621 sym
->next
= sym_free_first
;
622 sym_free_first
= sym
;
628 /* push, without hashing */
629 ST_FUNC Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
634 memset(s
, 0, sizeof *s
);
644 /* find a symbol and return its associated structure. 's' is the top
645 of the symbol stack */
646 ST_FUNC Sym
*sym_find2(Sym
*s
, int v
)
658 /* structure lookup */
659 ST_INLN Sym
*struct_find(int v
)
662 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
664 return table_ident
[v
]->sym_struct
;
667 /* find an identifier */
668 ST_INLN Sym
*sym_find(int v
)
671 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
673 return table_ident
[v
]->sym_identifier
;
676 static int sym_scope(Sym
*s
)
678 if (IS_ENUM_VAL (s
->type
.t
))
679 return s
->type
.ref
->sym_scope
;
684 /* push a given symbol on the symbol stack */
685 ST_FUNC Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
694 s
= sym_push2(ps
, v
, type
->t
, c
);
695 s
->type
.ref
= type
->ref
;
697 /* don't record fields or anonymous symbols */
699 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
700 /* record symbol in token array */
701 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
703 ps
= &ts
->sym_struct
;
705 ps
= &ts
->sym_identifier
;
708 s
->sym_scope
= local_scope
;
709 if (s
->prev_tok
&& sym_scope(s
->prev_tok
) == s
->sym_scope
)
710 tcc_error("redeclaration of '%s'",
711 get_tok_str(v
& ~SYM_STRUCT
, NULL
));
716 /* push a global identifier */
717 ST_FUNC Sym
*global_identifier_push(int v
, int t
, int c
)
720 s
= sym_push2(&global_stack
, v
, t
, c
);
721 s
->r
= VT_CONST
| VT_SYM
;
722 /* don't record anonymous symbol */
723 if (v
< SYM_FIRST_ANOM
) {
724 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
725 /* modify the top most local identifier, so that sym_identifier will
726 point to 's' when popped; happens when called from inline asm */
727 while (*ps
!= NULL
&& (*ps
)->sym_scope
)
728 ps
= &(*ps
)->prev_tok
;
735 /* pop symbols until top reaches 'b'. If KEEP is non-zero don't really
736 pop them yet from the list, but do remove them from the token array. */
737 ST_FUNC
void sym_pop(Sym
**ptop
, Sym
*b
, int keep
)
747 /* remove symbol in token array */
749 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
750 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
752 ps
= &ts
->sym_struct
;
754 ps
= &ts
->sym_identifier
;
766 ST_FUNC Sym
*label_find(int v
)
769 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
771 return table_ident
[v
]->sym_label
;
774 ST_FUNC Sym
*label_push(Sym
**ptop
, int v
, int flags
)
777 s
= sym_push2(ptop
, v
, VT_STATIC
, 0);
779 ps
= &table_ident
[v
- TOK_IDENT
]->sym_label
;
780 if (ptop
== &global_label_stack
) {
781 /* modify the top most local identifier, so that
782 sym_identifier will point to 's' when popped */
784 ps
= &(*ps
)->prev_tok
;
791 /* pop labels until element last is reached. Look if any labels are
792 undefined. Define symbols if '&&label' was used. */
793 ST_FUNC
void label_pop(Sym
**ptop
, Sym
*slast
, int keep
)
796 for(s
= *ptop
; s
!= slast
; s
= s1
) {
798 if (s
->r
== LABEL_DECLARED
) {
799 tcc_warning_c(warn_all
)("label '%s' declared but not used", get_tok_str(s
->v
, NULL
));
800 } else if (s
->r
== LABEL_FORWARD
) {
801 tcc_error("label '%s' used but not defined",
802 get_tok_str(s
->v
, NULL
));
805 /* define corresponding symbol. A size of
807 put_extern_sym(s
, cur_text_section
, s
->jnext
, 1);
811 if (s
->r
!= LABEL_GONE
)
812 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= s
->prev_tok
;
822 /* ------------------------------------------------------------------------- */
823 static void vcheck_cmp(void)
825 /* cannot let cpu flags if other instruction are generated. Also
826 avoid leaving VT_JMP anywhere except on the top of the stack
827 because it would complicate the code generator.
829 Don't do this when nocode_wanted. vtop might come from
830 !nocode_wanted regions (see 88_codeopt.c) and transforming
831 it to a register without actually generating code is wrong
832 as their value might still be used for real. All values
833 we push under nocode_wanted will eventually be popped
834 again, so that the VT_CMP/VT_JMP value will be in vtop
835 when code is unsuppressed again. */
837 /* However if it's just automatic suppression via CODE_OFF/ON()
838 then it seems that we better let things work undisturbed.
839 How can it work at all under nocode_wanted? Well, gv() will
840 actually clear it at the gsym() in load()/VT_JMP in the
841 generator backends */
843 if (vtop
->r
== VT_CMP
&& 0 == (nocode_wanted
& ~CODE_OFF_BIT
))
847 static void vsetc(CType
*type
, int r
, CValue
*vc
)
849 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
850 tcc_error("memory full (vstack)");
860 ST_FUNC
void vswap(void)
870 /* pop stack value */
871 ST_FUNC
void vpop(void)
874 v
= vtop
->r
& VT_VALMASK
;
875 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
876 /* for x86, we need to pop the FP stack */
878 o(0xd8dd); /* fstp %st(0) */
882 /* need to put correct jump if && or || without test */
889 /* push constant of type "type" with useless value */
890 static void vpush(CType
*type
)
892 vset(type
, VT_CONST
, 0);
895 /* push arbitrary 64bit constant */
896 static void vpush64(int ty
, unsigned long long v
)
903 vsetc(&ctype
, VT_CONST
, &cval
);
906 /* push integer constant */
907 ST_FUNC
void vpushi(int v
)
912 /* push a pointer sized constant */
913 static void vpushs(addr_t v
)
915 vpush64(VT_SIZE_T
, v
);
918 /* push long long constant */
919 static inline void vpushll(long long v
)
921 vpush64(VT_LLONG
, v
);
924 ST_FUNC
void vset(CType
*type
, int r
, int v
)
928 vsetc(type
, r
, &cval
);
931 static void vseti(int r
, int v
)
939 ST_FUNC
void vpushv(SValue
*v
)
941 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
942 tcc_error("memory full (vstack)");
947 static void vdup(void)
952 /* rotate n first stack elements to the bottom
953 I1 ... In -> I2 ... In I1 [top is right]
955 ST_FUNC
void vrotb(int n
)
967 /* rotate the n elements before entry e towards the top
968 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
970 ST_FUNC
void vrote(SValue
*e
, int n
)
977 for(i
= 0;i
< n
- 1; i
++)
982 /* rotate n first stack elements to the top
983 I1 ... In -> In I1 ... I(n-1) [top is right]
985 ST_FUNC
void vrott(int n
)
990 /* ------------------------------------------------------------------------- */
991 /* vtop->r = VT_CMP means CPU-flags have been set from comparison or test. */
993 /* called from generators to set the result from relational ops */
994 ST_FUNC
void vset_VT_CMP(int op
)
1002 /* called once before asking generators to load VT_CMP to a register */
1003 static void vset_VT_JMP(void)
1005 int op
= vtop
->cmp_op
;
1007 if (vtop
->jtrue
|| vtop
->jfalse
) {
1008 int origt
= vtop
->type
.t
;
1009 /* we need to jump to 'mov $0,%R' or 'mov $1,%R' */
1010 int inv
= op
& (op
< 2); /* small optimization */
1011 vseti(VT_JMP
+inv
, gvtst(inv
, 0));
1012 vtop
->type
.t
|= origt
& (VT_UNSIGNED
| VT_DEFSIGN
);
1014 /* otherwise convert flags (rsp. 0/1) to register */
1016 if (op
< 2) /* doesn't seem to happen */
1021 /* Set CPU Flags, doesn't yet jump */
1022 static void gvtst_set(int inv
, int t
)
1026 if (vtop
->r
!= VT_CMP
) {
1029 if (vtop
->r
!= VT_CMP
) /* must be VT_CONST then */
1030 vset_VT_CMP(vtop
->c
.i
!= 0);
1033 p
= inv
? &vtop
->jfalse
: &vtop
->jtrue
;
1034 *p
= gjmp_append(*p
, t
);
1037 /* Generate value test
1039 * Generate a test for any value (jump, comparison and integers) */
1040 static int gvtst(int inv
, int t
)
1045 t
= vtop
->jtrue
, u
= vtop
->jfalse
;
1047 x
= u
, u
= t
, t
= x
;
1050 /* jump to the wanted target */
1052 t
= gjmp_cond(op
^ inv
, t
);
1055 /* resolve complementary jumps to here */
1062 /* generate a zero or nozero test */
1063 static void gen_test_zero(int op
)
1065 if (vtop
->r
== VT_CMP
) {
1069 vtop
->jfalse
= vtop
->jtrue
;
1079 /* ------------------------------------------------------------------------- */
1080 /* push a symbol value of TYPE */
1081 ST_FUNC
void vpushsym(CType
*type
, Sym
*sym
)
1085 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
1089 /* Return a static symbol pointing to a section */
1090 ST_FUNC Sym
*get_sym_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
1096 sym
= sym_push(v
, type
, VT_CONST
| VT_SYM
, 0);
1097 sym
->type
.t
|= VT_STATIC
;
1098 put_extern_sym(sym
, sec
, offset
, size
);
1102 /* push a reference to a section offset by adding a dummy symbol */
1103 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
1105 vpushsym(type
, get_sym_ref(type
, sec
, offset
, size
));
1108 /* define a new external reference to a symbol 'v' of type 'u' */
1109 ST_FUNC Sym
*external_global_sym(int v
, CType
*type
)
1115 /* push forward reference */
1116 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
1117 s
->type
.ref
= type
->ref
;
1118 } else if (IS_ASM_SYM(s
)) {
1119 s
->type
.t
= type
->t
| (s
->type
.t
& VT_EXTERN
);
1120 s
->type
.ref
= type
->ref
;
1126 /* create an external reference with no specific type similar to asm labels.
1127 This avoids type conflicts if the symbol is used from C too */
1128 ST_FUNC Sym
*external_helper_sym(int v
)
1130 CType ct
= { VT_ASM_FUNC
, NULL
};
1131 return external_global_sym(v
, &ct
);
1134 /* push a reference to an helper function (such as memmove) */
1135 ST_FUNC
void vpush_helper_func(int v
)
1137 vpushsym(&func_old_type
, external_helper_sym(v
));
1140 /* Merge symbol attributes. */
1141 static void merge_symattr(struct SymAttr
*sa
, struct SymAttr
*sa1
)
1143 if (sa1
->aligned
&& !sa
->aligned
)
1144 sa
->aligned
= sa1
->aligned
;
1145 sa
->packed
|= sa1
->packed
;
1146 sa
->weak
|= sa1
->weak
;
1147 sa
->nodebug
|= sa1
->nodebug
;
1148 if (sa1
->visibility
!= STV_DEFAULT
) {
1149 int vis
= sa
->visibility
;
1150 if (vis
== STV_DEFAULT
1151 || vis
> sa1
->visibility
)
1152 vis
= sa1
->visibility
;
1153 sa
->visibility
= vis
;
1155 sa
->dllexport
|= sa1
->dllexport
;
1156 sa
->nodecorate
|= sa1
->nodecorate
;
1157 sa
->dllimport
|= sa1
->dllimport
;
1160 /* Merge function attributes. */
1161 static void merge_funcattr(struct FuncAttr
*fa
, struct FuncAttr
*fa1
)
1163 if (fa1
->func_call
&& !fa
->func_call
)
1164 fa
->func_call
= fa1
->func_call
;
1165 if (fa1
->func_type
&& !fa
->func_type
)
1166 fa
->func_type
= fa1
->func_type
;
1167 if (fa1
->func_args
&& !fa
->func_args
)
1168 fa
->func_args
= fa1
->func_args
;
1169 if (fa1
->func_noreturn
)
1170 fa
->func_noreturn
= 1;
1177 /* Merge attributes. */
1178 static void merge_attr(AttributeDef
*ad
, AttributeDef
*ad1
)
1180 merge_symattr(&ad
->a
, &ad1
->a
);
1181 merge_funcattr(&ad
->f
, &ad1
->f
);
1184 ad
->section
= ad1
->section
;
1185 if (ad1
->alias_target
)
1186 ad
->alias_target
= ad1
->alias_target
;
1188 ad
->asm_label
= ad1
->asm_label
;
1190 ad
->attr_mode
= ad1
->attr_mode
;
1193 /* Merge some type attributes. */
1194 static void patch_type(Sym
*sym
, CType
*type
)
1196 if (!(type
->t
& VT_EXTERN
) || IS_ENUM_VAL(sym
->type
.t
)) {
1197 if (!(sym
->type
.t
& VT_EXTERN
))
1198 tcc_error("redefinition of '%s'", get_tok_str(sym
->v
, NULL
));
1199 sym
->type
.t
&= ~VT_EXTERN
;
1202 if (IS_ASM_SYM(sym
)) {
1203 /* stay static if both are static */
1204 sym
->type
.t
= type
->t
& (sym
->type
.t
| ~VT_STATIC
);
1205 sym
->type
.ref
= type
->ref
;
1208 if (!is_compatible_types(&sym
->type
, type
)) {
1209 tcc_error("incompatible types for redefinition of '%s'",
1210 get_tok_str(sym
->v
, NULL
));
1212 } else if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
) {
1213 int static_proto
= sym
->type
.t
& VT_STATIC
;
1214 /* warn if static follows non-static function declaration */
1215 if ((type
->t
& VT_STATIC
) && !static_proto
1216 /* XXX this test for inline shouldn't be here. Until we
1217 implement gnu-inline mode again it silences a warning for
1218 mingw caused by our workarounds. */
1219 && !((type
->t
| sym
->type
.t
) & VT_INLINE
))
1220 tcc_warning("static storage ignored for redefinition of '%s'",
1221 get_tok_str(sym
->v
, NULL
));
1223 /* set 'inline' if both agree or if one has static */
1224 if ((type
->t
| sym
->type
.t
) & VT_INLINE
) {
1225 if (!((type
->t
^ sym
->type
.t
) & VT_INLINE
)
1226 || ((type
->t
| sym
->type
.t
) & VT_STATIC
))
1227 static_proto
|= VT_INLINE
;
1230 if (0 == (type
->t
& VT_EXTERN
)) {
1231 struct FuncAttr f
= sym
->type
.ref
->f
;
1232 /* put complete type, use static from prototype */
1233 sym
->type
.t
= (type
->t
& ~(VT_STATIC
|VT_INLINE
)) | static_proto
;
1234 sym
->type
.ref
= type
->ref
;
1235 merge_funcattr(&sym
->type
.ref
->f
, &f
);
1237 sym
->type
.t
&= ~VT_INLINE
| static_proto
;
1240 if (sym
->type
.ref
->f
.func_type
== FUNC_OLD
1241 && type
->ref
->f
.func_type
!= FUNC_OLD
) {
1242 sym
->type
.ref
= type
->ref
;
1246 if ((sym
->type
.t
& VT_ARRAY
) && type
->ref
->c
>= 0) {
1247 /* set array size if it was omitted in extern declaration */
1248 sym
->type
.ref
->c
= type
->ref
->c
;
1250 if ((type
->t
^ sym
->type
.t
) & VT_STATIC
)
1251 tcc_warning("storage mismatch for redefinition of '%s'",
1252 get_tok_str(sym
->v
, NULL
));
1256 /* Merge some storage attributes. */
1257 static void patch_storage(Sym
*sym
, AttributeDef
*ad
, CType
*type
)
1260 patch_type(sym
, type
);
1262 #ifdef TCC_TARGET_PE
1263 if (sym
->a
.dllimport
!= ad
->a
.dllimport
)
1264 tcc_error("incompatible dll linkage for redefinition of '%s'",
1265 get_tok_str(sym
->v
, NULL
));
1267 merge_symattr(&sym
->a
, &ad
->a
);
1269 sym
->asm_label
= ad
->asm_label
;
1270 update_storage(sym
);
1273 /* copy sym to other stack */
1274 static Sym
*sym_copy(Sym
*s0
, Sym
**ps
)
1277 s
= sym_malloc(), *s
= *s0
;
1278 s
->prev
= *ps
, *ps
= s
;
1279 if (s
->v
< SYM_FIRST_ANOM
) {
1280 ps
= &table_ident
[s
->v
- TOK_IDENT
]->sym_identifier
;
1281 s
->prev_tok
= *ps
, *ps
= s
;
1286 /* copy s->type.ref to stack 'ps' for VT_FUNC and VT_PTR */
1287 static void sym_copy_ref(Sym
*s
, Sym
**ps
)
1289 int bt
= s
->type
.t
& VT_BTYPE
;
1290 if (bt
== VT_FUNC
|| bt
== VT_PTR
|| (bt
== VT_STRUCT
&& s
->sym_scope
)) {
1291 Sym
**sp
= &s
->type
.ref
;
1292 for (s
= *sp
, *sp
= NULL
; s
; s
= s
->next
) {
1293 Sym
*s2
= sym_copy(s
, ps
);
1294 sp
= &(*sp
= s2
)->next
;
1295 sym_copy_ref(s2
, ps
);
1300 /* define a new external reference to a symbol 'v' */
1301 static Sym
*external_sym(int v
, CType
*type
, int r
, AttributeDef
*ad
)
1305 /* look for global symbol */
1307 while (s
&& s
->sym_scope
)
1311 /* push forward reference */
1312 s
= global_identifier_push(v
, type
->t
, 0);
1315 s
->asm_label
= ad
->asm_label
;
1316 s
->type
.ref
= type
->ref
;
1317 /* copy type to the global stack */
1319 sym_copy_ref(s
, &global_stack
);
1321 patch_storage(s
, ad
, type
);
1323 /* push variables on local_stack if any */
1324 if (local_stack
&& (s
->type
.t
& VT_BTYPE
) != VT_FUNC
)
1325 s
= sym_copy(s
, &local_stack
);
1329 /* save registers up to (vtop - n) stack entry */
1330 ST_FUNC
void save_regs(int n
)
1333 for(p
= vstack
, p1
= vtop
- n
; p
<= p1
; p
++)
1337 /* save r to the memory stack, and mark it as being free */
1338 ST_FUNC
void save_reg(int r
)
1340 save_reg_upstack(r
, 0);
1343 /* save r to the memory stack, and mark it as being free,
1344 if seen up to (vtop - n) stack entry */
1345 ST_FUNC
void save_reg_upstack(int r
, int n
)
1347 int l
, size
, align
, bt
;
1350 if ((r
&= VT_VALMASK
) >= VT_CONST
)
1355 for(p
= vstack
, p1
= vtop
- n
; p
<= p1
; p
++) {
1356 if ((p
->r
& VT_VALMASK
) == r
|| p
->r2
== r
) {
1357 /* must save value on stack if not already done */
1359 bt
= p
->type
.t
& VT_BTYPE
;
1362 if ((p
->r
& VT_LVAL
) || bt
== VT_FUNC
)
1365 size
= type_size(&sv
.type
, &align
);
1366 l
= get_temp_local_var(size
,align
);
1367 sv
.r
= VT_LOCAL
| VT_LVAL
;
1369 store(p
->r
& VT_VALMASK
, &sv
);
1370 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1371 /* x86 specific: need to pop fp register ST0 if saved */
1372 if (r
== TREG_ST0
) {
1373 o(0xd8dd); /* fstp %st(0) */
1376 /* special long long case */
1377 if (p
->r2
< VT_CONST
&& USING_TWO_WORDS(bt
)) {
1382 /* mark that stack entry as being saved on the stack */
1383 if (p
->r
& VT_LVAL
) {
1384 /* also clear the bounded flag because the
1385 relocation address of the function was stored in
1387 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
1389 p
->r
= VT_LVAL
| VT_LOCAL
;
1398 #ifdef TCC_TARGET_ARM
1399 /* find a register of class 'rc2' with at most one reference on stack.
1400 * If none, call get_reg(rc) */
1401 ST_FUNC
int get_reg_ex(int rc
, int rc2
)
1406 for(r
=0;r
<NB_REGS
;r
++) {
1407 if (reg_classes
[r
] & rc2
) {
1410 for(p
= vstack
; p
<= vtop
; p
++) {
1411 if ((p
->r
& VT_VALMASK
) == r
||
1423 /* find a free register of class 'rc'. If none, save one register */
1424 ST_FUNC
int get_reg(int rc
)
1429 /* find a free register */
1430 for(r
=0;r
<NB_REGS
;r
++) {
1431 if (reg_classes
[r
] & rc
) {
1434 for(p
=vstack
;p
<=vtop
;p
++) {
1435 if ((p
->r
& VT_VALMASK
) == r
||
1444 /* no register left : free the first one on the stack (VERY
1445 IMPORTANT to start from the bottom to ensure that we don't
1446 spill registers used in gen_opi()) */
1447 for(p
=vstack
;p
<=vtop
;p
++) {
1448 /* look at second register (if long long) */
1450 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
1452 r
= p
->r
& VT_VALMASK
;
1453 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
1459 /* Should never comes here */
1463 /* find a free temporary local variable (return the offset on stack) match the size and align. If none, add new temporary stack variable*/
1464 static int get_temp_local_var(int size
,int align
){
1466 struct temp_local_variable
*temp_var
;
1473 for(i
=0;i
<nb_temp_local_vars
;i
++){
1474 temp_var
=&arr_temp_local_vars
[i
];
1475 if(temp_var
->size
<size
||align
!=temp_var
->align
){
1478 /*check if temp_var is free*/
1480 for(p
=vstack
;p
<=vtop
;p
++) {
1482 if(r
==VT_LOCAL
||r
==VT_LLOCAL
){
1483 if(p
->c
.i
==temp_var
->location
){
1490 found_var
=temp_var
->location
;
1496 loc
= (loc
- size
) & -align
;
1497 if(nb_temp_local_vars
<MAX_TEMP_LOCAL_VARIABLE_NUMBER
){
1498 temp_var
=&arr_temp_local_vars
[i
];
1499 temp_var
->location
=loc
;
1500 temp_var
->size
=size
;
1501 temp_var
->align
=align
;
1502 nb_temp_local_vars
++;
1509 static void clear_temp_local_var_list(){
1510 nb_temp_local_vars
=0;
1513 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
1515 static void move_reg(int r
, int s
, int t
)
1529 /* get address of vtop (vtop MUST BE an lvalue) */
1530 ST_FUNC
void gaddrof(void)
1532 vtop
->r
&= ~VT_LVAL
;
1533 /* tricky: if saved lvalue, then we can go back to lvalue */
1534 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
1535 vtop
->r
= (vtop
->r
& ~VT_VALMASK
) | VT_LOCAL
| VT_LVAL
;
1538 #ifdef CONFIG_TCC_BCHECK
1539 /* generate a bounded pointer addition */
1540 static void gen_bounded_ptr_add(void)
1542 int save
= (vtop
[-1].r
& VT_VALMASK
) == VT_LOCAL
;
1547 vpush_helper_func(TOK___bound_ptr_add
);
1552 /* returned pointer is in REG_IRET */
1553 vtop
->r
= REG_IRET
| VT_BOUNDED
;
1556 /* relocation offset of the bounding function call point */
1557 vtop
->c
.i
= (cur_text_section
->reloc
->data_offset
- sizeof(ElfW_Rel
));
1560 /* patch pointer addition in vtop so that pointer dereferencing is
1562 static void gen_bounded_ptr_deref(void)
1572 size
= type_size(&vtop
->type
, &align
);
1574 case 1: func
= TOK___bound_ptr_indir1
; break;
1575 case 2: func
= TOK___bound_ptr_indir2
; break;
1576 case 4: func
= TOK___bound_ptr_indir4
; break;
1577 case 8: func
= TOK___bound_ptr_indir8
; break;
1578 case 12: func
= TOK___bound_ptr_indir12
; break;
1579 case 16: func
= TOK___bound_ptr_indir16
; break;
1581 /* may happen with struct member access */
1584 sym
= external_helper_sym(func
);
1586 put_extern_sym(sym
, NULL
, 0, 0);
1587 /* patch relocation */
1588 /* XXX: find a better solution ? */
1589 rel
= (ElfW_Rel
*)(cur_text_section
->reloc
->data
+ vtop
->c
.i
);
1590 rel
->r_info
= ELFW(R_INFO
)(sym
->c
, ELFW(R_TYPE
)(rel
->r_info
));
1593 /* generate lvalue bound code */
1594 static void gbound(void)
1598 vtop
->r
&= ~VT_MUSTBOUND
;
1599 /* if lvalue, then use checking code before dereferencing */
1600 if (vtop
->r
& VT_LVAL
) {
1601 /* if not VT_BOUNDED value, then make one */
1602 if (!(vtop
->r
& VT_BOUNDED
)) {
1603 /* must save type because we must set it to int to get pointer */
1605 vtop
->type
.t
= VT_PTR
;
1608 gen_bounded_ptr_add();
1612 /* then check for dereferencing */
1613 gen_bounded_ptr_deref();
1617 /* we need to call __bound_ptr_add before we start to load function
1618 args into registers */
1619 ST_FUNC
void gbound_args(int nb_args
)
1624 for (i
= 1; i
<= nb_args
; ++i
)
1625 if (vtop
[1 - i
].r
& VT_MUSTBOUND
) {
1631 sv
= vtop
- nb_args
;
1632 if (sv
->r
& VT_SYM
) {
1636 #ifndef TCC_TARGET_PE
1637 || v
== TOK_sigsetjmp
1638 || v
== TOK___sigsetjmp
1641 vpush_helper_func(TOK___bound_setjmp
);
1644 func_bound_add_epilog
= 1;
1646 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
1647 if (v
== TOK_alloca
)
1648 func_bound_add_epilog
= 1;
1651 if (v
== TOK_longjmp
) /* undo rename to __longjmp14 */
1652 sv
->sym
->asm_label
= TOK___bound_longjmp
;
1657 /* Add bounds for local symbols from S to E (via ->prev) */
1658 static void add_local_bounds(Sym
*s
, Sym
*e
)
1660 for (; s
!= e
; s
= s
->prev
) {
1661 if (!s
->v
|| (s
->r
& VT_VALMASK
) != VT_LOCAL
)
1663 /* Add arrays/structs/unions because we always take address */
1664 if ((s
->type
.t
& VT_ARRAY
)
1665 || (s
->type
.t
& VT_BTYPE
) == VT_STRUCT
1666 || s
->a
.addrtaken
) {
1667 /* add local bound info */
1668 int align
, size
= type_size(&s
->type
, &align
);
1669 addr_t
*bounds_ptr
= section_ptr_add(lbounds_section
,
1670 2 * sizeof(addr_t
));
1671 bounds_ptr
[0] = s
->c
;
1672 bounds_ptr
[1] = size
;
1678 /* Wrapper around sym_pop, that potentially also registers local bounds. */
1679 static void pop_local_syms(Sym
*b
, int keep
)
1681 #ifdef CONFIG_TCC_BCHECK
1682 if (tcc_state
->do_bounds_check
&& !keep
&& (local_scope
|| !func_var
))
1683 add_local_bounds(local_stack
, b
);
1686 tcc_add_debug_info (tcc_state
, !local_scope
, local_stack
, b
);
1687 sym_pop(&local_stack
, b
, keep
);
1690 /* increment an lvalue pointer */
1691 static void incr_offset(int offset
)
1693 int t
= vtop
->type
.t
;
1694 gaddrof(); /* remove VT_LVAL */
1695 vtop
->type
.t
= VT_PTRDIFF_T
; /* set scalar type */
1702 static void incr_bf_adr(int o
)
1704 vtop
->type
.t
= VT_BYTE
| VT_UNSIGNED
;
1708 /* single-byte load mode for packed or otherwise unaligned bitfields */
1709 static void load_packed_bf(CType
*type
, int bit_pos
, int bit_size
)
1712 save_reg_upstack(vtop
->r
, 1);
1713 vpush64(type
->t
& VT_BTYPE
, 0); // B X
1714 bits
= 0, o
= bit_pos
>> 3, bit_pos
&= 7;
1723 vpushi(bit_pos
), gen_op(TOK_SHR
), bit_pos
= 0; // X B Y
1725 vpushi((1 << n
) - 1), gen_op('&');
1728 vpushi(bits
), gen_op(TOK_SHL
);
1731 bits
+= n
, bit_size
-= n
, o
= 1;
1734 if (!(type
->t
& VT_UNSIGNED
)) {
1735 n
= ((type
->t
& VT_BTYPE
) == VT_LLONG
? 64 : 32) - bits
;
1736 vpushi(n
), gen_op(TOK_SHL
);
1737 vpushi(n
), gen_op(TOK_SAR
);
1741 /* single-byte store mode for packed or otherwise unaligned bitfields */
1742 static void store_packed_bf(int bit_pos
, int bit_size
)
1744 int bits
, n
, o
, m
, c
;
1745 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1747 save_reg_upstack(vtop
->r
, 1);
1748 bits
= 0, o
= bit_pos
>> 3, bit_pos
&= 7;
1750 incr_bf_adr(o
); // X B
1752 c
? vdup() : gv_dup(); // B V X
1755 vpushi(bits
), gen_op(TOK_SHR
);
1757 vpushi(bit_pos
), gen_op(TOK_SHL
);
1762 m
= ((1 << n
) - 1) << bit_pos
;
1763 vpushi(m
), gen_op('&'); // X B V1
1764 vpushv(vtop
-1); // X B V1 B
1765 vpushi(m
& 0x80 ? ~m
& 0x7f : ~m
);
1766 gen_op('&'); // X B V1 B1
1767 gen_op('|'); // X B V2
1769 vdup(), vtop
[-1] = vtop
[-2]; // X B B V2
1770 vstore(), vpop(); // X B
1771 bits
+= n
, bit_size
-= n
, bit_pos
= 0, o
= 1;
1776 static int adjust_bf(SValue
*sv
, int bit_pos
, int bit_size
)
1779 if (0 == sv
->type
.ref
)
1781 t
= sv
->type
.ref
->auxtype
;
1782 if (t
!= -1 && t
!= VT_STRUCT
) {
1783 sv
->type
.t
= (sv
->type
.t
& ~(VT_BTYPE
| VT_LONG
)) | t
;
1789 /* store vtop a register belonging to class 'rc'. lvalues are
1790 converted to values. Cannot be used if cannot be converted to
1791 register value (such as structures). */
1792 ST_FUNC
int gv(int rc
)
1794 int r
, r2
, r_ok
, r2_ok
, rc2
, bt
;
1795 int bit_pos
, bit_size
, size
, align
;
1797 /* NOTE: get_reg can modify vstack[] */
1798 if (vtop
->type
.t
& VT_BITFIELD
) {
1801 bit_pos
= BIT_POS(vtop
->type
.t
);
1802 bit_size
= BIT_SIZE(vtop
->type
.t
);
1803 /* remove bit field info to avoid loops */
1804 vtop
->type
.t
&= ~VT_STRUCT_MASK
;
1807 type
.t
= vtop
->type
.t
& VT_UNSIGNED
;
1808 if ((vtop
->type
.t
& VT_BTYPE
) == VT_BOOL
)
1809 type
.t
|= VT_UNSIGNED
;
1811 r
= adjust_bf(vtop
, bit_pos
, bit_size
);
1813 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
)
1818 if (r
== VT_STRUCT
) {
1819 load_packed_bf(&type
, bit_pos
, bit_size
);
1821 int bits
= (type
.t
& VT_BTYPE
) == VT_LLONG
? 64 : 32;
1822 /* cast to int to propagate signedness in following ops */
1824 /* generate shifts */
1825 vpushi(bits
- (bit_pos
+ bit_size
));
1827 vpushi(bits
- bit_size
);
1828 /* NOTE: transformed to SHR if unsigned */
1833 if (is_float(vtop
->type
.t
) &&
1834 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
1835 /* CPUs usually cannot use float constants, so we store them
1836 generically in data segment */
1837 init_params p
= { rodata_section
};
1838 unsigned long offset
;
1839 size
= type_size(&vtop
->type
, &align
);
1841 size
= 0, align
= 1;
1842 offset
= section_add(p
.sec
, size
, align
);
1843 vpush_ref(&vtop
->type
, p
.sec
, offset
, size
);
1845 init_putv(&p
, &vtop
->type
, offset
);
1848 #ifdef CONFIG_TCC_BCHECK
1849 if (vtop
->r
& VT_MUSTBOUND
)
1853 bt
= vtop
->type
.t
& VT_BTYPE
;
1855 #ifdef TCC_TARGET_RISCV64
1857 if (bt
== VT_LDOUBLE
&& rc
== RC_FLOAT
)
1860 rc2
= RC2_TYPE(bt
, rc
);
1862 /* need to reload if:
1864 - lvalue (need to dereference pointer)
1865 - already a register, but not in the right class */
1866 r
= vtop
->r
& VT_VALMASK
;
1867 r_ok
= !(vtop
->r
& VT_LVAL
) && (r
< VT_CONST
) && (reg_classes
[r
] & rc
);
1868 r2_ok
= !rc2
|| ((vtop
->r2
< VT_CONST
) && (reg_classes
[vtop
->r2
] & rc2
));
1870 if (!r_ok
|| !r2_ok
) {
1873 if (1 /* we can 'mov (r),r' in cases */
1875 && (reg_classes
[r
] & rc
)
1878 save_reg_upstack(r
, 1);
1884 int load_type
= (bt
== VT_QFLOAT
) ? VT_DOUBLE
: VT_PTRDIFF_T
;
1885 int original_type
= vtop
->type
.t
;
1887 /* two register type load :
1888 expand to two words temporarily */
1889 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
1891 unsigned long long ll
= vtop
->c
.i
;
1892 vtop
->c
.i
= ll
; /* first word */
1894 vtop
->r
= r
; /* save register value */
1895 vpushi(ll
>> 32); /* second word */
1896 } else if (vtop
->r
& VT_LVAL
) {
1897 /* We do not want to modifier the long long pointer here.
1898 So we save any other instances down the stack */
1899 save_reg_upstack(vtop
->r
, 1);
1900 /* load from memory */
1901 vtop
->type
.t
= load_type
;
1904 vtop
[-1].r
= r
; /* save register value */
1905 /* increment pointer to get second word */
1906 incr_offset(PTR_SIZE
);
1908 /* move registers */
1911 if (r2_ok
&& vtop
->r2
< VT_CONST
)
1914 vtop
[-1].r
= r
; /* save register value */
1915 vtop
->r
= vtop
[-1].r2
;
1917 /* Allocate second register. Here we rely on the fact that
1918 get_reg() tries first to free r2 of an SValue. */
1922 /* write second register */
1925 vtop
->type
.t
= original_type
;
1927 if (vtop
->r
== VT_CMP
)
1929 /* one register type load */
1934 #ifdef TCC_TARGET_C67
1935 /* uses register pairs for doubles */
1936 if (bt
== VT_DOUBLE
)
1943 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
1944 ST_FUNC
void gv2(int rc1
, int rc2
)
1946 /* generate more generic register first. But VT_JMP or VT_CMP
1947 values must be generated first in all cases to avoid possible
1949 if (vtop
->r
!= VT_CMP
&& rc1
<= rc2
) {
1954 /* test if reload is needed for first register */
1955 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
1965 /* test if reload is needed for first register */
1966 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
1973 /* expand 64bit on stack in two ints */
1974 ST_FUNC
void lexpand(void)
1977 u
= vtop
->type
.t
& (VT_DEFSIGN
| VT_UNSIGNED
);
1978 v
= vtop
->r
& (VT_VALMASK
| VT_LVAL
);
1979 if (v
== VT_CONST
) {
1982 } else if (v
== (VT_LVAL
|VT_CONST
) || v
== (VT_LVAL
|VT_LOCAL
)) {
1988 vtop
[0].r
= vtop
[-1].r2
;
1989 vtop
[0].r2
= vtop
[-1].r2
= VT_CONST
;
1991 vtop
[0].type
.t
= vtop
[-1].type
.t
= VT_INT
| u
;
1996 /* build a long long from two ints */
1997 static void lbuild(int t
)
1999 gv2(RC_INT
, RC_INT
);
2000 vtop
[-1].r2
= vtop
[0].r
;
2001 vtop
[-1].type
.t
= t
;
2006 /* convert stack entry to register and duplicate its value in another
2008 static void gv_dup(void)
2014 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2015 if (t
& VT_BITFIELD
) {
2025 /* stack: H L L1 H1 */
2035 /* duplicate value */
2045 /* generate CPU independent (unsigned) long long operations */
2046 static void gen_opl(int op
)
2048 int t
, a
, b
, op1
, c
, i
;
2050 unsigned short reg_iret
= REG_IRET
;
2051 unsigned short reg_lret
= REG_IRE2
;
2057 func
= TOK___divdi3
;
2060 func
= TOK___udivdi3
;
2063 func
= TOK___moddi3
;
2066 func
= TOK___umoddi3
;
2073 /* call generic long long function */
2074 vpush_helper_func(func
);
2079 vtop
->r2
= reg_lret
;
2087 //pv("gen_opl A",0,2);
2093 /* stack: L1 H1 L2 H2 */
2098 vtop
[-2] = vtop
[-3];
2101 /* stack: H1 H2 L1 L2 */
2102 //pv("gen_opl B",0,4);
2108 /* stack: H1 H2 L1 L2 ML MH */
2111 /* stack: ML MH H1 H2 L1 L2 */
2115 /* stack: ML MH H1 L2 H2 L1 */
2120 /* stack: ML MH M1 M2 */
2123 } else if (op
== '+' || op
== '-') {
2124 /* XXX: add non carry method too (for MIPS or alpha) */
2130 /* stack: H1 H2 (L1 op L2) */
2133 gen_op(op1
+ 1); /* TOK_xxxC2 */
2136 /* stack: H1 H2 (L1 op L2) */
2139 /* stack: (L1 op L2) H1 H2 */
2141 /* stack: (L1 op L2) (H1 op H2) */
2149 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
2150 t
= vtop
[-1].type
.t
;
2154 /* stack: L H shift */
2156 /* constant: simpler */
2157 /* NOTE: all comments are for SHL. the other cases are
2158 done by swapping words */
2169 if (op
!= TOK_SAR
) {
2202 /* XXX: should provide a faster fallback on x86 ? */
2205 func
= TOK___ashrdi3
;
2208 func
= TOK___lshrdi3
;
2211 func
= TOK___ashldi3
;
2217 /* compare operations */
2223 /* stack: L1 H1 L2 H2 */
2225 vtop
[-1] = vtop
[-2];
2227 /* stack: L1 L2 H1 H2 */
2231 /* when values are equal, we need to compare low words. since
2232 the jump is inverted, we invert the test too. */
2235 else if (op1
== TOK_GT
)
2237 else if (op1
== TOK_ULT
)
2239 else if (op1
== TOK_UGT
)
2249 /* generate non equal test */
2251 vset_VT_CMP(TOK_NE
);
2255 /* compare low. Always unsigned */
2259 else if (op1
== TOK_LE
)
2261 else if (op1
== TOK_GT
)
2263 else if (op1
== TOK_GE
)
2266 #if 0//def TCC_TARGET_I386
2267 if (op
== TOK_NE
) { gsym(b
); break; }
2268 if (op
== TOK_EQ
) { gsym(a
); break; }
2277 static uint64_t gen_opic_sdiv(uint64_t a
, uint64_t b
)
2279 uint64_t x
= (a
>> 63 ? -a
: a
) / (b
>> 63 ? -b
: b
);
2280 return (a
^ b
) >> 63 ? -x
: x
;
2283 static int gen_opic_lt(uint64_t a
, uint64_t b
)
2285 return (a
^ (uint64_t)1 << 63) < (b
^ (uint64_t)1 << 63);
2288 /* handle integer constant optimizations and various machine
2290 static void gen_opic(int op
)
2292 SValue
*v1
= vtop
- 1;
2294 int t1
= v1
->type
.t
& VT_BTYPE
;
2295 int t2
= v2
->type
.t
& VT_BTYPE
;
2296 int c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2297 int c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2298 uint64_t l1
= c1
? v1
->c
.i
: 0;
2299 uint64_t l2
= c2
? v2
->c
.i
: 0;
2300 int shm
= (t1
== VT_LLONG
) ? 63 : 31;
2303 if (t1
!= VT_LLONG
&& (PTR_SIZE
!= 8 || t1
!= VT_PTR
))
2304 l1
= ((uint32_t)l1
|
2305 (v1
->type
.t
& VT_UNSIGNED
? 0 : -(l1
& 0x80000000)));
2306 if (t2
!= VT_LLONG
&& (PTR_SIZE
!= 8 || t2
!= VT_PTR
))
2307 l2
= ((uint32_t)l2
|
2308 (v2
->type
.t
& VT_UNSIGNED
? 0 : -(l2
& 0x80000000)));
2312 case '+': l1
+= l2
; break;
2313 case '-': l1
-= l2
; break;
2314 case '&': l1
&= l2
; break;
2315 case '^': l1
^= l2
; break;
2316 case '|': l1
|= l2
; break;
2317 case '*': l1
*= l2
; break;
2324 /* if division by zero, generate explicit division */
2326 if (CONST_WANTED
&& !NOEVAL_WANTED
)
2327 tcc_error("division by zero in constant");
2331 default: l1
= gen_opic_sdiv(l1
, l2
); break;
2332 case '%': l1
= l1
- l2
* gen_opic_sdiv(l1
, l2
); break;
2333 case TOK_UDIV
: l1
= l1
/ l2
; break;
2334 case TOK_UMOD
: l1
= l1
% l2
; break;
2337 case TOK_SHL
: l1
<<= (l2
& shm
); break;
2338 case TOK_SHR
: l1
>>= (l2
& shm
); break;
2340 l1
= (l1
>> 63) ? ~(~l1
>> (l2
& shm
)) : l1
>> (l2
& shm
);
2343 case TOK_ULT
: l1
= l1
< l2
; break;
2344 case TOK_UGE
: l1
= l1
>= l2
; break;
2345 case TOK_EQ
: l1
= l1
== l2
; break;
2346 case TOK_NE
: l1
= l1
!= l2
; break;
2347 case TOK_ULE
: l1
= l1
<= l2
; break;
2348 case TOK_UGT
: l1
= l1
> l2
; break;
2349 case TOK_LT
: l1
= gen_opic_lt(l1
, l2
); break;
2350 case TOK_GE
: l1
= !gen_opic_lt(l1
, l2
); break;
2351 case TOK_LE
: l1
= !gen_opic_lt(l2
, l1
); break;
2352 case TOK_GT
: l1
= gen_opic_lt(l2
, l1
); break;
2354 case TOK_LAND
: l1
= l1
&& l2
; break;
2355 case TOK_LOR
: l1
= l1
|| l2
; break;
2359 if (t1
!= VT_LLONG
&& (PTR_SIZE
!= 8 || t1
!= VT_PTR
))
2360 l1
= ((uint32_t)l1
|
2361 (v1
->type
.t
& VT_UNSIGNED
? 0 : -(l1
& 0x80000000)));
2363 v1
->r
|= v2
->r
& VT_NONCONST
;
2366 /* if commutative ops, put c2 as constant */
2367 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
2368 op
== '|' || op
== '*' || op
== TOK_EQ
|| op
== TOK_NE
)) {
2370 c2
= c1
; //c = c1, c1 = c2, c2 = c;
2371 l2
= l1
; //l = l1, l1 = l2, l2 = l;
2373 if (c1
&& ((l1
== 0 &&
2374 (op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
)) ||
2375 (l1
== -1 && op
== TOK_SAR
))) {
2376 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
2378 } else if (c2
&& ((l2
== 0 && (op
== '&' || op
== '*')) ||
2380 (l2
== -1 || (l2
== 0xFFFFFFFF && t2
!= VT_LLONG
))) ||
2381 (l2
== 1 && (op
== '%' || op
== TOK_UMOD
)))) {
2382 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
2387 } else if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
2390 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
2391 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
2394 (l2
== -1 || (l2
== 0xFFFFFFFF && t2
!= VT_LLONG
))))) {
2395 /* filter out NOP operations like x*1, x-0, x&-1... */
2397 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
2398 /* try to use shifts instead of muls or divs */
2399 if (l2
> 0 && (l2
& (l2
- 1)) == 0) {
2408 else if (op
== TOK_PDIV
)
2414 } else if (c2
&& (op
== '+' || op
== '-') &&
2415 (r
= vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
),
2416 r
== (VT_CONST
| VT_SYM
) || r
== VT_LOCAL
)) {
2417 /* symbol + constant case */
2421 /* The backends can't always deal with addends to symbols
2422 larger than +-1<<31. Don't construct such. */
2429 /* call low level op generator */
2430 if (t1
== VT_LLONG
|| t2
== VT_LLONG
||
2431 (PTR_SIZE
== 8 && (t1
== VT_PTR
|| t2
== VT_PTR
)))
2436 if (vtop
->r
== VT_CONST
)
2437 vtop
->r
|= VT_NONCONST
; /* is const, but only by optimization */
2441 #if defined TCC_TARGET_X86_64 || defined TCC_TARGET_I386
2442 # define gen_negf gen_opf
2443 #elif defined TCC_TARGET_ARM
2444 void gen_negf(int op
)
2446 /* arm will detect 0-x and replace by vneg */
2447 vpushi(0), vswap(), gen_op('-');
2450 /* XXX: implement in gen_opf() for other backends too */
2451 void gen_negf(int op
)
2453 /* In IEEE negate(x) isn't subtract(0,x). Without NaNs it's
2454 subtract(-0, x), but with them it's really a sign flip
2455 operation. We implement this with bit manipulation and have
2456 to do some type reinterpretation for this, which TCC can do
2459 int align
, size
, bt
;
2461 size
= type_size(&vtop
->type
, &align
);
2462 bt
= vtop
->type
.t
& VT_BTYPE
;
2463 save_reg(gv(RC_TYPE(bt
)));
2465 incr_bf_adr(size
- 1);
2467 vpushi(0x80); /* flip sign */
2474 /* generate a floating point operation with constant propagation */
2475 static void gen_opif(int op
)
2477 int c1
, c2
, cast_int
= 0;
2479 #if defined _MSC_VER && defined __x86_64__
2480 /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
2490 /* currently, we cannot do computations with forward symbols */
2491 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2492 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2494 if (v1
->type
.t
== VT_FLOAT
) {
2497 } else if (v1
->type
.t
== VT_DOUBLE
) {
2504 /* NOTE: we only do constant propagation if finite number (not
2505 NaN or infinity) (ANSI spec) */
2506 if (!(ieee_finite(f1
) || !ieee_finite(f2
)) && !CONST_WANTED
)
2509 case '+': f1
+= f2
; break;
2510 case '-': f1
-= f2
; break;
2511 case '*': f1
*= f2
; break;
2514 union { float f
; unsigned u
; } x1
, x2
, y
;
2515 /* If not in initializer we need to potentially generate
2516 FP exceptions at runtime, otherwise we want to fold. */
2519 /* the run-time result of 0.0/0.0 on x87, also of other compilers
2520 when used to compile the f1 /= f2 below, would be -nan */
2521 x1
.f
= f1
, x2
.f
= f2
;
2523 y
.u
= 0x7fc00000; /* nan */
2525 y
.u
= 0x7f800000; /* infinity */
2526 y
.u
|= (x1
.u
^ x2
.u
) & 0x80000000; /* set sign */
2555 /* XXX: also handles tests ? */
2561 /* XXX: overflow test ? */
2562 if (v1
->type
.t
== VT_FLOAT
) {
2564 } else if (v1
->type
.t
== VT_DOUBLE
) {
2573 if (op
== TOK_NEG
) {
2581 /* print a type. If 'varstr' is not NULL, then the variable is also
2582 printed in the type */
2584 /* XXX: add array and function pointers */
2585 static void type_to_str(char *buf
, int buf_size
,
2586 CType
*type
, const char *varstr
)
2598 pstrcat(buf
, buf_size
, "extern ");
2600 pstrcat(buf
, buf_size
, "static ");
2602 pstrcat(buf
, buf_size
, "typedef ");
2604 pstrcat(buf
, buf_size
, "inline ");
2606 if (t
& VT_VOLATILE
)
2607 pstrcat(buf
, buf_size
, "volatile ");
2608 if (t
& VT_CONSTANT
)
2609 pstrcat(buf
, buf_size
, "const ");
2611 if (((t
& VT_DEFSIGN
) && bt
== VT_BYTE
)
2612 || ((t
& VT_UNSIGNED
)
2613 && (bt
== VT_SHORT
|| bt
== VT_INT
|| bt
== VT_LLONG
)
2616 pstrcat(buf
, buf_size
, (t
& VT_UNSIGNED
) ? "unsigned " : "signed ");
2618 buf_size
-= strlen(buf
);
2654 tstr
= "long double";
2656 pstrcat(buf
, buf_size
, tstr
);
2663 pstrcat(buf
, buf_size
, tstr
);
2664 v
= type
->ref
->v
& ~SYM_STRUCT
;
2665 if (v
>= SYM_FIRST_ANOM
)
2666 pstrcat(buf
, buf_size
, "<anonymous>");
2668 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
2673 if (varstr
&& '*' == *varstr
) {
2674 pstrcat(buf1
, sizeof(buf1
), "(");
2675 pstrcat(buf1
, sizeof(buf1
), varstr
);
2676 pstrcat(buf1
, sizeof(buf1
), ")");
2678 pstrcat(buf1
, buf_size
, "(");
2680 while (sa
!= NULL
) {
2682 type_to_str(buf2
, sizeof(buf2
), &sa
->type
, NULL
);
2683 pstrcat(buf1
, sizeof(buf1
), buf2
);
2686 pstrcat(buf1
, sizeof(buf1
), ", ");
2688 if (s
->f
.func_type
== FUNC_ELLIPSIS
)
2689 pstrcat(buf1
, sizeof(buf1
), ", ...");
2690 pstrcat(buf1
, sizeof(buf1
), ")");
2691 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
2695 if (t
& (VT_ARRAY
|VT_VLA
)) {
2696 if (varstr
&& '*' == *varstr
)
2697 snprintf(buf1
, sizeof(buf1
), "(%s)[%d]", varstr
, s
->c
);
2699 snprintf(buf1
, sizeof(buf1
), "%s[%d]", varstr
? varstr
: "", s
->c
);
2700 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
2703 pstrcpy(buf1
, sizeof(buf1
), "*");
2704 if (t
& VT_CONSTANT
)
2705 pstrcat(buf1
, buf_size
, "const ");
2706 if (t
& VT_VOLATILE
)
2707 pstrcat(buf1
, buf_size
, "volatile ");
2709 pstrcat(buf1
, sizeof(buf1
), varstr
);
2710 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
2714 pstrcat(buf
, buf_size
, " ");
2715 pstrcat(buf
, buf_size
, varstr
);
2720 static void type_incompatibility_error(CType
* st
, CType
* dt
, const char* fmt
)
2722 char buf1
[256], buf2
[256];
2723 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
2724 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
2725 tcc_error(fmt
, buf1
, buf2
);
2728 static void type_incompatibility_warning(CType
* st
, CType
* dt
, const char* fmt
)
2730 char buf1
[256], buf2
[256];
2731 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
2732 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
2733 tcc_warning(fmt
, buf1
, buf2
);
2736 static int pointed_size(CType
*type
)
2739 return type_size(pointed_type(type
), &align
);
2742 static inline int is_null_pointer(SValue
*p
)
2744 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
| VT_NONCONST
)) != VT_CONST
)
2746 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& (uint32_t)p
->c
.i
== 0) ||
2747 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.i
== 0) ||
2748 ((p
->type
.t
& VT_BTYPE
) == VT_PTR
&&
2749 (PTR_SIZE
== 4 ? (uint32_t)p
->c
.i
== 0 : p
->c
.i
== 0) &&
2750 ((pointed_type(&p
->type
)->t
& VT_BTYPE
) == VT_VOID
) &&
2751 0 == (pointed_type(&p
->type
)->t
& (VT_CONSTANT
| VT_VOLATILE
))
2755 /* compare function types. OLD functions match any new functions */
2756 static int is_compatible_func(CType
*type1
, CType
*type2
)
2762 if (s1
->f
.func_call
!= s2
->f
.func_call
)
2764 if (s1
->f
.func_type
!= s2
->f
.func_type
2765 && s1
->f
.func_type
!= FUNC_OLD
2766 && s2
->f
.func_type
!= FUNC_OLD
)
2769 if (!is_compatible_unqualified_types(&s1
->type
, &s2
->type
))
2771 if (s1
->f
.func_type
== FUNC_OLD
|| s2
->f
.func_type
== FUNC_OLD
)
2782 /* return true if type1 and type2 are the same. If unqualified is
2783 true, qualifiers on the types are ignored.
2785 static int compare_types(CType
*type1
, CType
*type2
, int unqualified
)
2789 t1
= type1
->t
& VT_TYPE
;
2790 t2
= type2
->t
& VT_TYPE
;
2792 /* strip qualifiers before comparing */
2793 t1
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2794 t2
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2797 /* Default Vs explicit signedness only matters for char */
2798 if ((t1
& VT_BTYPE
) != VT_BYTE
) {
2802 /* XXX: bitfields ? */
2807 && !(type1
->ref
->c
< 0
2808 || type2
->ref
->c
< 0
2809 || type1
->ref
->c
== type2
->ref
->c
))
2812 /* test more complicated cases */
2813 bt1
= t1
& VT_BTYPE
;
2814 if (bt1
== VT_PTR
) {
2815 type1
= pointed_type(type1
);
2816 type2
= pointed_type(type2
);
2817 return is_compatible_types(type1
, type2
);
2818 } else if (bt1
== VT_STRUCT
) {
2819 return (type1
->ref
== type2
->ref
);
2820 } else if (bt1
== VT_FUNC
) {
2821 return is_compatible_func(type1
, type2
);
2822 } else if (IS_ENUM(type1
->t
) && IS_ENUM(type2
->t
)) {
2823 /* If both are enums then they must be the same, if only one is then
2824 t1 and t2 must be equal, which was checked above already. */
2825 return type1
->ref
== type2
->ref
;
2831 /* Check if OP1 and OP2 can be "combined" with operation OP, the combined
2832 type is stored in DEST if non-null (except for pointer plus/minus) . */
2833 static int combine_types(CType
*dest
, SValue
*op1
, SValue
*op2
, int op
)
2835 CType
*type1
= &op1
->type
, *type2
= &op2
->type
, type
;
2836 int t1
= type1
->t
, t2
= type2
->t
, bt1
= t1
& VT_BTYPE
, bt2
= t2
& VT_BTYPE
;
2842 if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
2843 ret
= op
== '?' ? 1 : 0;
2844 /* NOTE: as an extension, we accept void on only one side */
2846 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
2847 if (op
== '+') ; /* Handled in caller */
2848 /* http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6 */
2849 /* If one is a null ptr constant the result type is the other. */
2850 else if (is_null_pointer (op2
)) type
= *type1
;
2851 else if (is_null_pointer (op1
)) type
= *type2
;
2852 else if (bt1
!= bt2
) {
2853 /* accept comparison or cond-expr between pointer and integer
2855 if ((op
== '?' || TOK_ISCOND(op
))
2856 && (is_integer_btype(bt1
) || is_integer_btype(bt2
)))
2857 tcc_warning("pointer/integer mismatch in %s",
2858 op
== '?' ? "conditional expression" : "comparison");
2859 else if (op
!= '-' || !is_integer_btype(bt2
))
2861 type
= *(bt1
== VT_PTR
? type1
: type2
);
2863 CType
*pt1
= pointed_type(type1
);
2864 CType
*pt2
= pointed_type(type2
);
2865 int pbt1
= pt1
->t
& VT_BTYPE
;
2866 int pbt2
= pt2
->t
& VT_BTYPE
;
2867 int newquals
, copied
= 0;
2868 if (pbt1
!= VT_VOID
&& pbt2
!= VT_VOID
2869 && !compare_types(pt1
, pt2
, 1/*unqualif*/)) {
2870 if (op
!= '?' && !TOK_ISCOND(op
))
2873 type_incompatibility_warning(type1
, type2
,
2875 ? "pointer type mismatch in conditional expression ('%s' and '%s')"
2876 : "pointer type mismatch in comparison('%s' and '%s')");
2879 /* pointers to void get preferred, otherwise the
2880 pointed to types minus qualifs should be compatible */
2881 type
= *((pbt1
== VT_VOID
) ? type1
: type2
);
2882 /* combine qualifs */
2883 newquals
= ((pt1
->t
| pt2
->t
) & (VT_CONSTANT
| VT_VOLATILE
));
2884 if ((~pointed_type(&type
)->t
& (VT_CONSTANT
| VT_VOLATILE
))
2887 /* copy the pointer target symbol */
2888 type
.ref
= sym_push(SYM_FIELD
, &type
.ref
->type
,
2891 pointed_type(&type
)->t
|= newquals
;
2893 /* pointers to incomplete arrays get converted to
2894 pointers to completed ones if possible */
2895 if (pt1
->t
& VT_ARRAY
2896 && pt2
->t
& VT_ARRAY
2897 && pointed_type(&type
)->ref
->c
< 0
2898 && (pt1
->ref
->c
> 0 || pt2
->ref
->c
> 0))
2901 type
.ref
= sym_push(SYM_FIELD
, &type
.ref
->type
,
2903 pointed_type(&type
)->ref
=
2904 sym_push(SYM_FIELD
, &pointed_type(&type
)->ref
->type
,
2905 0, pointed_type(&type
)->ref
->c
);
2906 pointed_type(&type
)->ref
->c
=
2907 0 < pt1
->ref
->c
? pt1
->ref
->c
: pt2
->ref
->c
;
2913 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
2914 if (op
!= '?' || !compare_types(type1
, type2
, 1))
2917 } else if (is_float(bt1
) || is_float(bt2
)) {
2918 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
2919 type
.t
= VT_LDOUBLE
;
2920 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
2925 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
2926 /* cast to biggest op */
2927 type
.t
= VT_LLONG
| VT_LONG
;
2928 if (bt1
== VT_LLONG
)
2930 if (bt2
== VT_LLONG
)
2932 /* convert to unsigned if it does not fit in a long long */
2933 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_LLONG
| VT_UNSIGNED
) ||
2934 (t2
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_LLONG
| VT_UNSIGNED
))
2935 type
.t
|= VT_UNSIGNED
;
2937 /* integer operations */
2938 type
.t
= VT_INT
| (VT_LONG
& (t1
| t2
));
2939 /* convert to unsigned if it does not fit in an integer */
2940 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_INT
| VT_UNSIGNED
) ||
2941 (t2
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_INT
| VT_UNSIGNED
))
2942 type
.t
|= VT_UNSIGNED
;
2949 /* generic gen_op: handles types problems */
2950 ST_FUNC
void gen_op(int op
)
2952 int t1
, t2
, bt1
, bt2
, t
;
2953 CType type1
, combtype
;
2956 t1
= vtop
[-1].type
.t
;
2957 t2
= vtop
[0].type
.t
;
2958 bt1
= t1
& VT_BTYPE
;
2959 bt2
= t2
& VT_BTYPE
;
2961 if (bt1
== VT_FUNC
|| bt2
== VT_FUNC
) {
2962 if (bt2
== VT_FUNC
) {
2963 mk_pointer(&vtop
->type
);
2966 if (bt1
== VT_FUNC
) {
2968 mk_pointer(&vtop
->type
);
2973 } else if (!combine_types(&combtype
, vtop
- 1, vtop
, op
)) {
2974 tcc_error("invalid operand types for binary operation");
2975 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
2976 /* at least one operand is a pointer */
2977 /* relational op: must be both pointers */
2981 /* if both pointers, then it must be the '-' op */
2982 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
2984 tcc_error("cannot use pointers here");
2985 vpush_type_size(pointed_type(&vtop
[-1].type
), &align
);
2988 vtop
->type
.t
= VT_PTRDIFF_T
;
2992 /* exactly one pointer : must be '+' or '-'. */
2993 if (op
!= '-' && op
!= '+')
2994 tcc_error("cannot use pointers here");
2995 /* Put pointer as first operand */
2996 if (bt2
== VT_PTR
) {
2998 t
= t1
, t1
= t2
, t2
= t
;
3001 if ((vtop
[0].type
.t
& VT_BTYPE
) == VT_LLONG
)
3002 /* XXX: truncate here because gen_opl can't handle ptr + long long */
3005 type1
= vtop
[-1].type
;
3006 vpush_type_size(pointed_type(&vtop
[-1].type
), &align
);
3008 #ifdef CONFIG_TCC_BCHECK
3009 if (tcc_state
->do_bounds_check
&& !CONST_WANTED
) {
3010 /* if bounded pointers, we generate a special code to
3017 gen_bounded_ptr_add();
3023 type1
.t
&= ~(VT_ARRAY
|VT_VLA
);
3024 /* put again type if gen_opic() swaped operands */
3028 /* floats can only be used for a few operations */
3029 if (is_float(combtype
.t
)
3030 && op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/'
3032 tcc_error("invalid operands for binary operation");
3033 else if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
) {
3034 t
= bt1
== VT_LLONG
? VT_LLONG
: VT_INT
;
3035 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (t
| VT_UNSIGNED
))
3037 t
|= (VT_LONG
& t1
);
3041 t
= t2
= combtype
.t
;
3042 /* XXX: currently, some unsigned operations are explicit, so
3043 we modify them here */
3044 if (t
& VT_UNSIGNED
) {
3051 else if (op
== TOK_LT
)
3053 else if (op
== TOK_GT
)
3055 else if (op
== TOK_LE
)
3057 else if (op
== TOK_GE
)
3063 /* special case for shifts and long long: we keep the shift as
3065 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3072 if (TOK_ISCOND(op
)) {
3073 /* relational op: the result is an int */
3074 vtop
->type
.t
= VT_INT
;
3079 // Make sure that we have converted to an rvalue:
3080 if (vtop
->r
& VT_LVAL
)
3081 gv(is_float(vtop
->type
.t
& VT_BTYPE
) ? RC_FLOAT
: RC_INT
);
3084 #if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 || defined TCC_TARGET_ARM
3085 #define gen_cvt_itof1 gen_cvt_itof
3087 /* generic itof for unsigned long long case */
3088 static void gen_cvt_itof1(int t
)
3090 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3091 (VT_LLONG
| VT_UNSIGNED
)) {
3094 vpush_helper_func(TOK___floatundisf
);
3095 #if LDOUBLE_SIZE != 8
3096 else if (t
== VT_LDOUBLE
)
3097 vpush_helper_func(TOK___floatundixf
);
3100 vpush_helper_func(TOK___floatundidf
);
3111 #if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
3112 #define gen_cvt_ftoi1 gen_cvt_ftoi
3114 /* generic ftoi for unsigned long long case */
3115 static void gen_cvt_ftoi1(int t
)
3118 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3119 /* not handled natively */
3120 st
= vtop
->type
.t
& VT_BTYPE
;
3122 vpush_helper_func(TOK___fixunssfdi
);
3123 #if LDOUBLE_SIZE != 8
3124 else if (st
== VT_LDOUBLE
)
3125 vpush_helper_func(TOK___fixunsxfdi
);
3128 vpush_helper_func(TOK___fixunsdfdi
);
3139 /* special delayed cast for char/short */
3140 static void force_charshort_cast(void)
3142 int sbt
= BFGET(vtop
->r
, VT_MUSTCAST
) == 2 ? VT_LLONG
: VT_INT
;
3143 int dbt
= vtop
->type
.t
;
3144 vtop
->r
&= ~VT_MUSTCAST
;
3146 gen_cast_s(dbt
== VT_BOOL
? VT_BYTE
|VT_UNSIGNED
: dbt
);
3150 static void gen_cast_s(int t
)
3158 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
3159 static void gen_cast(CType
*type
)
3161 int sbt
, dbt
, sf
, df
, c
;
3162 int dbt_bt
, sbt_bt
, ds
, ss
, bits
, trunc
;
3164 /* special delayed cast for char/short */
3165 if (vtop
->r
& VT_MUSTCAST
)
3166 force_charshort_cast();
3168 /* bitfields first get cast to ints */
3169 if (vtop
->type
.t
& VT_BITFIELD
)
3172 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3173 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
3181 dbt_bt
= dbt
& VT_BTYPE
;
3182 sbt_bt
= sbt
& VT_BTYPE
;
3183 if (dbt_bt
== VT_VOID
)
3185 if (sbt_bt
== VT_VOID
) {
3187 cast_error(&vtop
->type
, type
);
3190 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3191 #if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
3192 /* don't try to convert to ldouble when cross-compiling
3193 (except when it's '0' which is needed for arm:gen_negf()) */
3194 if (dbt_bt
== VT_LDOUBLE
&& !nocode_wanted
&& (sf
|| vtop
->c
.i
!= 0))
3198 /* constant case: we can do it now */
3199 /* XXX: in ISOC, cannot do it if error in convert */
3200 if (sbt
== VT_FLOAT
)
3201 vtop
->c
.ld
= vtop
->c
.f
;
3202 else if (sbt
== VT_DOUBLE
)
3203 vtop
->c
.ld
= vtop
->c
.d
;
3206 if (sbt_bt
== VT_LLONG
) {
3207 if ((sbt
& VT_UNSIGNED
) || !(vtop
->c
.i
>> 63))
3208 vtop
->c
.ld
= vtop
->c
.i
;
3210 vtop
->c
.ld
= -(long double)-vtop
->c
.i
;
3212 if ((sbt
& VT_UNSIGNED
) || !(vtop
->c
.i
>> 31))
3213 vtop
->c
.ld
= (uint32_t)vtop
->c
.i
;
3215 vtop
->c
.ld
= -(long double)-(uint32_t)vtop
->c
.i
;
3218 if (dbt
== VT_FLOAT
)
3219 vtop
->c
.f
= (float)vtop
->c
.ld
;
3220 else if (dbt
== VT_DOUBLE
)
3221 vtop
->c
.d
= (double)vtop
->c
.ld
;
3222 } else if (sf
&& dbt
== VT_BOOL
) {
3223 vtop
->c
.i
= (vtop
->c
.ld
!= 0);
3226 vtop
->c
.i
= vtop
->c
.ld
;
3227 else if (sbt_bt
== VT_LLONG
|| (PTR_SIZE
== 8 && sbt
== VT_PTR
))
3229 else if (sbt
& VT_UNSIGNED
)
3230 vtop
->c
.i
= (uint32_t)vtop
->c
.i
;
3232 vtop
->c
.i
= ((uint32_t)vtop
->c
.i
| -(vtop
->c
.i
& 0x80000000));
3234 if (dbt_bt
== VT_LLONG
|| (PTR_SIZE
== 8 && dbt
== VT_PTR
))
3236 else if (dbt
== VT_BOOL
)
3237 vtop
->c
.i
= (vtop
->c
.i
!= 0);
3239 uint32_t m
= dbt_bt
== VT_BYTE
? 0xff :
3240 dbt_bt
== VT_SHORT
? 0xffff :
3243 if (!(dbt
& VT_UNSIGNED
))
3244 vtop
->c
.i
|= -(vtop
->c
.i
& ((m
>> 1) + 1));
3249 } else if (dbt
== VT_BOOL
3250 && (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
))
3251 == (VT_CONST
| VT_SYM
)) {
3252 /* addresses are considered non-zero (see tcctest.c:sinit23) */
3258 /* cannot generate code for global or static initializers */
3259 if (nocode_wanted
& DATA_ONLY_WANTED
)
3262 /* non constant case: generate code */
3263 if (dbt
== VT_BOOL
) {
3264 gen_test_zero(TOK_NE
);
3270 /* convert from fp to fp */
3273 /* convert int to fp */
3276 /* convert fp to int */
3278 if (dbt_bt
!= VT_LLONG
&& dbt_bt
!= VT_INT
)
3281 goto again
; /* may need char/short cast */
3286 ds
= btype_size(dbt_bt
);
3287 ss
= btype_size(sbt_bt
);
3288 if (ds
== 0 || ss
== 0)
3291 if (IS_ENUM(type
->t
) && type
->ref
->c
< 0)
3292 tcc_error("cast to incomplete type");
3294 /* same size and no sign conversion needed */
3295 if (ds
== ss
&& ds
>= 4)
3297 if (dbt_bt
== VT_PTR
|| sbt_bt
== VT_PTR
) {
3298 tcc_warning("cast between pointer and integer of different size");
3299 if (sbt_bt
== VT_PTR
) {
3300 /* put integer type to allow logical operations below */
3301 vtop
->type
.t
= (PTR_SIZE
== 8 ? VT_LLONG
: VT_INT
);
3305 /* processor allows { int a = 0, b = *(char*)&a; }
3306 That means that if we cast to less width, we can just
3307 change the type and read it still later. */
3308 #define ALLOW_SUBTYPE_ACCESS 1
3310 if (ALLOW_SUBTYPE_ACCESS
&& (vtop
->r
& VT_LVAL
)) {
3311 /* value still in memory */
3315 if (ds
<= 4 && !(dbt
== (VT_SHORT
| VT_UNSIGNED
) && sbt
== VT_BYTE
)) {
3317 goto done
; /* no 64bit envolved */
3325 /* generate high word */
3326 if (sbt
& VT_UNSIGNED
) {
3335 } else if (ss
== 8) {
3336 /* from long long: just take low order word */
3344 /* need to convert from 32bit to 64bit */
3345 if (sbt
& VT_UNSIGNED
) {
3346 #if defined(TCC_TARGET_RISCV64)
3347 /* RISC-V keeps 32bit vals in registers sign-extended.
3348 So here we need a zero-extension. */
3357 ss
= ds
, ds
= 4, dbt
= sbt
;
3358 } else if (ss
== 8) {
3359 /* RISC-V keeps 32bit vals in registers sign-extended.
3360 So here we need a sign-extension for signed types and
3361 zero-extension. for unsigned types. */
3362 #if !defined(TCC_TARGET_RISCV64)
3363 trunc
= 32; /* zero upper 32 bits for non RISC-V targets */
3372 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM64
3378 bits
= (ss
- ds
) * 8;
3379 /* for unsigned, gen_op will convert SAR to SHR */
3380 vtop
->type
.t
= (ss
== 8 ? VT_LLONG
: VT_INT
) | (dbt
& VT_UNSIGNED
);
3383 vpushi(bits
- trunc
);
3390 vtop
->type
.t
&= ~ ( VT_CONSTANT
| VT_VOLATILE
| VT_ARRAY
);
3393 /* return type size as known at compile time. Put alignment at 'a' */
3394 ST_FUNC
int type_size(CType
*type
, int *a
)
3399 bt
= type
->t
& VT_BTYPE
;
3400 if (bt
== VT_STRUCT
) {
3405 } else if (bt
== VT_PTR
) {
3406 if (type
->t
& VT_ARRAY
) {
3410 ts
= type_size(&s
->type
, a
);
3412 if (ts
< 0 && s
->c
< 0)
3420 } else if (IS_ENUM(type
->t
) && type
->ref
->c
< 0) {
3422 return -1; /* incomplete enum */
3423 } else if (bt
== VT_LDOUBLE
) {
3425 return LDOUBLE_SIZE
;
3426 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3427 #ifdef TCC_TARGET_I386
3428 #ifdef TCC_TARGET_PE
3433 #elif defined(TCC_TARGET_ARM)
3443 } else if (bt
== VT_INT
|| bt
== VT_FLOAT
) {
3446 } else if (bt
== VT_SHORT
) {
3449 } else if (bt
== VT_QLONG
|| bt
== VT_QFLOAT
) {
3453 /* char, void, function, _Bool */
3459 /* push type size as known at runtime time on top of value stack. Put
3461 static void vpush_type_size(CType
*type
, int *a
)
3463 if (type
->t
& VT_VLA
) {
3464 type_size(&type
->ref
->type
, a
);
3465 vset(&int_type
, VT_LOCAL
|VT_LVAL
, type
->ref
->c
);
3467 int size
= type_size(type
, a
);
3469 tcc_error("unknown type size");
3478 /* return the pointed type of t */
3479 static inline CType
*pointed_type(CType
*type
)
3481 return &type
->ref
->type
;
3484 /* modify type so that its it is a pointer to type. */
3485 ST_FUNC
void mk_pointer(CType
*type
)
3488 s
= sym_push(SYM_FIELD
, type
, 0, -1);
3489 type
->t
= VT_PTR
| (type
->t
& VT_STORAGE
);
3493 /* return true if type1 and type2 are exactly the same (including
3496 static int is_compatible_types(CType
*type1
, CType
*type2
)
3498 return compare_types(type1
,type2
,0);
3501 /* return true if type1 and type2 are the same (ignoring qualifiers).
3503 static int is_compatible_unqualified_types(CType
*type1
, CType
*type2
)
3505 return compare_types(type1
,type2
,1);
3508 static void cast_error(CType
*st
, CType
*dt
)
3510 type_incompatibility_error(st
, dt
, "cannot convert '%s' to '%s'");
3513 /* verify type compatibility to store vtop in 'dt' type */
3514 static void verify_assign_cast(CType
*dt
)
3516 CType
*st
, *type1
, *type2
;
3517 int dbt
, sbt
, qualwarn
, lvl
;
3519 st
= &vtop
->type
; /* source type */
3520 dbt
= dt
->t
& VT_BTYPE
;
3521 sbt
= st
->t
& VT_BTYPE
;
3522 if (dt
->t
& VT_CONSTANT
)
3523 tcc_warning("assignment of read-only location");
3527 tcc_error("assignment to void expression");
3530 /* special cases for pointers */
3531 /* '0' can also be a pointer */
3532 if (is_null_pointer(vtop
))
3534 /* accept implicit pointer to integer cast with warning */
3535 if (is_integer_btype(sbt
)) {
3536 tcc_warning("assignment makes pointer from integer without a cast");
3539 type1
= pointed_type(dt
);
3541 type2
= pointed_type(st
);
3542 else if (sbt
== VT_FUNC
)
3543 type2
= st
; /* a function is implicitly a function pointer */
3546 if (is_compatible_types(type1
, type2
))
3548 for (qualwarn
= lvl
= 0;; ++lvl
) {
3549 if (((type2
->t
& VT_CONSTANT
) && !(type1
->t
& VT_CONSTANT
)) ||
3550 ((type2
->t
& VT_VOLATILE
) && !(type1
->t
& VT_VOLATILE
)))
3552 dbt
= type1
->t
& (VT_BTYPE
|VT_LONG
);
3553 sbt
= type2
->t
& (VT_BTYPE
|VT_LONG
);
3554 if (dbt
!= VT_PTR
|| sbt
!= VT_PTR
)
3556 type1
= pointed_type(type1
);
3557 type2
= pointed_type(type2
);
3559 if (!is_compatible_unqualified_types(type1
, type2
)) {
3560 if ((dbt
== VT_VOID
|| sbt
== VT_VOID
) && lvl
== 0) {
3561 /* void * can match anything */
3562 } else if (dbt
== sbt
3563 && is_integer_btype(sbt
& VT_BTYPE
)
3564 && IS_ENUM(type1
->t
) + IS_ENUM(type2
->t
)
3565 + !!((type1
->t
^ type2
->t
) & VT_UNSIGNED
) < 2) {
3566 /* Like GCC don't warn by default for merely changes
3567 in pointer target signedness. Do warn for different
3568 base types, though, in particular for unsigned enums
3569 and signed int targets. */
3571 tcc_warning("assignment from incompatible pointer type");
3576 tcc_warning_c(warn_discarded_qualifiers
)("assignment discards qualifiers from pointer target type");
3582 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
3583 tcc_warning("assignment makes integer from pointer without a cast");
3584 } else if (sbt
== VT_STRUCT
) {
3585 goto case_VT_STRUCT
;
3587 /* XXX: more tests */
3591 if (!is_compatible_unqualified_types(dt
, st
)) {
3599 static void gen_assign_cast(CType
*dt
)
3601 verify_assign_cast(dt
);
3605 /* store vtop in lvalue pushed on stack */
3606 ST_FUNC
void vstore(void)
3608 int sbt
, dbt
, ft
, r
, size
, align
, bit_size
, bit_pos
, delayed_cast
;
3610 ft
= vtop
[-1].type
.t
;
3611 sbt
= vtop
->type
.t
& VT_BTYPE
;
3612 dbt
= ft
& VT_BTYPE
;
3613 verify_assign_cast(&vtop
[-1].type
);
3615 if (sbt
== VT_STRUCT
) {
3616 /* if structure, only generate pointer */
3617 /* structure assignment : generate memcpy */
3618 size
= type_size(&vtop
->type
, &align
);
3619 /* destination, keep on stack() as result */
3621 #ifdef CONFIG_TCC_BCHECK
3622 if (vtop
->r
& VT_MUSTBOUND
)
3623 gbound(); /* check would be wrong after gaddrof() */
3625 vtop
->type
.t
= VT_PTR
;
3629 #ifdef CONFIG_TCC_BCHECK
3630 if (vtop
->r
& VT_MUSTBOUND
)
3633 vtop
->type
.t
= VT_PTR
;
3636 #ifdef TCC_TARGET_NATIVE_STRUCT_COPY
3638 #ifdef CONFIG_TCC_BCHECK
3639 && !tcc_state
->do_bounds_check
3642 gen_struct_copy(size
);
3648 /* Use memmove, rather than memcpy, as dest and src may be same: */
3651 vpush_helper_func(TOK_memmove8
);
3652 else if(!(align
& 3))
3653 vpush_helper_func(TOK_memmove4
);
3656 vpush_helper_func(TOK_memmove
);
3661 } else if (ft
& VT_BITFIELD
) {
3662 /* bitfield store handling */
3664 /* save lvalue as expression result (example: s.b = s.a = n;) */
3665 vdup(), vtop
[-1] = vtop
[-2];
3667 bit_pos
= BIT_POS(ft
);
3668 bit_size
= BIT_SIZE(ft
);
3669 /* remove bit field info to avoid loops */
3670 vtop
[-1].type
.t
= ft
& ~VT_STRUCT_MASK
;
3672 if (dbt
== VT_BOOL
) {
3673 gen_cast(&vtop
[-1].type
);
3674 vtop
[-1].type
.t
= (vtop
[-1].type
.t
& ~VT_BTYPE
) | (VT_BYTE
| VT_UNSIGNED
);
3676 r
= adjust_bf(vtop
- 1, bit_pos
, bit_size
);
3677 if (dbt
!= VT_BOOL
) {
3678 gen_cast(&vtop
[-1].type
);
3679 dbt
= vtop
[-1].type
.t
& VT_BTYPE
;
3681 if (r
== VT_STRUCT
) {
3682 store_packed_bf(bit_pos
, bit_size
);
3684 unsigned long long mask
= (1ULL << bit_size
) - 1;
3685 if (dbt
!= VT_BOOL
) {
3687 if (dbt
== VT_LLONG
)
3690 vpushi((unsigned)mask
);
3697 /* duplicate destination */
3700 /* load destination, mask and or with source */
3701 if (dbt
== VT_LLONG
)
3702 vpushll(~(mask
<< bit_pos
));
3704 vpushi(~((unsigned)mask
<< bit_pos
));
3709 /* ... and discard */
3712 } else if (dbt
== VT_VOID
) {
3715 /* optimize char/short casts */
3717 if ((dbt
== VT_BYTE
|| dbt
== VT_SHORT
)
3718 && is_integer_btype(sbt
)
3720 if ((vtop
->r
& VT_MUSTCAST
)
3721 && btype_size(dbt
) > btype_size(sbt
)
3723 force_charshort_cast();
3726 gen_cast(&vtop
[-1].type
);
3729 #ifdef CONFIG_TCC_BCHECK
3730 /* bound check case */
3731 if (vtop
[-1].r
& VT_MUSTBOUND
) {
3737 gv(RC_TYPE(dbt
)); /* generate value */
3740 vtop
->r
|= BFVAL(VT_MUSTCAST
, (sbt
== VT_LLONG
) + 1);
3741 //tcc_warning("deley cast %x -> %x", sbt, dbt);
3742 vtop
->type
.t
= ft
& VT_TYPE
;
3745 /* if lvalue was saved on stack, must read it */
3746 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
3748 r
= get_reg(RC_INT
);
3749 sv
.type
.t
= VT_PTRDIFF_T
;
3750 sv
.r
= VT_LOCAL
| VT_LVAL
;
3751 sv
.c
.i
= vtop
[-1].c
.i
;
3753 vtop
[-1].r
= r
| VT_LVAL
;
3756 r
= vtop
->r
& VT_VALMASK
;
3757 /* two word case handling :
3758 store second register at word + 4 (or +8 for x86-64) */
3759 if (USING_TWO_WORDS(dbt
)) {
3760 int load_type
= (dbt
== VT_QFLOAT
) ? VT_DOUBLE
: VT_PTRDIFF_T
;
3761 vtop
[-1].type
.t
= load_type
;
3764 incr_offset(PTR_SIZE
);
3766 /* XXX: it works because r2 is spilled last ! */
3767 store(vtop
->r2
, vtop
- 1);
3773 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
3777 /* post defines POST/PRE add. c is the token ++ or -- */
3778 ST_FUNC
void inc(int post
, int c
)
3781 vdup(); /* save lvalue */
3783 gv_dup(); /* duplicate value */
3788 vpushi(c
- TOK_MID
);
3790 vstore(); /* store value */
3792 vpop(); /* if post op, return saved value */
3795 ST_FUNC CString
* parse_mult_str (const char *msg
)
3797 /* read the string */
3800 cstr_reset(&initstr
);
3801 while (tok
== TOK_STR
) {
3802 /* XXX: add \0 handling too ? */
3803 cstr_cat(&initstr
, tokc
.str
.data
, -1);
3806 cstr_ccat(&initstr
, '\0');
3810 /* If I is >= 1 and a power of two, returns log2(i)+1.
3811 If I is 0 returns 0. */
3812 ST_FUNC
int exact_log2p1(int i
)
3817 for (ret
= 1; i
>= 1 << 8; ret
+= 8)
3828 /* Parse __attribute__((...)) GNUC extension. */
3829 static void parse_attribute(AttributeDef
*ad
)
3835 if (tok
!= TOK_ATTRIBUTE1
&& tok
!= TOK_ATTRIBUTE2
)
3840 while (tok
!= ')') {
3841 if (tok
< TOK_IDENT
)
3842 expect("attribute name");
3854 tcc_warning_c(warn_implicit_function_declaration
)(
3855 "implicit declaration of function '%s'", get_tok_str(tok
, &tokc
));
3856 s
= external_global_sym(tok
, &func_old_type
);
3857 } else if ((s
->type
.t
& VT_BTYPE
) != VT_FUNC
)
3858 tcc_error("'%s' is not declared as function", get_tok_str(tok
, &tokc
));
3859 ad
->cleanup_func
= s
;
3864 case TOK_CONSTRUCTOR1
:
3865 case TOK_CONSTRUCTOR2
:
3866 ad
->f
.func_ctor
= 1;
3868 case TOK_DESTRUCTOR1
:
3869 case TOK_DESTRUCTOR2
:
3870 ad
->f
.func_dtor
= 1;
3872 case TOK_ALWAYS_INLINE1
:
3873 case TOK_ALWAYS_INLINE2
:
3874 ad
->f
.func_alwinl
= 1;
3879 astr
= parse_mult_str("section name")->data
;
3880 ad
->section
= find_section(tcc_state
, astr
);
3886 astr
= parse_mult_str("alias(\"target\")")->data
;
3887 /* save string as token, for later */
3888 ad
->alias_target
= tok_alloc_const(astr
);
3891 case TOK_VISIBILITY1
:
3892 case TOK_VISIBILITY2
:
3894 astr
= parse_mult_str("visibility(\"default|hidden|internal|protected\")")->data
;
3895 if (!strcmp (astr
, "default"))
3896 ad
->a
.visibility
= STV_DEFAULT
;
3897 else if (!strcmp (astr
, "hidden"))
3898 ad
->a
.visibility
= STV_HIDDEN
;
3899 else if (!strcmp (astr
, "internal"))
3900 ad
->a
.visibility
= STV_INTERNAL
;
3901 else if (!strcmp (astr
, "protected"))
3902 ad
->a
.visibility
= STV_PROTECTED
;
3904 expect("visibility(\"default|hidden|internal|protected\")");
3912 if (n
<= 0 || (n
& (n
- 1)) != 0)
3913 tcc_error("alignment must be a positive power of two");
3918 ad
->a
.aligned
= exact_log2p1(n
);
3919 if (n
!= 1 << (ad
->a
.aligned
- 1))
3920 tcc_error("alignment of %d is larger than implemented", n
);
3936 /* currently, no need to handle it because tcc does not
3937 track unused objects */
3941 ad
->f
.func_noreturn
= 1;
3946 ad
->f
.func_call
= FUNC_CDECL
;
3951 ad
->f
.func_call
= FUNC_STDCALL
;
3953 #ifdef TCC_TARGET_I386
3963 ad
->f
.func_call
= FUNC_FASTCALL1
+ n
- 1;
3969 ad
->f
.func_call
= FUNC_FASTCALLW
;
3976 ad
->attr_mode
= VT_LLONG
+ 1;
3979 ad
->attr_mode
= VT_BYTE
+ 1;
3982 ad
->attr_mode
= VT_SHORT
+ 1;
3986 ad
->attr_mode
= VT_INT
+ 1;
3989 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok
, NULL
));
3996 ad
->a
.dllexport
= 1;
3998 case TOK_NODECORATE
:
3999 ad
->a
.nodecorate
= 1;
4002 ad
->a
.dllimport
= 1;
4005 tcc_warning_c(warn_unsupported
)("'%s' attribute ignored", get_tok_str(t
, NULL
));
4006 /* skip parameters */
4008 int parenthesis
= 0;
4012 else if (tok
== ')')
4015 } while (parenthesis
&& tok
!= -1);
4028 static Sym
* find_field (CType
*type
, int v
, int *cumofs
)
4031 int v1
= v
| SYM_FIELD
;
4033 while ((s
= s
->next
) != NULL
) {
4038 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
4039 && s
->v
>= (SYM_FIRST_ANOM
| SYM_FIELD
)) {
4040 /* try to find field in anonymous sub-struct/union */
4041 Sym
*ret
= find_field (&s
->type
, v1
, cumofs
);
4049 if (!(v
& SYM_FIELD
)) { /* top-level call */
4052 tcc_error("dereferencing incomplete type '%s'",
4053 get_tok_str(s
->v
& ~SYM_STRUCT
, 0));
4055 tcc_error("field not found: %s",
4056 get_tok_str(v
, &tokc
));
4061 static void check_fields (CType
*type
, int check
)
4065 while ((s
= s
->next
) != NULL
) {
4066 int v
= s
->v
& ~SYM_FIELD
;
4067 if (v
< SYM_FIRST_ANOM
) {
4068 TokenSym
*ts
= table_ident
[v
- TOK_IDENT
];
4069 if (check
&& (ts
->tok
& SYM_FIELD
))
4070 tcc_error("duplicate member '%s'", get_tok_str(v
, NULL
));
4071 ts
->tok
^= SYM_FIELD
;
4072 } else if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
)
4073 check_fields (&s
->type
, check
);
4077 static void struct_layout(CType
*type
, AttributeDef
*ad
)
4079 int size
, align
, maxalign
, offset
, c
, bit_pos
, bit_size
;
4080 int packed
, a
, bt
, prevbt
, prev_bit_size
;
4081 int pcc
= !tcc_state
->ms_bitfields
;
4082 int pragma_pack
= *tcc_state
->pack_stack_ptr
;
4089 prevbt
= VT_STRUCT
; /* make it never match */
4094 for (f
= type
->ref
->next
; f
; f
= f
->next
) {
4095 if (f
->type
.t
& VT_BITFIELD
)
4096 bit_size
= BIT_SIZE(f
->type
.t
);
4099 size
= type_size(&f
->type
, &align
);
4100 a
= f
->a
.aligned
? 1 << (f
->a
.aligned
- 1) : 0;
4103 if (pcc
&& bit_size
== 0) {
4104 /* in pcc mode, packing does not affect zero-width bitfields */
4107 /* in pcc mode, attribute packed overrides if set. */
4108 if (pcc
&& (f
->a
.packed
|| ad
->a
.packed
))
4111 /* pragma pack overrides align if lesser and packs bitfields always */
4114 if (pragma_pack
< align
)
4115 align
= pragma_pack
;
4116 /* in pcc mode pragma pack also overrides individual align */
4117 if (pcc
&& pragma_pack
< a
)
4121 /* some individual align was specified */
4125 if (type
->ref
->type
.t
== VT_UNION
) {
4126 if (pcc
&& bit_size
>= 0)
4127 size
= (bit_size
+ 7) >> 3;
4132 } else if (bit_size
< 0) {
4134 c
+= (bit_pos
+ 7) >> 3;
4135 c
= (c
+ align
- 1) & -align
;
4144 /* A bit-field. Layout is more complicated. There are two
4145 options: PCC (GCC) compatible and MS compatible */
4147 /* In PCC layout a bit-field is placed adjacent to the
4148 preceding bit-fields, except if:
4150 - an individual alignment was given
4151 - it would overflow its base type container and
4152 there is no packing */
4153 if (bit_size
== 0) {
4155 c
= (c
+ ((bit_pos
+ 7) >> 3) + align
- 1) & -align
;
4157 } else if (f
->a
.aligned
) {
4159 } else if (!packed
) {
4161 int ofs
= ((c
* 8 + bit_pos
) % a8
+ bit_size
+ a8
- 1) / a8
;
4162 if (ofs
> size
/ align
)
4166 /* in pcc mode, long long bitfields have type int if they fit */
4167 if (size
== 8 && bit_size
<= 32)
4168 f
->type
.t
= (f
->type
.t
& ~VT_BTYPE
) | VT_INT
, size
= 4;
4170 while (bit_pos
>= align
* 8)
4171 c
+= align
, bit_pos
-= align
* 8;
4174 /* In PCC layout named bit-fields influence the alignment
4175 of the containing struct using the base types alignment,
4176 except for packed fields (which here have correct align). */
4177 if (f
->v
& SYM_FIRST_ANOM
4178 // && bit_size // ??? gcc on ARM/rpi does that
4183 bt
= f
->type
.t
& VT_BTYPE
;
4184 if ((bit_pos
+ bit_size
> size
* 8)
4185 || (bit_size
> 0) == (bt
!= prevbt
)
4187 c
= (c
+ align
- 1) & -align
;
4190 /* In MS bitfield mode a bit-field run always uses
4191 at least as many bits as the underlying type.
4192 To start a new run it's also required that this
4193 or the last bit-field had non-zero width. */
4194 if (bit_size
|| prev_bit_size
)
4197 /* In MS layout the records alignment is normally
4198 influenced by the field, except for a zero-width
4199 field at the start of a run (but by further zero-width
4200 fields it is again). */
4201 if (bit_size
== 0 && prevbt
!= bt
)
4204 prev_bit_size
= bit_size
;
4207 f
->type
.t
= (f
->type
.t
& ~(0x3f << VT_STRUCT_SHIFT
))
4208 | (bit_pos
<< VT_STRUCT_SHIFT
);
4209 bit_pos
+= bit_size
;
4211 if (align
> maxalign
)
4215 printf("set field %s offset %-2d size %-2d align %-2d",
4216 get_tok_str(f
->v
& ~SYM_FIELD
, NULL
), offset
, size
, align
);
4217 if (f
->type
.t
& VT_BITFIELD
) {
4218 printf(" pos %-2d bits %-2d",
4231 c
+= (bit_pos
+ 7) >> 3;
4233 /* store size and alignment */
4234 a
= bt
= ad
->a
.aligned
? 1 << (ad
->a
.aligned
- 1) : 1;
4238 if (pragma_pack
&& pragma_pack
< maxalign
&& 0 == pcc
) {
4239 /* can happen if individual align for some member was given. In
4240 this case MSVC ignores maxalign when aligning the size */
4245 c
= (c
+ a
- 1) & -a
;
4249 printf("struct size %-2d align %-2d\n\n", c
, a
), fflush(stdout
);
4252 /* check whether we can access bitfields by their type */
4253 for (f
= type
->ref
->next
; f
; f
= f
->next
) {
4257 if (0 == (f
->type
.t
& VT_BITFIELD
))
4261 bit_size
= BIT_SIZE(f
->type
.t
);
4264 bit_pos
= BIT_POS(f
->type
.t
);
4265 size
= type_size(&f
->type
, &align
);
4267 if (bit_pos
+ bit_size
<= size
* 8 && f
->c
+ size
<= c
4268 #ifdef TCC_TARGET_ARM
4269 && !(f
->c
& (align
- 1))
4274 /* try to access the field using a different type */
4275 c0
= -1, s
= align
= 1;
4278 px
= f
->c
* 8 + bit_pos
;
4279 cx
= (px
>> 3) & -align
;
4280 px
= px
- (cx
<< 3);
4283 s
= (px
+ bit_size
+ 7) >> 3;
4293 s
= type_size(&t
, &align
);
4297 if (px
+ bit_size
<= s
* 8 && cx
+ s
<= c
4298 #ifdef TCC_TARGET_ARM
4299 && !(cx
& (align
- 1))
4302 /* update offset and bit position */
4305 f
->type
.t
= (f
->type
.t
& ~(0x3f << VT_STRUCT_SHIFT
))
4306 | (bit_pos
<< VT_STRUCT_SHIFT
);
4310 printf("FIX field %s offset %-2d size %-2d align %-2d "
4311 "pos %-2d bits %-2d\n",
4312 get_tok_str(f
->v
& ~SYM_FIELD
, NULL
),
4313 cx
, s
, align
, px
, bit_size
);
4316 /* fall back to load/store single-byte wise */
4317 f
->auxtype
= VT_STRUCT
;
4319 printf("FIX field %s : load byte-wise\n",
4320 get_tok_str(f
->v
& ~SYM_FIELD
, NULL
));
4326 static void do_Static_assert(void);
4328 /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
4329 static void struct_decl(CType
*type
, int u
)
4331 int v
, c
, size
, align
, flexible
;
4332 int bit_size
, bsize
, bt
;
4334 AttributeDef ad
, ad1
;
4337 memset(&ad
, 0, sizeof ad
);
4339 parse_attribute(&ad
);
4343 /* struct already defined ? return it */
4345 expect("struct/union/enum name");
4347 if (s
&& (s
->sym_scope
== local_scope
|| tok
!= '{')) {
4350 if (u
== VT_ENUM
&& IS_ENUM(s
->type
.t
))
4352 tcc_error("redefinition of '%s'", get_tok_str(v
, NULL
));
4357 /* Record the original enum/struct/union token. */
4358 type1
.t
= u
== VT_ENUM
? u
| VT_INT
| VT_UNSIGNED
: u
;
4360 /* we put an undefined size for struct/union */
4361 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
4362 s
->r
= 0; /* default alignment is zero as gcc */
4364 type
->t
= s
->type
.t
;
4370 tcc_error("struct/union/enum already defined");
4372 /* cannot be empty */
4373 /* non empty enums are not allowed */
4376 long long ll
= 0, pl
= 0, nl
= 0;
4379 /* enum symbols have static storage */
4380 t
.t
= VT_INT
|VT_STATIC
|VT_ENUM_VAL
;
4384 expect("identifier");
4386 if (ss
&& !local_stack
)
4387 tcc_error("redefinition of enumerator '%s'",
4388 get_tok_str(v
, NULL
));
4392 ll
= expr_const64();
4394 ss
= sym_push(v
, &t
, VT_CONST
, 0);
4396 *ps
= ss
, ps
= &ss
->next
;
4405 /* NOTE: we accept a trailing comma */
4410 /* set integral type of the enum */
4413 if (pl
!= (unsigned)pl
)
4414 t
.t
= (LONG_SIZE
==8 ? VT_LLONG
|VT_LONG
: VT_LLONG
);
4416 } else if (pl
!= (int)pl
|| nl
!= (int)nl
)
4417 t
.t
= (LONG_SIZE
==8 ? VT_LLONG
|VT_LONG
: VT_LLONG
);
4418 s
->type
.t
= type
->t
= t
.t
| VT_ENUM
;
4420 /* set type for enum members */
4421 for (ss
= s
->next
; ss
; ss
= ss
->next
) {
4423 if (ll
== (int)ll
) /* default is int if it fits */
4425 if (t
.t
& VT_UNSIGNED
) {
4426 ss
->type
.t
|= VT_UNSIGNED
;
4427 if (ll
== (unsigned)ll
)
4430 ss
->type
.t
= (ss
->type
.t
& ~VT_BTYPE
)
4431 | (LONG_SIZE
==8 ? VT_LLONG
|VT_LONG
: VT_LLONG
);
4436 while (tok
!= '}') {
4437 if (tok
== TOK_STATIC_ASSERT
) {
4441 if (!parse_btype(&btype
, &ad1
, 0)) {
4447 tcc_error("flexible array member '%s' not at the end of struct",
4448 get_tok_str(v
, NULL
));
4454 type_decl(&type1
, &ad1
, &v
, TYPE_DIRECT
);
4456 if ((type1
.t
& VT_BTYPE
) != VT_STRUCT
)
4457 expect("identifier");
4459 int v
= btype
.ref
->v
;
4460 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
4461 if (tcc_state
->ms_extensions
== 0)
4462 expect("identifier");
4466 if (type_size(&type1
, &align
) < 0) {
4467 if ((u
== VT_STRUCT
) && (type1
.t
& VT_ARRAY
) && c
)
4470 tcc_error("field '%s' has incomplete type",
4471 get_tok_str(v
, NULL
));
4473 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
4474 (type1
.t
& VT_BTYPE
) == VT_VOID
||
4475 (type1
.t
& VT_STORAGE
))
4476 tcc_error("invalid type for '%s'",
4477 get_tok_str(v
, NULL
));
4481 bit_size
= expr_const();
4482 /* XXX: handle v = 0 case for messages */
4484 tcc_error("negative width in bit-field '%s'",
4485 get_tok_str(v
, NULL
));
4486 if (v
&& bit_size
== 0)
4487 tcc_error("zero width for bit-field '%s'",
4488 get_tok_str(v
, NULL
));
4489 parse_attribute(&ad1
);
4491 size
= type_size(&type1
, &align
);
4492 if (bit_size
>= 0) {
4493 bt
= type1
.t
& VT_BTYPE
;
4499 tcc_error("bitfields must have scalar type");
4501 if (bit_size
> bsize
) {
4502 tcc_error("width of '%s' exceeds its type",
4503 get_tok_str(v
, NULL
));
4504 } else if (bit_size
== bsize
4505 && !ad
.a
.packed
&& !ad1
.a
.packed
) {
4506 /* no need for bit fields */
4508 } else if (bit_size
== 64) {
4509 tcc_error("field width 64 not implemented");
4511 type1
.t
= (type1
.t
& ~VT_STRUCT_MASK
)
4513 | (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4516 if (v
!= 0 || (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
4517 /* Remember we've seen a real field to check
4518 for placement of flexible array member. */
4521 /* If member is a struct or bit-field, enforce
4522 placing into the struct (as anonymous). */
4524 ((type1
.t
& VT_BTYPE
) == VT_STRUCT
||
4529 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, 0);
4534 if (tok
== ';' || tok
== TOK_EOF
)
4541 parse_attribute(&ad
);
4542 if (ad
.cleanup_func
) {
4543 tcc_warning("attribute '__cleanup__' ignored on type");
4545 check_fields(type
, 1);
4546 check_fields(type
, 0);
4547 struct_layout(type
, &ad
);
4549 tcc_debug_fix_anon(tcc_state
, type
);
4554 static void sym_to_attr(AttributeDef
*ad
, Sym
*s
)
4556 merge_symattr(&ad
->a
, &s
->a
);
4557 merge_funcattr(&ad
->f
, &s
->f
);
4560 /* Add type qualifiers to a type. If the type is an array then the qualifiers
4561 are added to the element type, copied because it could be a typedef. */
4562 static void parse_btype_qualify(CType
*type
, int qualifiers
)
4564 while (type
->t
& VT_ARRAY
) {
4565 type
->ref
= sym_push(SYM_FIELD
, &type
->ref
->type
, 0, type
->ref
->c
);
4566 type
= &type
->ref
->type
;
4568 type
->t
|= qualifiers
;
4571 /* return 0 if no type declaration. otherwise, return the basic type
4574 static int parse_btype(CType
*type
, AttributeDef
*ad
, int ignore_label
)
4576 int t
, u
, bt
, st
, type_found
, typespec_found
, g
, n
;
4580 memset(ad
, 0, sizeof(AttributeDef
));
4590 /* currently, we really ignore extension */
4600 if (u
== VT_SHORT
|| u
== VT_LONG
) {
4601 if (st
!= -1 || (bt
!= -1 && bt
!= VT_INT
))
4602 tmbt
: tcc_error("too many basic types");
4605 if (bt
!= -1 || (st
!= -1 && u
!= VT_INT
))
4610 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | u
;
4627 memset(&ad1
, 0, sizeof(AttributeDef
));
4628 if (parse_btype(&type1
, &ad1
, 0)) {
4629 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
4631 n
= 1 << (ad1
.a
.aligned
- 1);
4633 type_size(&type1
, &n
);
4636 if (n
< 0 || (n
& (n
- 1)) != 0)
4637 tcc_error("alignment must be a positive power of two");
4640 ad
->a
.aligned
= exact_log2p1(n
);
4644 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4645 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | VT_LDOUBLE
;
4646 } else if ((t
& (VT_BTYPE
|VT_LONG
)) == VT_LONG
) {
4647 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | VT_LLONG
;
4654 #ifdef TCC_TARGET_ARM64
4656 /* GCC's __uint128_t appears in some Linux header files. Make it a
4657 synonym for long double to get the size and alignment right. */
4665 tcc_error("_Complex is not yet supported");
4670 if ((t
& (VT_BTYPE
|VT_LONG
)) == VT_LONG
) {
4671 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | VT_LDOUBLE
;
4679 struct_decl(&type1
, VT_ENUM
);
4682 type
->ref
= type1
.ref
;
4685 struct_decl(&type1
, VT_STRUCT
);
4688 struct_decl(&type1
, VT_UNION
);
4691 /* type modifiers */
4695 parse_btype_qualify(type
, VT_ATOMIC
);
4698 parse_expr_type(&type1
);
4699 /* remove all storage modifiers except typedef */
4700 type1
.t
&= ~(VT_STORAGE
&~VT_TYPEDEF
);
4702 sym_to_attr(ad
, type1
.ref
);
4710 parse_btype_qualify(type
, VT_CONSTANT
);
4718 parse_btype_qualify(type
, VT_VOLATILE
);
4725 if ((t
& (VT_DEFSIGN
|VT_UNSIGNED
)) == (VT_DEFSIGN
|VT_UNSIGNED
))
4726 tcc_error("signed and unsigned modifier");
4739 if ((t
& (VT_DEFSIGN
|VT_UNSIGNED
)) == VT_DEFSIGN
)
4740 tcc_error("signed and unsigned modifier");
4741 t
|= VT_DEFSIGN
| VT_UNSIGNED
;
4757 if (t
& (VT_EXTERN
|VT_STATIC
|VT_TYPEDEF
) & ~g
)
4758 tcc_error("multiple storage classes");
4770 ad
->f
.func_noreturn
= 1;
4772 /* GNUC attribute */
4773 case TOK_ATTRIBUTE1
:
4774 case TOK_ATTRIBUTE2
:
4775 parse_attribute(ad
);
4776 if (ad
->attr_mode
) {
4777 u
= ad
->attr_mode
-1;
4778 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | u
;
4786 parse_expr_type(&type1
);
4787 /* remove all storage modifiers except typedef */
4788 type1
.t
&= ~(VT_STORAGE
&~VT_TYPEDEF
);
4790 sym_to_attr(ad
, type1
.ref
);
4792 case TOK_THREAD_LOCAL
:
4793 tcc_error("_Thread_local is not implemented");
4798 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
4802 if (tok
== ':' && ignore_label
) {
4803 /* ignore if it's a label */
4808 t
&= ~(VT_BTYPE
|VT_LONG
);
4809 u
= t
& ~(VT_CONSTANT
| VT_VOLATILE
), t
^= u
;
4810 type
->t
= (s
->type
.t
& ~VT_TYPEDEF
) | u
;
4811 type
->ref
= s
->type
.ref
;
4813 parse_btype_qualify(type
, t
);
4815 /* get attributes from typedef */
4824 if (tcc_state
->char_is_unsigned
) {
4825 if ((t
& (VT_DEFSIGN
|VT_BTYPE
)) == VT_BYTE
)
4828 /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
4829 bt
= t
& (VT_BTYPE
|VT_LONG
);
4831 t
|= LONG_SIZE
== 8 ? VT_LLONG
: VT_INT
;
4832 #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
4833 if (bt
== VT_LDOUBLE
)
4834 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | (VT_DOUBLE
|VT_LONG
);
4840 /* convert a function parameter type (array to pointer and function to
4841 function pointer) */
4842 static inline void convert_parameter_type(CType
*pt
)
4844 /* remove const and volatile qualifiers (XXX: const could be used
4845 to indicate a const function parameter */
4846 pt
->t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
4847 /* array must be transformed to pointer according to ANSI C */
4849 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
4854 ST_FUNC CString
* parse_asm_str(void)
4857 return parse_mult_str("string constant");
4860 /* Parse an asm label and return the token */
4861 static int asm_label_instr(void)
4867 astr
= parse_asm_str()->data
;
4870 printf("asm_alias: \"%s\"\n", astr
);
4872 v
= tok_alloc_const(astr
);
4876 static int post_type(CType
*type
, AttributeDef
*ad
, int storage
, int td
)
4878 int n
, l
, t1
, arg_size
, align
;
4879 Sym
**plast
, *s
, *first
;
4882 TokenString
*vla_array_tok
= NULL
;
4883 int *vla_array_str
= NULL
;
4886 /* function type, or recursive declarator (return if so) */
4888 if (TYPE_DIRECT
== (td
& (TYPE_DIRECT
|TYPE_ABSTRACT
)))
4892 else if (parse_btype(&pt
, &ad1
, 0))
4894 else if (td
& (TYPE_DIRECT
|TYPE_ABSTRACT
)) {
4895 merge_attr (ad
, &ad1
);
4906 /* read param name and compute offset */
4907 if (l
!= FUNC_OLD
) {
4908 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
4910 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
| TYPE_PARAM
);
4911 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
4912 tcc_error("parameter declared as void");
4917 pt
.t
= VT_VOID
; /* invalid type */
4922 expect("identifier");
4923 convert_parameter_type(&pt
);
4924 arg_size
+= (type_size(&pt
, &align
) + PTR_SIZE
- 1) / PTR_SIZE
;
4925 /* these symbols may be evaluated for VLArrays (see below, under
4926 nocode_wanted) which is why we push them here as normal symbols
4927 temporarily. Example: int func(int a, int b[++a]); */
4928 s
= sym_push(n
, &pt
, VT_LOCAL
|VT_LVAL
, 0);
4934 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
4939 if (l
== FUNC_NEW
&& !parse_btype(&pt
, &ad1
, 0))
4940 tcc_error("invalid type");
4943 /* if no parameters, then old type prototype */
4946 /* remove parameter symbols from token table, keep on stack */
4948 sym_pop(local_stack
? &local_stack
: &global_stack
, first
->prev
, 1);
4949 for (s
= first
; s
; s
= s
->next
)
4953 /* NOTE: const is ignored in returned type as it has a special
4954 meaning in gcc / C++ */
4955 type
->t
&= ~VT_CONSTANT
;
4956 /* some ancient pre-K&R C allows a function to return an array
4957 and the array brackets to be put after the arguments, such
4958 that "int c()[]" means something like "int[] c()" */
4961 skip(']'); /* only handle simple "[]" */
4964 /* we push a anonymous symbol which will contain the function prototype */
4965 ad
->f
.func_args
= arg_size
;
4966 ad
->f
.func_type
= l
;
4967 s
= sym_push(SYM_FIELD
, type
, 0, 0);
4973 } else if (tok
== '[') {
4974 int saved_nocode_wanted
= nocode_wanted
;
4975 /* array definition */
4979 if (td
& TYPE_PARAM
) while (1) {
4980 /* XXX The optional type-quals and static should only be accepted
4981 in parameter decls. The '*' as well, and then even only
4982 in prototypes (not function defs). */
4984 case TOK_RESTRICT1
: case TOK_RESTRICT2
: case TOK_RESTRICT3
:
4995 /* Code generation is not done now but has to be done
4996 at start of function. Save code here for later use. */
4998 skip_or_save_block(&vla_array_tok
);
5000 vla_array_str
= vla_array_tok
->str
;
5001 begin_macro(vla_array_tok
, 2);
5010 } else if (tok
!= ']') {
5011 if (!local_stack
|| (storage
& VT_STATIC
))
5012 vpushi(expr_const());
5014 /* VLAs (which can only happen with local_stack && !VT_STATIC)
5015 length must always be evaluated, even under nocode_wanted,
5016 so that its size slot is initialized (e.g. under sizeof
5022 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
5025 tcc_error("invalid array size");
5027 if (!is_integer_btype(vtop
->type
.t
& VT_BTYPE
))
5028 tcc_error("size of variable length array should be an integer");
5034 /* parse next post type */
5035 post_type(type
, ad
, storage
, (td
& ~(TYPE_DIRECT
|TYPE_ABSTRACT
)) | TYPE_NEST
);
5037 if ((type
->t
& VT_BTYPE
) == VT_FUNC
)
5038 tcc_error("declaration of an array of functions");
5039 if ((type
->t
& VT_BTYPE
) == VT_VOID
5040 || type_size(type
, &align
) < 0)
5041 tcc_error("declaration of an array of incomplete type elements");
5043 t1
|= type
->t
& VT_VLA
;
5048 tcc_error("need explicit inner array size in VLAs");
5051 loc
-= type_size(&int_type
, &align
);
5055 vpush_type_size(type
, &align
);
5057 vset(&int_type
, VT_LOCAL
|VT_LVAL
, n
);
5064 nocode_wanted
= saved_nocode_wanted
;
5066 /* we push an anonymous symbol which will contain the array
5068 s
= sym_push(SYM_FIELD
, type
, 0, n
);
5069 type
->t
= (t1
? VT_VLA
: VT_ARRAY
) | VT_PTR
;
5072 if (vla_array_str
) {
5074 s
->vla_array_str
= vla_array_str
;
5076 tok_str_free_str(vla_array_str
);
5082 /* Parse a type declarator (except basic type), and return the type
5083 in 'type'. 'td' is a bitmask indicating which kind of type decl is
5084 expected. 'type' should contain the basic type. 'ad' is the
5085 attribute definition of the basic type. It can be modified by
5086 type_decl(). If this (possibly abstract) declarator is a pointer chain
5087 it returns the innermost pointed to type (equals *type, but is a different
5088 pointer), otherwise returns type itself, that's used for recursive calls. */
5089 static CType
*type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
5092 int qualifiers
, storage
;
5094 /* recursive type, remove storage bits first, apply them later again */
5095 storage
= type
->t
& VT_STORAGE
;
5096 type
->t
&= ~VT_STORAGE
;
5099 while (tok
== '*') {
5105 qualifiers
|= VT_ATOMIC
;
5110 qualifiers
|= VT_CONSTANT
;
5115 qualifiers
|= VT_VOLATILE
;
5121 /* XXX: clarify attribute handling */
5122 case TOK_ATTRIBUTE1
:
5123 case TOK_ATTRIBUTE2
:
5124 parse_attribute(ad
);
5128 type
->t
|= qualifiers
;
5130 /* innermost pointed to type is the one for the first derivation */
5131 ret
= pointed_type(type
);
5135 /* This is possibly a parameter type list for abstract declarators
5136 ('int ()'), use post_type for testing this. */
5137 if (!post_type(type
, ad
, 0, td
)) {
5138 /* It's not, so it's a nested declarator, and the post operations
5139 apply to the innermost pointed to type (if any). */
5140 /* XXX: this is not correct to modify 'ad' at this point, but
5141 the syntax is not clear */
5142 parse_attribute(ad
);
5143 post
= type_decl(type
, ad
, v
, td
);
5147 } else if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
5148 /* type identifier */
5153 if (!(td
& TYPE_ABSTRACT
))
5154 expect("identifier");
5157 post_type(post
, ad
, post
!= ret
? 0 : storage
,
5158 td
& ~(TYPE_DIRECT
|TYPE_ABSTRACT
));
5159 parse_attribute(ad
);
5164 /* indirection with full error checking and bound check */
5165 ST_FUNC
void indir(void)
5167 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
) {
5168 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
5172 if (vtop
->r
& VT_LVAL
)
5174 vtop
->type
= *pointed_type(&vtop
->type
);
5175 /* Arrays and functions are never lvalues */
5176 if (!(vtop
->type
.t
& (VT_ARRAY
| VT_VLA
))
5177 && (vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
5179 /* if bound checking, the referenced pointer must be checked */
5180 #ifdef CONFIG_TCC_BCHECK
5181 if (tcc_state
->do_bounds_check
)
5182 vtop
->r
|= VT_MUSTBOUND
;
5187 /* pass a parameter to a function and do type checking and casting */
5188 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
5193 func_type
= func
->f
.func_type
;
5194 if (func_type
== FUNC_OLD
||
5195 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
5196 /* default casting : only need to convert float to double */
5197 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
5198 gen_cast_s(VT_DOUBLE
);
5199 } else if (vtop
->type
.t
& VT_BITFIELD
) {
5200 type
.t
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5201 type
.ref
= vtop
->type
.ref
;
5203 } else if (vtop
->r
& VT_MUSTCAST
) {
5204 force_charshort_cast();
5206 } else if (arg
== NULL
) {
5207 tcc_error("too many arguments to function");
5210 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
5211 gen_assign_cast(&type
);
5215 /* parse an expression and return its type without any side effect. */
5216 static void expr_type(CType
*type
, void (*expr_fn
)(void))
5225 /* parse an expression of the form '(type)' or '(expr)' and return its
5227 static void parse_expr_type(CType
*type
)
5233 if (parse_btype(type
, &ad
, 0)) {
5234 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
5236 expr_type(type
, gexpr
);
5241 static void parse_type(CType
*type
)
5246 if (!parse_btype(type
, &ad
, 0)) {
5249 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
5252 static void parse_builtin_params(int nc
, const char *args
)
5261 while ((c
= *args
++)) {
5276 type
.t
= VT_CONSTANT
;
5282 type
.t
= VT_CONSTANT
;
5284 type
.t
|= char_type
.t
;
5296 gen_assign_cast(&type
);
5303 static void parse_atomic(int atok
)
5305 int size
, align
, arg
, t
, save
= 0;
5306 CType
*atom
, *atom_ptr
, ct
= {0};
5309 static const char *const templates
[] = {
5311 * Each entry consists of callback and function template.
5312 * The template represents argument types and return type.
5314 * ? void (return-only)
5317 * A read-only atomic
5318 * p pointer to memory
5325 /* keep in order of appearance in tcctok.h: */
5326 /* __atomic_store */ "alm.?",
5327 /* __atomic_load */ "Asm.v",
5328 /* __atomic_exchange */ "alsm.v",
5329 /* __atomic_compare_exchange */ "aplbmm.b",
5330 /* __atomic_fetch_add */ "avm.v",
5331 /* __atomic_fetch_sub */ "avm.v",
5332 /* __atomic_fetch_or */ "avm.v",
5333 /* __atomic_fetch_xor */ "avm.v",
5334 /* __atomic_fetch_and */ "avm.v",
5335 /* __atomic_fetch_nand */ "avm.v",
5336 /* __atomic_and_fetch */ "avm.v",
5337 /* __atomic_sub_fetch */ "avm.v",
5338 /* __atomic_or_fetch */ "avm.v",
5339 /* __atomic_xor_fetch */ "avm.v",
5340 /* __atomic_and_fetch */ "avm.v",
5341 /* __atomic_nand_fetch */ "avm.v"
5343 const char *template = templates
[(atok
- TOK___atomic_store
)];
5345 atom
= atom_ptr
= NULL
;
5346 size
= 0; /* pacify compiler */
5351 switch (template[arg
]) {
5354 atom_ptr
= &vtop
->type
;
5355 if ((atom_ptr
->t
& VT_BTYPE
) != VT_PTR
)
5357 atom
= pointed_type(atom_ptr
);
5358 size
= type_size(atom
, &align
);
5360 || (size
& (size
- 1))
5361 || (atok
> TOK___atomic_compare_exchange
5362 && (0 == btype_size(atom
->t
& VT_BTYPE
)
5363 || (atom
->t
& VT_BTYPE
) == VT_PTR
)))
5364 expect("integral or integer-sized pointer target type");
5365 /* GCC does not care either: */
5366 /* if (!(atom->t & VT_ATOMIC))
5367 tcc_warning("pointer target declaration is missing '_Atomic'"); */
5371 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
5372 || type_size(pointed_type(&vtop
->type
), &align
) != size
)
5373 tcc_error("pointer target type mismatch in argument %d", arg
+ 1);
5374 gen_assign_cast(atom_ptr
);
5377 gen_assign_cast(atom
);
5381 gen_assign_cast(atom
);
5390 gen_assign_cast(&int_type
);
5394 gen_assign_cast(&ct
);
5397 if ('.' == template[++arg
])
5404 switch (template[arg
+ 1]) {
5413 sprintf(buf
, "%s_%d", get_tok_str(atok
, 0), size
);
5414 vpush_helper_func(tok_alloc_const(buf
));
5415 vrott(arg
- save
+ 1);
5416 gfunc_call(arg
- save
);
5419 PUT_R_RET(vtop
, ct
.t
);
5420 t
= ct
.t
& VT_BTYPE
;
5421 if (t
== VT_BYTE
|| t
== VT_SHORT
|| t
== VT_BOOL
) {
5423 vtop
->r
|= BFVAL(VT_MUSTCAST
, 1);
5425 vtop
->type
.t
= VT_INT
;
5437 ST_FUNC
void unary(void)
5439 int n
, t
, align
, size
, r
, sizeof_caller
;
5444 /* generate line number info */
5446 tcc_debug_line(tcc_state
), tcc_tcov_check_line (tcc_state
, 1);
5448 sizeof_caller
= in_sizeof
;
5451 /* XXX: GCC 2.95.3 does not generate a table although it should be
5459 #ifdef TCC_TARGET_PE
5460 t
= VT_SHORT
|VT_UNSIGNED
;
5468 vsetc(&type
, VT_CONST
, &tokc
);
5472 t
= VT_INT
| VT_UNSIGNED
;
5478 t
= VT_LLONG
| VT_UNSIGNED
;
5487 #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
5488 t
= VT_DOUBLE
| VT_LONG
;
5494 t
= (LONG_SIZE
== 8 ? VT_LLONG
: VT_INT
) | VT_LONG
;
5497 t
= (LONG_SIZE
== 8 ? VT_LLONG
: VT_INT
) | VT_LONG
| VT_UNSIGNED
;
5499 case TOK___FUNCTION__
:
5501 goto tok_identifier
;
5507 /* special function name identifier */
5508 len
= strlen(funcname
) + 1;
5509 /* generate char[len] type */
5510 type
.t
= char_type
.t
;
5511 if (tcc_state
->warn_write_strings
& WARN_ON
)
5512 type
.t
|= VT_CONSTANT
;
5516 sec
= rodata_section
;
5517 vpush_ref(&type
, sec
, sec
->data_offset
, len
);
5519 memcpy(section_ptr_add(sec
, len
), funcname
, len
);
5524 #ifdef TCC_TARGET_PE
5525 t
= VT_SHORT
| VT_UNSIGNED
;
5531 /* string parsing */
5534 if (tcc_state
->warn_write_strings
& WARN_ON
)
5539 memset(&ad
, 0, sizeof(AttributeDef
));
5540 ad
.section
= rodata_section
;
5541 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
5546 if (parse_btype(&type
, &ad
, 0)) {
5547 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
5549 /* check ISOC99 compound literal */
5551 /* data is allocated locally by default */
5556 /* all except arrays are lvalues */
5557 if (!(type
.t
& VT_ARRAY
))
5559 memset(&ad
, 0, sizeof(AttributeDef
));
5560 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
5562 if (sizeof_caller
) {
5569 } else if (tok
== '{') {
5570 int saved_nocode_wanted
= nocode_wanted
;
5571 if (CONST_WANTED
&& !NOEVAL_WANTED
)
5573 if (0 == local_scope
)
5574 tcc_error("statement expression outside of function");
5575 /* save all registers */
5577 /* statement expression : we do not accept break/continue
5578 inside as GCC does. We do retain the nocode_wanted state,
5579 as statement expressions can't ever be entered from the
5580 outside, so any reactivation of code emission (from labels
5581 or loop heads) can be disabled again after the end of it. */
5583 /* If the statement expr can be entered, then we retain the current
5584 nocode_wanted state (from e.g. a 'return 0;' in the stmt-expr).
5585 If it can't be entered then the state is that from before the
5586 statement expression. */
5587 if (saved_nocode_wanted
)
5588 nocode_wanted
= saved_nocode_wanted
;
5603 /* functions names must be treated as function pointers,
5604 except for unary '&' and sizeof. Since we consider that
5605 functions are not lvalues, we only have to handle it
5606 there and in function calls. */
5607 /* arrays can also be used although they are not lvalues */
5608 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
5609 !(vtop
->type
.t
& (VT_ARRAY
| VT_VLA
)))
5612 vtop
->sym
->a
.addrtaken
= 1;
5613 mk_pointer(&vtop
->type
);
5619 gen_test_zero(TOK_EQ
);
5630 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
5631 tcc_error("pointer not accepted for unary plus");
5632 /* In order to force cast, we add zero, except for floating point
5633 where we really need an noop (otherwise -0.0 will be transformed
5635 if (!is_float(vtop
->type
.t
)) {
5647 expr_type(&type
, unary
); /* Perform a in_sizeof = 0; */
5648 if (t
== TOK_SIZEOF
) {
5649 vpush_type_size(&type
, &align
);
5650 gen_cast_s(VT_SIZE_T
);
5652 type_size(&type
, &align
);
5654 if (vtop
[1].r
& VT_SYM
)
5655 s
= vtop
[1].sym
; /* hack: accessing previous vtop */
5656 if (s
&& s
->a
.aligned
)
5657 align
= 1 << (s
->a
.aligned
- 1);
5662 case TOK_builtin_expect
:
5663 /* __builtin_expect is a no-op for now */
5664 parse_builtin_params(0, "ee");
5667 case TOK_builtin_types_compatible_p
:
5668 parse_builtin_params(0, "tt");
5669 vtop
[-1].type
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
5670 vtop
[0].type
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
5671 n
= is_compatible_types(&vtop
[-1].type
, &vtop
[0].type
);
5675 case TOK_builtin_choose_expr
:
5702 case TOK_builtin_constant_p
:
5704 parse_builtin_params(1, "e");
5706 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
&&
5707 !((vtop
->r
& VT_SYM
) && vtop
->sym
->a
.addrtaken
);
5711 case TOK_builtin_frame_address
:
5712 case TOK_builtin_return_address
:
5718 level
= expr_const64();
5720 tcc_error("%s only takes positive integers",
5721 tok1
== TOK_builtin_return_address
?
5722 "__builtin_return_address" :
5723 "__builtin_frame_address");
5728 vset(&type
, VT_LOCAL
, 0); /* local frame */
5730 #ifdef TCC_TARGET_RISCV64
5734 mk_pointer(&vtop
->type
);
5735 indir(); /* -> parent frame */
5737 if (tok1
== TOK_builtin_return_address
) {
5738 // assume return address is just above frame pointer on stack
5739 #ifdef TCC_TARGET_ARM
5742 #elif defined TCC_TARGET_RISCV64
5749 mk_pointer(&vtop
->type
);
5754 #ifdef TCC_TARGET_RISCV64
5755 case TOK_builtin_va_start
:
5756 parse_builtin_params(0, "ee");
5757 r
= vtop
->r
& VT_VALMASK
;
5761 tcc_error("__builtin_va_start expects a local variable");
5766 #ifdef TCC_TARGET_X86_64
5767 #ifdef TCC_TARGET_PE
5768 case TOK_builtin_va_start
:
5769 parse_builtin_params(0, "ee");
5770 r
= vtop
->r
& VT_VALMASK
;
5774 tcc_error("__builtin_va_start expects a local variable");
5776 vtop
->type
= char_pointer_type
;
5781 case TOK_builtin_va_arg_types
:
5782 parse_builtin_params(0, "t");
5783 vpushi(classify_x86_64_va_arg(&vtop
->type
));
5790 #ifdef TCC_TARGET_ARM64
5791 case TOK_builtin_va_start
: {
5792 parse_builtin_params(0, "ee");
5796 vtop
->type
.t
= VT_VOID
;
5799 case TOK_builtin_va_arg
: {
5800 parse_builtin_params(0, "et");
5808 case TOK___arm64_clear_cache
: {
5809 parse_builtin_params(0, "ee");
5812 vtop
->type
.t
= VT_VOID
;
5817 /* atomic operations */
5818 case TOK___atomic_store
:
5819 case TOK___atomic_load
:
5820 case TOK___atomic_exchange
:
5821 case TOK___atomic_compare_exchange
:
5822 case TOK___atomic_fetch_add
:
5823 case TOK___atomic_fetch_sub
:
5824 case TOK___atomic_fetch_or
:
5825 case TOK___atomic_fetch_xor
:
5826 case TOK___atomic_fetch_and
:
5827 case TOK___atomic_fetch_nand
:
5828 case TOK___atomic_add_fetch
:
5829 case TOK___atomic_sub_fetch
:
5830 case TOK___atomic_or_fetch
:
5831 case TOK___atomic_xor_fetch
:
5832 case TOK___atomic_and_fetch
:
5833 case TOK___atomic_nand_fetch
:
5837 /* pre operations */
5848 if (is_float(vtop
->type
.t
)) {
5858 goto tok_identifier
;
5860 /* allow to take the address of a label */
5861 if (tok
< TOK_UIDENT
)
5862 expect("label identifier");
5863 s
= label_find(tok
);
5865 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
5867 if (s
->r
== LABEL_DECLARED
)
5868 s
->r
= LABEL_FORWARD
;
5870 if ((s
->type
.t
& VT_BTYPE
) != VT_PTR
) {
5871 s
->type
.t
= VT_VOID
;
5872 mk_pointer(&s
->type
);
5873 s
->type
.t
|= VT_STATIC
;
5875 vpushsym(&s
->type
, s
);
5881 CType controlling_type
;
5882 int has_default
= 0;
5885 TokenString
*str
= NULL
;
5886 int saved_nocode_wanted
= nocode_wanted
;
5887 nocode_wanted
&= ~CONST_WANTED_MASK
;
5891 expr_type(&controlling_type
, expr_eq
);
5892 controlling_type
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
| VT_ARRAY
);
5893 if ((controlling_type
.t
& VT_BTYPE
) == VT_FUNC
)
5894 mk_pointer(&controlling_type
);
5896 nocode_wanted
= saved_nocode_wanted
;
5901 if (tok
== TOK_DEFAULT
) {
5903 tcc_error("too many 'default'");
5909 AttributeDef ad_tmp
;
5913 parse_btype(&cur_type
, &ad_tmp
, 0);
5914 type_decl(&cur_type
, &ad_tmp
, &itmp
, TYPE_ABSTRACT
);
5915 if (compare_types(&controlling_type
, &cur_type
, 0)) {
5917 tcc_error("type match twice");
5927 skip_or_save_block(&str
);
5929 skip_or_save_block(NULL
);
5936 type_to_str(buf
, sizeof buf
, &controlling_type
, NULL
);
5937 tcc_error("type '%s' does not match any association", buf
);
5939 begin_macro(str
, 1);
5948 // special qnan , snan and infinity values
5953 vtop
->type
.t
= VT_FLOAT
;
5958 goto special_math_val
;
5961 goto special_math_val
;
5968 expect("identifier");
5970 if (!s
|| IS_ASM_SYM(s
)) {
5971 const char *name
= get_tok_str(t
, NULL
);
5973 tcc_error("'%s' undeclared", name
);
5974 /* for simple function calls, we tolerate undeclared
5975 external reference to int() function */
5976 tcc_warning_c(warn_implicit_function_declaration
)(
5977 "implicit declaration of function '%s'", name
);
5978 s
= external_global_sym(t
, &func_old_type
);
5982 /* A symbol that has a register is a local register variable,
5983 which starts out as VT_LOCAL value. */
5984 if ((r
& VT_VALMASK
) < VT_CONST
)
5985 r
= (r
& ~VT_VALMASK
) | VT_LOCAL
;
5987 vset(&s
->type
, r
, s
->c
);
5988 /* Point to s as backpointer (even without r&VT_SYM).
5989 Will be used by at least the x86 inline asm parser for
5995 } else if (r
== VT_CONST
&& IS_ENUM_VAL(s
->type
.t
)) {
5996 vtop
->c
.i
= s
->enum_val
;
6001 /* post operations */
6003 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
6006 } else if (tok
== '.' || tok
== TOK_ARROW
|| tok
== TOK_CDOUBLE
) {
6007 int qualifiers
, cumofs
= 0;
6009 if (tok
== TOK_ARROW
)
6011 qualifiers
= vtop
->type
.t
& (VT_CONSTANT
| VT_VOLATILE
);
6013 /* expect pointer on structure */
6014 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
6015 expect("struct or union");
6016 if (tok
== TOK_CDOUBLE
)
6017 expect("field name");
6019 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
6020 expect("field name");
6021 s
= find_field(&vtop
->type
, tok
, &cumofs
);
6022 /* add field offset to pointer */
6023 incr_offset(cumofs
);
6024 /* change type to field type, and set to lvalue */
6025 vtop
->type
= s
->type
;
6026 vtop
->type
.t
|= qualifiers
;
6027 /* an array is never an lvalue */
6028 if (vtop
->type
.t
& VT_ARRAY
) {
6029 vtop
->r
&= ~VT_LVAL
;
6030 #ifdef CONFIG_TCC_BCHECK
6032 /* if bound checking, the referenced pointer must be checked */
6033 if (tcc_state
->do_bounds_check
)
6034 vtop
->r
|= VT_MUSTBOUND
;
6038 } else if (tok
== '[') {
6044 } else if (tok
== '(') {
6047 int nb_args
, ret_nregs
, ret_align
, regsize
, variadic
;
6050 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
6051 /* pointer test (no array accepted) */
6052 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
6053 vtop
->type
= *pointed_type(&vtop
->type
);
6054 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
6058 expect("function pointer");
6061 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
6063 /* get return type */
6066 sa
= s
->next
; /* first parameter */
6067 nb_args
= regsize
= 0;
6069 /* compute first implicit argument if a structure is returned */
6070 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
6071 variadic
= (s
->f
.func_type
== FUNC_ELLIPSIS
);
6072 ret_nregs
= gfunc_sret(&s
->type
, variadic
, &ret
.type
,
6073 &ret_align
, ®size
);
6074 if (ret_nregs
<= 0) {
6075 /* get some space for the returned structure */
6076 size
= type_size(&s
->type
, &align
);
6077 #ifdef TCC_TARGET_ARM64
6078 /* On arm64, a small struct is return in registers.
6079 It is much easier to write it to memory if we know
6080 that we are allowed to write some extra bytes, so
6081 round the allocated space up to a power of 2: */
6083 while (size
& (size
- 1))
6084 size
= (size
| (size
- 1)) + 1;
6086 loc
= (loc
- size
) & -align
;
6088 ret
.r
= VT_LOCAL
| VT_LVAL
;
6089 /* pass it as 'int' to avoid structure arg passing
6091 vseti(VT_LOCAL
, loc
);
6092 #ifdef CONFIG_TCC_BCHECK
6093 if (tcc_state
->do_bounds_check
)
6107 if (ret_nregs
> 0) {
6108 /* return in register */
6110 PUT_R_RET(&ret
, ret
.type
.t
);
6115 gfunc_param_typed(s
, sa
);
6125 tcc_error("too few arguments to function");
6127 gfunc_call(nb_args
);
6129 if (ret_nregs
< 0) {
6130 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
6131 #ifdef TCC_TARGET_RISCV64
6132 arch_transfer_ret_regs(1);
6138 int rc
= reg_classes
[ret
.r
] & ~(RC_INT
| RC_FLOAT
);
6139 /* We assume that when a structure is returned in multiple
6140 registers, their classes are consecutive values of the
6143 for (r
= 0; r
< NB_REGS
; ++r
)
6144 if (reg_classes
[r
] & rc
)
6146 vsetc(&ret
.type
, r
, &ret
.c
);
6148 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
6151 /* handle packed struct return */
6152 if (((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) && ret_nregs
) {
6155 size
= type_size(&s
->type
, &align
);
6156 /* We're writing whole regs often, make sure there's enough
6157 space. Assume register size is power of 2. */
6158 size
= (size
+ regsize
- 1) & -regsize
;
6159 if (ret_align
> align
)
6161 loc
= (loc
- size
) & -align
;
6165 vset(&ret
.type
, VT_LOCAL
| VT_LVAL
, addr
+ offset
);
6169 if (--ret_nregs
== 0)
6173 vset(&s
->type
, VT_LOCAL
| VT_LVAL
, addr
);
6176 /* Promote char/short return values. This is matters only
6177 for calling function that were not compiled by TCC and
6178 only on some architectures. For those where it doesn't
6179 matter we expect things to be already promoted to int,
6181 t
= s
->type
.t
& VT_BTYPE
;
6182 if (t
== VT_BYTE
|| t
== VT_SHORT
|| t
== VT_BOOL
) {
6184 vtop
->r
|= BFVAL(VT_MUSTCAST
, 1);
6186 vtop
->type
.t
= VT_INT
;
6190 if (s
->f
.func_noreturn
) {
6192 tcc_tcov_block_end(tcc_state
, -1);
6201 #ifndef precedence_parser /* original top-down parser */
6203 static void expr_prod(void)
6208 while ((t
= tok
) == '*' || t
== '/' || t
== '%') {
6215 static void expr_sum(void)
6220 while ((t
= tok
) == '+' || t
== '-') {
6227 static void expr_shift(void)
6232 while ((t
= tok
) == TOK_SHL
|| t
== TOK_SAR
) {
6239 static void expr_cmp(void)
6244 while (((t
= tok
) >= TOK_ULE
&& t
<= TOK_GT
) ||
6245 t
== TOK_ULT
|| t
== TOK_UGE
) {
6252 static void expr_cmpeq(void)
6257 while ((t
= tok
) == TOK_EQ
|| t
== TOK_NE
) {
6264 static void expr_and(void)
6267 while (tok
== '&') {
6274 static void expr_xor(void)
6277 while (tok
== '^') {
6284 static void expr_or(void)
6287 while (tok
== '|') {
6294 static void expr_landor(int op
);
6296 static void expr_land(void)
6299 if (tok
== TOK_LAND
)
6303 static void expr_lor(void)
6310 # define expr_landor_next(op) op == TOK_LAND ? expr_or() : expr_land()
6311 #else /* defined precedence_parser */
6312 # define expr_landor_next(op) unary(), expr_infix(precedence(op) + 1)
6313 # define expr_lor() unary(), expr_infix(1)
6315 static int precedence(int tok
)
6318 case TOK_LOR
: return 1;
6319 case TOK_LAND
: return 2;
6323 case TOK_EQ
: case TOK_NE
: return 6;
6324 relat
: case TOK_ULT
: case TOK_UGE
: return 7;
6325 case TOK_SHL
: case TOK_SAR
: return 8;
6326 case '+': case '-': return 9;
6327 case '*': case '/': case '%': return 10;
6329 if (tok
>= TOK_ULE
&& tok
<= TOK_GT
)
6334 static unsigned char prec
[256];
6335 static void init_prec(void)
6338 for (i
= 0; i
< 256; i
++)
6339 prec
[i
] = precedence(i
);
6341 #define precedence(i) ((unsigned)i < 256 ? prec[i] : 0)
6343 static void expr_landor(int op
);
6345 static void expr_infix(int p
)
6348 while ((p2
= precedence(t
)) >= p
) {
6349 if (t
== TOK_LOR
|| t
== TOK_LAND
) {
6354 if (precedence(tok
) > p2
)
6363 /* Assuming vtop is a value used in a conditional context
6364 (i.e. compared with zero) return 0 if it's false, 1 if
6365 true and -1 if it can't be statically determined. */
6366 static int condition_3way(void)
6369 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
&&
6370 (!(vtop
->r
& VT_SYM
) || !vtop
->sym
->a
.weak
)) {
6372 gen_cast_s(VT_BOOL
);
6379 static void expr_landor(int op
)
6381 int t
= 0, cc
= 1, f
= 0, i
= op
== TOK_LAND
, c
;
6383 c
= f
? i
: condition_3way();
6385 save_regs(1), cc
= 0;
6387 nocode_wanted
++, f
= 1;
6395 expr_landor_next(op
);
6407 static int is_cond_bool(SValue
*sv
)
6409 if ((sv
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
6410 && (sv
->type
.t
& VT_BTYPE
) == VT_INT
)
6411 return (unsigned)sv
->c
.i
< 2;
6412 if (sv
->r
== VT_CMP
)
6417 static void expr_cond(void)
6419 int tt
, u
, r1
, r2
, rc
, t1
, t2
, islv
, c
, g
;
6426 c
= condition_3way();
6427 g
= (tok
== ':' && gnu_ext
);
6437 /* needed to avoid having different registers saved in
6449 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
6450 mk_pointer(&vtop
->type
);
6451 sv
= *vtop
; /* save value to handle it later */
6452 vtop
--; /* no vpop so that FP stack is not flushed */
6469 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
6470 mk_pointer(&vtop
->type
);
6472 /* cast operands to correct type according to ISOC rules */
6473 if (!combine_types(&type
, &sv
, vtop
, '?'))
6474 type_incompatibility_error(&sv
.type
, &vtop
->type
,
6475 "type mismatch in conditional expression (have '%s' and '%s')");
6477 if (c
< 0 && is_cond_bool(vtop
) && is_cond_bool(&sv
)) {
6478 /* optimize "if (f ? a > b : c || d) ..." for example, where normally
6479 "a < b" and "c || d" would be forced to "(int)0/1" first, whereas
6480 this code jumps directly to the if's then/else branches. */
6485 /* combine jump targets of 2nd op with VT_CMP of 1st op */
6489 // tcc_warning("two conditions expr_cond");
6493 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
6494 that `(expr ? a : b).mem` does not error with "lvalue expected" */
6495 islv
= (vtop
->r
& VT_LVAL
) && (sv
.r
& VT_LVAL
) && VT_STRUCT
== (type
.t
& VT_BTYPE
);
6497 /* now we convert second operand */
6501 mk_pointer(&vtop
->type
);
6503 } else if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
6507 rc
= RC_TYPE(type
.t
);
6508 /* for long longs, we use fixed registers to avoid having
6509 to handle a complicated move */
6510 if (USING_TWO_WORDS(type
.t
))
6511 rc
= RC_RET(type
.t
);
6522 /* this is horrible, but we must also convert first
6528 mk_pointer(&vtop
->type
);
6530 } else if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
6536 move_reg(r2
, r1
, islv
? VT_PTR
: type
.t
);
6546 static void expr_eq(void)
6551 if ((t
= tok
) == '=' || TOK_ASSIGN(t
)) {
6559 gen_op(TOK_ASSIGN_OP(t
));
6565 ST_FUNC
void gexpr(void)
6571 constant_p
&= (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
&&
6572 !((vtop
->r
& VT_SYM
) && vtop
->sym
->a
.addrtaken
);
6578 /* parse a constant expression and return value in vtop. */
6579 static void expr_const1(void)
6581 nocode_wanted
+= CONST_WANTED_BIT
;
6583 nocode_wanted
-= CONST_WANTED_BIT
;
6586 /* parse an integer constant and return its value. */
6587 static inline int64_t expr_const64(void)
6591 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
| VT_NONCONST
)) != VT_CONST
)
6592 expect("constant expression");
6598 /* parse an integer constant and return its value.
6599 Complain if it doesn't fit 32bit (signed or unsigned). */
6600 ST_FUNC
int expr_const(void)
6603 int64_t wc
= expr_const64();
6605 if (c
!= wc
&& (unsigned)c
!= wc
)
6606 tcc_error("constant exceeds 32 bit");
6610 /* ------------------------------------------------------------------------- */
6611 /* return from function */
6613 #ifndef TCC_TARGET_ARM64
6614 static void gfunc_return(CType
*func_type
)
6616 if ((func_type
->t
& VT_BTYPE
) == VT_STRUCT
) {
6617 CType type
, ret_type
;
6618 int ret_align
, ret_nregs
, regsize
;
6619 ret_nregs
= gfunc_sret(func_type
, func_var
, &ret_type
,
6620 &ret_align
, ®size
);
6621 if (ret_nregs
< 0) {
6622 #ifdef TCC_TARGET_RISCV64
6623 arch_transfer_ret_regs(0);
6625 } else if (0 == ret_nregs
) {
6626 /* if returning structure, must copy it to implicit
6627 first pointer arg location */
6630 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
6633 /* copy structure value to pointer */
6636 /* returning structure packed into registers */
6637 int size
, addr
, align
, rc
, n
;
6638 size
= type_size(func_type
,&align
);
6639 if ((align
& (ret_align
- 1))
6640 && ((vtop
->r
& VT_VALMASK
) < VT_CONST
/* pointer to struct */
6641 || (vtop
->c
.i
& (ret_align
- 1))
6643 loc
= (loc
- size
) & -ret_align
;
6646 vset(&type
, VT_LOCAL
| VT_LVAL
, addr
);
6650 vset(&ret_type
, VT_LOCAL
| VT_LVAL
, addr
);
6652 vtop
->type
= ret_type
;
6653 rc
= RC_RET(ret_type
.t
);
6654 //printf("struct return: n:%d t:%02x rc:%02x\n", ret_nregs, ret_type.t, rc);
6655 for (n
= ret_nregs
; --n
> 0;) {
6659 incr_offset(regsize
);
6660 /* We assume that when a structure is returned in multiple
6661 registers, their classes are consecutive values of the
6666 vtop
-= ret_nregs
- 1;
6669 gv(RC_RET(func_type
->t
));
6671 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6675 static void check_func_return(void)
6677 if ((func_vt
.t
& VT_BTYPE
) == VT_VOID
)
6679 if (!strcmp (funcname
, "main")
6680 && (func_vt
.t
& VT_BTYPE
) == VT_INT
) {
6681 /* main returns 0 by default */
6683 gen_assign_cast(&func_vt
);
6684 gfunc_return(&func_vt
);
6686 tcc_warning("function might return no value: '%s'", funcname
);
6690 /* ------------------------------------------------------------------------- */
6693 static int case_cmpi(const void *pa
, const void *pb
)
6695 int64_t a
= (*(struct case_t
**) pa
)->v1
;
6696 int64_t b
= (*(struct case_t
**) pb
)->v1
;
6697 return a
< b
? -1 : a
> b
;
6700 static int case_cmpu(const void *pa
, const void *pb
)
6702 uint64_t a
= (uint64_t)(*(struct case_t
**) pa
)->v1
;
6703 uint64_t b
= (uint64_t)(*(struct case_t
**) pb
)->v1
;
6704 return a
< b
? -1 : a
> b
;
6707 static void gtst_addr(int t
, int a
)
6709 gsym_addr(gvtst(0, t
), a
);
6712 static void gcase(struct case_t
**base
, int len
, int *bsym
)
6716 int ll
= (vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
;
6733 gtst_addr(0, p
->sym
); /* v1 <= x <= v2 */
6735 gcase(base
, len
/2, bsym
);
6739 base
+= e
; len
-= e
;
6749 if (p
->v1
== p
->v2
) {
6751 gtst_addr(0, p
->sym
);
6761 gtst_addr(0, p
->sym
);
6765 *bsym
= gjmp(*bsym
);
6768 /* ------------------------------------------------------------------------- */
6769 /* __attribute__((cleanup(fn))) */
6771 static void try_call_scope_cleanup(Sym
*stop
)
6773 Sym
*cls
= cur_scope
->cl
.s
;
6775 for (; cls
!= stop
; cls
= cls
->ncl
) {
6776 Sym
*fs
= cls
->next
;
6777 Sym
*vs
= cls
->prev_tok
;
6779 vpushsym(&fs
->type
, fs
);
6780 vset(&vs
->type
, vs
->r
, vs
->c
);
6782 mk_pointer(&vtop
->type
);
6788 static void try_call_cleanup_goto(Sym
*cleanupstate
)
6793 if (!cur_scope
->cl
.s
)
6796 /* search NCA of both cleanup chains given parents and initial depth */
6797 ocd
= cleanupstate
? cleanupstate
->v
& ~SYM_FIELD
: 0;
6798 for (ccd
= cur_scope
->cl
.n
, oc
= cleanupstate
; ocd
> ccd
; --ocd
, oc
= oc
->ncl
)
6800 for (cc
= cur_scope
->cl
.s
; ccd
> ocd
; --ccd
, cc
= cc
->ncl
)
6802 for (; cc
!= oc
; cc
= cc
->ncl
, oc
= oc
->ncl
, --ccd
)
6805 try_call_scope_cleanup(cc
);
6808 /* call 'func' for each __attribute__((cleanup(func))) */
6809 static void block_cleanup(struct scope
*o
)
6813 for (pg
= &pending_gotos
; (g
= *pg
) && g
->c
> o
->cl
.n
;) {
6814 if (g
->prev_tok
->r
& LABEL_FORWARD
) {
6819 try_call_scope_cleanup(o
->cl
.s
);
6820 pcl
->jnext
= gjmp(0);
6822 goto remove_pending
;
6832 try_call_scope_cleanup(o
->cl
.s
);
6835 /* ------------------------------------------------------------------------- */
6838 static void vla_restore(int loc
)
6841 gen_vla_sp_restore(loc
);
6844 static void vla_leave(struct scope
*o
)
6846 struct scope
*c
= cur_scope
, *v
= NULL
;
6847 for (; c
!= o
&& c
; c
= c
->prev
)
6851 vla_restore(v
->vla
.locorig
);
6854 /* ------------------------------------------------------------------------- */
6857 static void new_scope(struct scope
*o
)
6859 /* copy and link previous scope */
6861 o
->prev
= cur_scope
;
6863 cur_scope
->vla
.num
= 0;
6865 /* record local declaration stack position */
6866 o
->lstk
= local_stack
;
6867 o
->llstk
= local_label_stack
;
6871 static void prev_scope(struct scope
*o
, int is_expr
)
6875 if (o
->cl
.s
!= o
->prev
->cl
.s
)
6876 block_cleanup(o
->prev
);
6878 /* pop locally defined labels */
6879 label_pop(&local_label_stack
, o
->llstk
, is_expr
);
6881 /* In the is_expr case (a statement expression is finished here),
6882 vtop might refer to symbols on the local_stack. Either via the
6883 type or via vtop->sym. We can't pop those nor any that in turn
6884 might be referred to. To make it easier we don't roll back
6885 any symbols in that case; some upper level call to block() will
6886 do that. We do have to remove such symbols from the lookup
6887 tables, though. sym_pop will do that. */
6889 /* pop locally defined symbols */
6890 pop_local_syms(o
->lstk
, is_expr
);
6891 cur_scope
= o
->prev
;
6895 /* leave a scope via break/continue(/goto) */
6896 static void leave_scope(struct scope
*o
)
6900 try_call_scope_cleanup(o
->cl
.s
);
6904 /* short versiona for scopes with 'if/do/while/switch' which can
6905 declare only types (of struct/union/enum) */
6906 static void new_scope_s(struct scope
*o
)
6908 o
->lstk
= local_stack
;
6912 static void prev_scope_s(struct scope
*o
)
6914 sym_pop(&local_stack
, o
->lstk
, 0);
6918 /* ------------------------------------------------------------------------- */
6919 /* call block from 'for do while' loops */
6921 static void lblock(int *bsym
, int *csym
)
6923 struct scope
*lo
= loop_scope
, *co
= cur_scope
;
6924 int *b
= co
->bsym
, *c
= co
->csym
;
6938 static void block(int is_expr
)
6940 int a
, b
, c
, d
, e
, t
;
6945 /* default return value is (void) */
6947 vtop
->type
.t
= VT_VOID
;
6952 /* If the token carries a value, next() might destroy it. Only with
6953 invalid code such as f(){"123"4;} */
6954 if (TOK_HAS_VALUE(t
))
6959 tcc_tcov_check_line (tcc_state
, 0), tcc_tcov_block_begin (tcc_state
);
6968 if (tok
== TOK_ELSE
) {
6973 gsym(d
); /* patch else jmp */
6979 } else if (t
== TOK_WHILE
) {
6993 } else if (t
== '{') {
6995 tcc_debug_stabn(tcc_state
, N_LBRAC
, ind
- func_ind
);
6998 /* handle local labels declarations */
6999 while (tok
== TOK_LABEL
) {
7002 if (tok
< TOK_UIDENT
)
7003 expect("label identifier");
7004 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
7006 } while (tok
== ',');
7010 while (tok
!= '}') {
7019 prev_scope(&o
, is_expr
);
7021 tcc_debug_stabn(tcc_state
, N_RBRAC
, ind
- func_ind
);
7024 else if (!nocode_wanted
)
7025 check_func_return();
7027 } else if (t
== TOK_RETURN
) {
7028 b
= (func_vt
.t
& VT_BTYPE
) != VT_VOID
;
7032 gen_assign_cast(&func_vt
);
7034 if (vtop
->type
.t
!= VT_VOID
)
7035 tcc_warning("void function returns a value");
7039 tcc_warning("'return' with no value");
7042 leave_scope(root_scope
);
7044 gfunc_return(&func_vt
);
7046 /* jump unless last stmt in top-level block */
7047 if (tok
!= '}' || local_scope
!= 1)
7050 tcc_tcov_block_end (tcc_state
, -1);
7053 } else if (t
== TOK_BREAK
) {
7055 if (!cur_scope
->bsym
)
7056 tcc_error("cannot break");
7057 if (cur_switch
&& cur_scope
->bsym
== cur_switch
->bsym
)
7058 leave_scope(cur_switch
->scope
);
7060 leave_scope(loop_scope
);
7061 *cur_scope
->bsym
= gjmp(*cur_scope
->bsym
);
7064 } else if (t
== TOK_CONTINUE
) {
7066 if (!cur_scope
->csym
)
7067 tcc_error("cannot continue");
7068 leave_scope(loop_scope
);
7069 *cur_scope
->csym
= gjmp(*cur_scope
->csym
);
7072 } else if (t
== TOK_FOR
) {
7077 /* c99 for-loop init decl? */
7078 if (!decl(VT_JMP
)) {
7079 /* no, regular for-loop init expr */
7107 } else if (t
== TOK_DO
) {
7123 } else if (t
== TOK_SWITCH
) {
7124 struct switch_t
*sw
;
7126 sw
= tcc_mallocz(sizeof *sw
);
7128 sw
->scope
= cur_scope
;
7129 sw
->prev
= cur_switch
;
7130 sw
->nocode_wanted
= nocode_wanted
;
7137 sw
->sv
= *vtop
--; /* save switch value */
7139 b
= gjmp(0); /* jump to first case */
7141 a
= gjmp(a
); /* add implicit break */
7146 if (sw
->nocode_wanted
)
7148 if (sw
->sv
.type
.t
& VT_UNSIGNED
)
7149 qsort(sw
->p
, sw
->n
, sizeof(void*), case_cmpu
);
7151 qsort(sw
->p
, sw
->n
, sizeof(void*), case_cmpi
);
7152 for (b
= 1; b
< sw
->n
; b
++)
7153 if (sw
->sv
.type
.t
& VT_UNSIGNED
7154 ? (uint64_t)sw
->p
[b
- 1]->v2
>= (uint64_t)sw
->p
[b
]->v1
7155 : sw
->p
[b
- 1]->v2
>= sw
->p
[b
]->v1
)
7156 tcc_error("duplicate case value");
7159 d
= 0, gcase(sw
->p
, sw
->n
, &d
);
7162 gsym_addr(d
, sw
->def_sym
);
7169 dynarray_reset(&sw
->p
, &sw
->n
);
7170 cur_switch
= sw
->prev
;
7173 } else if (t
== TOK_CASE
) {
7174 struct case_t
*cr
= tcc_malloc(sizeof(struct case_t
));
7177 cr
->v1
= cr
->v2
= expr_const64();
7178 if (gnu_ext
&& tok
== TOK_DOTS
) {
7180 cr
->v2
= expr_const64();
7181 if ((!(cur_switch
->sv
.type
.t
& VT_UNSIGNED
) && cr
->v2
< cr
->v1
)
7182 || (cur_switch
->sv
.type
.t
& VT_UNSIGNED
&& (uint64_t)cr
->v2
< (uint64_t)cr
->v1
))
7183 tcc_warning("empty case range");
7185 /* case and default are unreachable from a switch under nocode_wanted */
7186 if (!cur_switch
->nocode_wanted
)
7188 dynarray_add(&cur_switch
->p
, &cur_switch
->n
, cr
);
7191 goto block_after_label
;
7193 } else if (t
== TOK_DEFAULT
) {
7196 if (cur_switch
->def_sym
)
7197 tcc_error("too many 'default'");
7198 cur_switch
->def_sym
= cur_switch
->nocode_wanted
? 1 : gind();
7201 goto block_after_label
;
7203 } else if (t
== TOK_GOTO
) {
7204 vla_restore(cur_scope
->vla
.locorig
);
7205 if (tok
== '*' && gnu_ext
) {
7209 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
7213 } else if (tok
>= TOK_UIDENT
) {
7214 s
= label_find(tok
);
7215 /* put forward definition if needed */
7217 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7218 else if (s
->r
== LABEL_DECLARED
)
7219 s
->r
= LABEL_FORWARD
;
7221 if (s
->r
& LABEL_FORWARD
) {
7222 /* start new goto chain for cleanups, linked via label->next */
7223 if (cur_scope
->cl
.s
&& !nocode_wanted
) {
7224 sym_push2(&pending_gotos
, SYM_FIELD
, 0, cur_scope
->cl
.n
);
7225 pending_gotos
->prev_tok
= s
;
7226 s
= sym_push2(&s
->next
, SYM_FIELD
, 0, 0);
7227 pending_gotos
->next
= s
;
7229 s
->jnext
= gjmp(s
->jnext
);
7231 try_call_cleanup_goto(s
->cleanupstate
);
7232 gjmp_addr(s
->jnext
);
7237 expect("label identifier");
7241 } else if (t
== TOK_ASM1
|| t
== TOK_ASM2
|| t
== TOK_ASM3
) {
7245 if (tok
== ':' && t
>= TOK_UIDENT
) {
7250 if (s
->r
== LABEL_DEFINED
)
7251 tcc_error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
7252 s
->r
= LABEL_DEFINED
;
7254 Sym
*pcl
; /* pending cleanup goto */
7255 for (pcl
= s
->next
; pcl
; pcl
= pcl
->prev
)
7257 sym_pop(&s
->next
, NULL
, 0);
7261 s
= label_push(&global_label_stack
, t
, LABEL_DEFINED
);
7264 s
->cleanupstate
= cur_scope
->cl
.s
;
7268 /* Accept attributes after labels (e.g. 'unused') */
7269 AttributeDef ad_tmp
;
7270 parse_attribute(&ad_tmp
);
7273 tcc_tcov_reset_ind(tcc_state
);
7274 vla_restore(cur_scope
->vla
.loc
);
7277 /* we accept this, but it is a mistake */
7278 tcc_warning_c(warn_all
)("deprecated use of label at end of compound statement");
7281 /* expression case */
7298 tcc_tcov_check_line (tcc_state
, 0), tcc_tcov_block_end (tcc_state
, 0);
7301 /* This skips over a stream of tokens containing balanced {} and ()
7302 pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started
7303 with a '{'). If STR then allocates and stores the skipped tokens
7304 in *STR. This doesn't check if () and {} are nested correctly,
7305 i.e. "({)}" is accepted. */
7306 static void skip_or_save_block(TokenString
**str
)
7308 int braces
= tok
== '{';
7311 *str
= tok_str_alloc();
7323 if (str
|| level
> 0)
7324 tcc_error("unexpected end of file");
7329 tok_str_add_tok(*str
);
7331 if (t
== '{' || t
== '(' || t
== '[') {
7333 } else if (t
== '}' || t
== ')' || t
== ']') {
7335 if (level
== 0 && braces
&& t
== '}')
7340 tok_str_add(*str
, -1);
7341 tok_str_add(*str
, 0);
7345 #define EXPR_CONST 1
7348 static void parse_init_elem(int expr_type
)
7350 int saved_global_expr
;
7353 /* compound literals must be allocated globally in this case */
7354 saved_global_expr
= global_expr
;
7357 global_expr
= saved_global_expr
;
7358 /* NOTE: symbols are accepted, as well as lvalue for anon symbols
7359 (compound literals). */
7360 if (((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
7361 && ((vtop
->r
& (VT_SYM
|VT_LVAL
)) != (VT_SYM
|VT_LVAL
)
7362 || vtop
->sym
->v
< SYM_FIRST_ANOM
))
7363 #ifdef TCC_TARGET_PE
7364 || ((vtop
->r
& VT_SYM
) && vtop
->sym
->a
.dllimport
)
7367 tcc_error("initializer element is not constant");
7376 static void init_assert(init_params
*p
, int offset
)
7378 if (p
->sec
? !NODATA_WANTED
&& offset
> p
->sec
->data_offset
7379 : !nocode_wanted
&& offset
> p
->local_offset
)
7380 tcc_internal_error("initializer overflow");
7383 #define init_assert(sec, offset)
7386 /* put zeros for variable based init */
7387 static void init_putz(init_params
*p
, unsigned long c
, int size
)
7389 init_assert(p
, c
+ size
);
7391 /* nothing to do because globals are already set to zero */
7393 vpush_helper_func(TOK_memset
);
7395 #ifdef TCC_TARGET_ARM
7407 #define DIF_SIZE_ONLY 2
7408 #define DIF_HAVE_ELEM 4
7411 /* delete relocations for specified range c ... c + size. Unfortunatly
7412 in very special cases, relocations may occur unordered */
7413 static void decl_design_delrels(Section
*sec
, int c
, int size
)
7415 ElfW_Rel
*rel
, *rel2
, *rel_end
;
7416 if (!sec
|| !sec
->reloc
)
7418 rel
= rel2
= (ElfW_Rel
*)sec
->reloc
->data
;
7419 rel_end
= (ElfW_Rel
*)(sec
->reloc
->data
+ sec
->reloc
->data_offset
);
7420 while (rel
< rel_end
) {
7421 if (rel
->r_offset
>= c
&& rel
->r_offset
< c
+ size
) {
7422 sec
->reloc
->data_offset
-= sizeof *rel
;
7425 memcpy(rel2
, rel
, sizeof *rel
);
7432 static void decl_design_flex(init_params
*p
, Sym
*ref
, int index
)
7434 if (ref
== p
->flex_array_ref
) {
7435 if (index
>= ref
->c
)
7437 } else if (ref
->c
< 0)
7438 tcc_error("flexible array has zero size in this context");
7441 /* t is the array or struct type. c is the array or struct
7442 address. cur_field is the pointer to the current
7443 field, for arrays the 'c' member contains the current start
7444 index. 'flags' is as in decl_initializer.
7445 'al' contains the already initialized length of the
7446 current container (starting at c). This returns the new length of that. */
7447 static int decl_designator(init_params
*p
, CType
*type
, unsigned long c
,
7448 Sym
**cur_field
, int flags
, int al
)
7451 int index
, index_last
, align
, l
, nb_elems
, elem_size
;
7452 unsigned long corig
= c
;
7457 if (flags
& DIF_HAVE_ELEM
)
7460 if (gnu_ext
&& tok
>= TOK_UIDENT
) {
7467 /* NOTE: we only support ranges for last designator */
7468 while (nb_elems
== 1 && (tok
== '[' || tok
== '.')) {
7470 if (!(type
->t
& VT_ARRAY
))
7471 expect("array type");
7473 index
= index_last
= expr_const();
7474 if (tok
== TOK_DOTS
&& gnu_ext
) {
7476 index_last
= expr_const();
7480 decl_design_flex(p
, s
, index_last
);
7481 if (index
< 0 || index_last
>= s
->c
|| index_last
< index
)
7482 tcc_error("index exceeds array bounds or range is empty");
7484 (*cur_field
)->c
= index_last
;
7485 type
= pointed_type(type
);
7486 elem_size
= type_size(type
, &align
);
7487 c
+= index
* elem_size
;
7488 nb_elems
= index_last
- index
+ 1;
7495 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
7496 expect("struct/union type");
7498 f
= find_field(type
, l
, &cumofs
);
7509 } else if (!gnu_ext
) {
7514 if (type
->t
& VT_ARRAY
) {
7515 index
= (*cur_field
)->c
;
7517 decl_design_flex(p
, s
, index
);
7519 tcc_error("too many initializers");
7520 type
= pointed_type(type
);
7521 elem_size
= type_size(type
, &align
);
7522 c
+= index
* elem_size
;
7525 /* Skip bitfield padding. Also with size 32 and 64. */
7526 while (f
&& (f
->v
& SYM_FIRST_ANOM
) &&
7527 is_integer_btype(f
->type
.t
& VT_BTYPE
))
7528 *cur_field
= f
= f
->next
;
7530 tcc_error("too many initializers");
7536 if (!elem_size
) /* for structs */
7537 elem_size
= type_size(type
, &align
);
7539 /* Using designators the same element can be initialized more
7540 than once. In that case we need to delete possibly already
7541 existing relocations. */
7542 if (!(flags
& DIF_SIZE_ONLY
) && c
- corig
< al
) {
7543 decl_design_delrels(p
->sec
, c
, elem_size
* nb_elems
);
7544 flags
&= ~DIF_CLEAR
; /* mark stack dirty too */
7547 decl_initializer(p
, type
, c
, flags
& ~DIF_FIRST
);
7549 if (!(flags
& DIF_SIZE_ONLY
) && nb_elems
> 1) {
7553 if (p
->sec
|| (type
->t
& VT_ARRAY
)) {
7554 /* make init_putv/vstore believe it were a struct */
7556 t1
.t
= VT_STRUCT
, t1
.ref
= &aref
;
7560 vpush_ref(type
, p
->sec
, c
, elem_size
);
7562 vset(type
, VT_LOCAL
|VT_LVAL
, c
);
7563 for (i
= 1; i
< nb_elems
; i
++) {
7565 init_putv(p
, type
, c
+ elem_size
* i
);
7570 c
+= nb_elems
* elem_size
;
7576 /* store a value or an expression directly in global data or in local array */
7577 static void init_putv(init_params
*p
, CType
*type
, unsigned long c
)
7583 Section
*sec
= p
->sec
;
7587 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
7589 size
= type_size(type
, &align
);
7590 if (type
->t
& VT_BITFIELD
)
7591 size
= (BIT_POS(type
->t
) + BIT_SIZE(type
->t
) + 7) / 8;
7592 init_assert(p
, c
+ size
);
7595 /* XXX: not portable */
7596 /* XXX: generate error if incorrect relocation */
7597 gen_assign_cast(&dtype
);
7598 bt
= type
->t
& VT_BTYPE
;
7600 if ((vtop
->r
& VT_SYM
)
7602 && (bt
!= (PTR_SIZE
== 8 ? VT_LLONG
: VT_INT
)
7603 || (type
->t
& VT_BITFIELD
))
7604 && !((vtop
->r
& VT_CONST
) && vtop
->sym
->v
>= SYM_FIRST_ANOM
)
7606 tcc_error("initializer element is not computable at load time");
7608 if (NODATA_WANTED
) {
7613 ptr
= sec
->data
+ c
;
7616 /* XXX: make code faster ? */
7617 if ((vtop
->r
& (VT_SYM
|VT_CONST
)) == (VT_SYM
|VT_CONST
) &&
7618 vtop
->sym
->v
>= SYM_FIRST_ANOM
&&
7619 /* XXX This rejects compound literals like
7620 '(void *){ptr}'. The problem is that '&sym' is
7621 represented the same way, which would be ruled out
7622 by the SYM_FIRST_ANOM check above, but also '"string"'
7623 in 'char *p = "string"' is represented the same
7624 with the type being VT_PTR and the symbol being an
7625 anonymous one. That is, there's no difference in vtop
7626 between '(void *){x}' and '&(void *){x}'. Ignore
7627 pointer typed entities here. Hopefully no real code
7628 will ever use compound literals with scalar type. */
7629 (vtop
->type
.t
& VT_BTYPE
) != VT_PTR
) {
7630 /* These come from compound literals, memcpy stuff over. */
7634 esym
= elfsym(vtop
->sym
);
7635 ssec
= tcc_state
->sections
[esym
->st_shndx
];
7636 memmove (ptr
, ssec
->data
+ esym
->st_value
+ (int)vtop
->c
.i
, size
);
7638 /* We need to copy over all memory contents, and that
7639 includes relocations. Use the fact that relocs are
7640 created it order, so look from the end of relocs
7641 until we hit one before the copied region. */
7642 unsigned long relofs
= ssec
->reloc
->data_offset
;
7643 while (relofs
>= sizeof(*rel
)) {
7644 relofs
-= sizeof(*rel
);
7645 rel
= (ElfW_Rel
*)(ssec
->reloc
->data
+ relofs
);
7646 if (rel
->r_offset
>= esym
->st_value
+ size
)
7648 if (rel
->r_offset
< esym
->st_value
)
7650 put_elf_reloca(symtab_section
, sec
,
7651 c
+ rel
->r_offset
- esym
->st_value
,
7652 ELFW(R_TYPE
)(rel
->r_info
),
7653 ELFW(R_SYM
)(rel
->r_info
),
7663 if (type
->t
& VT_BITFIELD
) {
7664 int bit_pos
, bit_size
, bits
, n
;
7665 unsigned char *p
, v
, m
;
7666 bit_pos
= BIT_POS(vtop
->type
.t
);
7667 bit_size
= BIT_SIZE(vtop
->type
.t
);
7668 p
= (unsigned char*)ptr
+ (bit_pos
>> 3);
7669 bit_pos
&= 7, bits
= 0;
7674 v
= val
>> bits
<< bit_pos
;
7675 m
= ((1 << n
) - 1) << bit_pos
;
7676 *p
= (*p
& ~m
) | (v
& m
);
7677 bits
+= n
, bit_size
-= n
, bit_pos
= 0, ++p
;
7682 *(char *)ptr
= val
!= 0;
7688 write16le(ptr
, val
);
7691 write32le(ptr
, val
);
7694 write64le(ptr
, val
);
7697 #if defined TCC_IS_NATIVE_387
7698 /* Host and target platform may be different but both have x87.
7699 On windows, tcc does not use VT_LDOUBLE, except when it is a
7700 cross compiler. In this case a mingw gcc as host compiler
7701 comes here with 10-byte long doubles, while msvc or tcc won't.
7702 tcc itself can still translate by asm.
7703 In any case we avoid possibly random bytes 11 and 12.
7705 if (sizeof (long double) >= 10)
7706 memcpy(ptr
, &vtop
->c
.ld
, 10);
7708 else if (sizeof (long double) == sizeof (double))
7709 __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr
) : "m" (vtop
->c
.ld
));
7713 /* For other platforms it should work natively, but may not work
7714 for cross compilers */
7715 if (sizeof(long double) == LDOUBLE_SIZE
)
7716 memcpy(ptr
, &vtop
->c
.ld
, LDOUBLE_SIZE
);
7717 else if (sizeof(double) == LDOUBLE_SIZE
)
7718 *(double*)ptr
= (double)vtop
->c
.ld
;
7719 else if (0 == memcmp(ptr
, &vtop
->c
.ld
, LDOUBLE_SIZE
))
7720 ; /* nothing to do for 0.0 */
7721 #ifndef TCC_CROSS_TEST
7723 tcc_error("can't cross compile long double constants");
7728 /* intptr_t may need a reloc too, see tcctest.c:relocation_test() */
7731 if (vtop
->r
& VT_SYM
)
7732 greloca(sec
, vtop
->sym
, c
, R_DATA_PTR
, val
);
7734 write64le(ptr
, val
);
7737 write32le(ptr
, val
);
7741 write64le(ptr
, val
);
7745 if (vtop
->r
& VT_SYM
)
7746 greloc(sec
, vtop
->sym
, c
, R_DATA_PTR
);
7747 write32le(ptr
, val
);
7751 //tcc_internal_error("unexpected type");
7757 vset(&dtype
, VT_LOCAL
|VT_LVAL
, c
);
7764 /* 't' contains the type and storage info. 'c' is the offset of the
7765 object in section 'sec'. If 'sec' is NULL, it means stack based
7766 allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi
7767 dimension implicit array init handling). 'flags & DIF_SIZE_ONLY' is true if
7768 size only evaluation is wanted (only for arrays). */
7769 static void decl_initializer(init_params
*p
, CType
*type
, unsigned long c
, int flags
)
7771 int len
, n
, no_oblock
, i
;
7777 /* generate line number info */
7778 if (debug_modes
&& !p
->sec
)
7779 tcc_debug_line(tcc_state
), tcc_tcov_check_line (tcc_state
, 1);
7781 if (!(flags
& DIF_HAVE_ELEM
) && tok
!= '{' &&
7782 /* In case of strings we have special handling for arrays, so
7783 don't consume them as initializer value (which would commit them
7784 to some anonymous symbol). */
7785 tok
!= TOK_LSTR
&& tok
!= TOK_STR
&&
7786 (!(flags
& DIF_SIZE_ONLY
)
7787 /* a struct may be initialized from a struct of same type, as in
7788 struct {int x,y;} a = {1,2}, b = {3,4}, c[] = {a,b};
7789 In that case we need to parse the element in order to check
7790 it for compatibility below */
7791 || (type
->t
& VT_BTYPE
) == VT_STRUCT
)
7793 int ncw_prev
= nocode_wanted
;
7794 if ((flags
& DIF_SIZE_ONLY
) && !p
->sec
)
7796 parse_init_elem(!p
->sec
? EXPR_ANY
: EXPR_CONST
);
7797 nocode_wanted
= ncw_prev
;
7798 flags
|= DIF_HAVE_ELEM
;
7801 if (type
->t
& VT_ARRAY
) {
7803 if (((flags
& DIF_FIRST
) && tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
7811 t1
= pointed_type(type
);
7812 size1
= type_size(t1
, &align1
);
7814 /* only parse strings here if correct type (otherwise: handle
7815 them as ((w)char *) expressions */
7816 if ((tok
== TOK_LSTR
&&
7817 #ifdef TCC_TARGET_PE
7818 (t1
->t
& VT_BTYPE
) == VT_SHORT
&& (t1
->t
& VT_UNSIGNED
)
7820 (t1
->t
& VT_BTYPE
) == VT_INT
7822 ) || (tok
== TOK_STR
&& (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
7824 cstr_reset(&initstr
);
7825 if (size1
!= (tok
== TOK_STR
? 1 : sizeof(nwchar_t
)))
7826 tcc_error("unhandled string literal merging");
7827 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
7829 initstr
.size
-= size1
;
7831 len
+= tokc
.str
.size
;
7833 len
+= tokc
.str
.size
/ sizeof(nwchar_t
);
7835 cstr_cat(&initstr
, tokc
.str
.data
, tokc
.str
.size
);
7838 if (tok
!= ')' && tok
!= '}' && tok
!= ',' && tok
!= ';'
7839 && tok
!= TOK_EOF
) {
7840 /* Not a lone literal but part of a bigger expression. */
7841 unget_tok(size1
== 1 ? TOK_STR
: TOK_LSTR
);
7842 tokc
.str
.size
= initstr
.size
;
7843 tokc
.str
.data
= initstr
.data
;
7847 decl_design_flex(p
, s
, len
);
7848 if (!(flags
& DIF_SIZE_ONLY
)) {
7853 tcc_warning("initializer-string for array is too long");
7854 /* in order to go faster for common case (char
7855 string in global variable, we handle it
7857 if (p
->sec
&& size1
== 1) {
7858 init_assert(p
, c
+ nb
);
7860 memcpy(p
->sec
->data
+ c
, initstr
.data
, nb
);
7864 /* only add trailing zero if enough storage (no
7865 warning in this case since it is standard) */
7866 if (flags
& DIF_CLEAR
)
7869 init_putz(p
, c
+ i
* size1
, (n
- i
) * size1
);
7873 } else if (size1
== 1)
7874 ch
= ((unsigned char *)initstr
.data
)[i
];
7876 ch
= ((nwchar_t
*)initstr
.data
)[i
];
7878 init_putv(p
, t1
, c
+ i
* size1
);
7889 /* zero memory once in advance */
7890 if (!(flags
& (DIF_CLEAR
| DIF_SIZE_ONLY
))) {
7891 init_putz(p
, c
, n
*size1
);
7896 /* GNU extension: if the initializer is empty for a flex array,
7897 it's size is zero. We won't enter the loop, so set the size
7899 decl_design_flex(p
, s
, len
);
7900 while (tok
!= '}' || (flags
& DIF_HAVE_ELEM
)) {
7901 len
= decl_designator(p
, type
, c
, &f
, flags
, len
);
7902 flags
&= ~DIF_HAVE_ELEM
;
7903 if (type
->t
& VT_ARRAY
) {
7905 /* special test for multi dimensional arrays (may not
7906 be strictly correct if designators are used at the
7908 if (no_oblock
&& len
>= n
*size1
)
7911 if (s
->type
.t
== VT_UNION
)
7915 if (no_oblock
&& f
== NULL
)
7927 } else if ((flags
& DIF_HAVE_ELEM
)
7928 /* Use i_c_parameter_t, to strip toplevel qualifiers.
7929 The source type might have VT_CONSTANT set, which is
7930 of course assignable to non-const elements. */
7931 && is_compatible_unqualified_types(type
, &vtop
->type
)) {
7934 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
) {
7936 if ((flags
& DIF_FIRST
) || tok
== '{') {
7946 } else if (tok
== '{') {
7947 if (flags
& DIF_HAVE_ELEM
)
7950 decl_initializer(p
, type
, c
, flags
& ~DIF_HAVE_ELEM
);
7953 } else one_elem
: if ((flags
& DIF_SIZE_ONLY
)) {
7954 /* If we supported only ISO C we wouldn't have to accept calling
7955 this on anything than an array if DIF_SIZE_ONLY (and even then
7956 only on the outermost level, so no recursion would be needed),
7957 because initializing a flex array member isn't supported.
7958 But GNU C supports it, so we need to recurse even into
7959 subfields of structs and arrays when DIF_SIZE_ONLY is set. */
7960 /* just skip expression */
7961 if (flags
& DIF_HAVE_ELEM
)
7964 skip_or_save_block(NULL
);
7967 if (!(flags
& DIF_HAVE_ELEM
)) {
7968 /* This should happen only when we haven't parsed
7969 the init element above for fear of committing a
7970 string constant to memory too early. */
7971 if (tok
!= TOK_STR
&& tok
!= TOK_LSTR
)
7972 expect("string constant");
7973 parse_init_elem(!p
->sec
? EXPR_ANY
: EXPR_CONST
);
7975 if (!p
->sec
&& (flags
& DIF_CLEAR
) /* container was already zero'd */
7976 && (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
7978 && btype_size(type
->t
& VT_BTYPE
) /* not for fp constants */
7982 init_putv(p
, type
, c
);
7986 /* parse an initializer for type 't' if 'has_init' is non zero, and
7987 allocate space in local or global data space ('r' is either
7988 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7989 variable 'v' of scope 'scope' is declared before initializers
7990 are parsed. If 'v' is zero, then a reference to the new object
7991 is put in the value stack. If 'has_init' is 2, a special parsing
7992 is done to handle string constants. */
7993 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
7994 int has_init
, int v
, int global
)
7996 int size
, align
, addr
;
7997 TokenString
*init_str
= NULL
;
8000 Sym
*flexible_array
;
8002 int saved_nocode_wanted
= nocode_wanted
;
8003 #ifdef CONFIG_TCC_BCHECK
8004 int bcheck
= tcc_state
->do_bounds_check
&& !NODATA_WANTED
;
8006 init_params p
= {0};
8008 /* Always allocate static or global variables */
8009 if (v
&& (r
& VT_VALMASK
) == VT_CONST
)
8010 nocode_wanted
|= DATA_ONLY_WANTED
;
8012 flexible_array
= NULL
;
8013 size
= type_size(type
, &align
);
8015 /* exactly one flexible array may be initialized, either the
8016 toplevel array or the last member of the toplevel struct */
8019 /* If the base type itself was an array type of unspecified size
8020 (like in 'typedef int arr[]; arr x = {1};') then we will
8021 overwrite the unknown size by the real one for this decl.
8022 We need to unshare the ref symbol holding that size. */
8023 type
->ref
= sym_push(SYM_FIELD
, &type
->ref
->type
, 0, type
->ref
->c
);
8024 p
.flex_array_ref
= type
->ref
;
8026 } else if (has_init
&& (type
->t
& VT_BTYPE
) == VT_STRUCT
) {
8027 Sym
*field
= type
->ref
->next
;
8030 field
= field
->next
;
8031 if (field
->type
.t
& VT_ARRAY
&& field
->type
.ref
->c
< 0) {
8032 flexible_array
= field
;
8033 p
.flex_array_ref
= field
->type
.ref
;
8040 /* If unknown size, do a dry-run 1st pass */
8042 tcc_error("unknown type size");
8043 if (has_init
== 2) {
8044 /* only get strings */
8045 init_str
= tok_str_alloc();
8046 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8047 tok_str_add_tok(init_str
);
8050 tok_str_add(init_str
, -1);
8051 tok_str_add(init_str
, 0);
8053 skip_or_save_block(&init_str
);
8057 begin_macro(init_str
, 1);
8059 decl_initializer(&p
, type
, 0, DIF_FIRST
| DIF_SIZE_ONLY
);
8060 /* prepare second initializer parsing */
8061 macro_ptr
= init_str
->str
;
8064 /* if still unknown size, error */
8065 size
= type_size(type
, &align
);
8067 tcc_error("unknown type size");
8069 /* If there's a flex member and it was used in the initializer
8071 if (flexible_array
&& flexible_array
->type
.ref
->c
> 0)
8072 size
+= flexible_array
->type
.ref
->c
8073 * pointed_size(&flexible_array
->type
);
8076 /* take into account specified alignment if bigger */
8077 if (ad
->a
.aligned
) {
8078 int speca
= 1 << (ad
->a
.aligned
- 1);
8081 } else if (ad
->a
.packed
) {
8085 if (!v
&& NODATA_WANTED
)
8086 size
= 0, align
= 1;
8088 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
8090 #ifdef CONFIG_TCC_BCHECK
8092 /* add padding between stack variables for bound checking */
8096 loc
= (loc
- size
) & -align
;
8098 p
.local_offset
= addr
+ size
;
8099 #ifdef CONFIG_TCC_BCHECK
8101 /* add padding between stack variables for bound checking */
8106 /* local variable */
8107 #ifdef CONFIG_TCC_ASM
8108 if (ad
->asm_label
) {
8109 int reg
= asm_parse_regvar(ad
->asm_label
);
8111 r
= (r
& ~VT_VALMASK
) | reg
;
8114 sym
= sym_push(v
, type
, r
, addr
);
8115 if (ad
->cleanup_func
) {
8116 Sym
*cls
= sym_push2(&all_cleanups
,
8117 SYM_FIELD
| ++cur_scope
->cl
.n
, 0, 0);
8118 cls
->prev_tok
= sym
;
8119 cls
->next
= ad
->cleanup_func
;
8120 cls
->ncl
= cur_scope
->cl
.s
;
8121 cur_scope
->cl
.s
= cls
;
8126 /* push local reference */
8127 vset(type
, r
, addr
);
8132 /* see if the symbol was already defined */
8135 if (p
.flex_array_ref
&& (sym
->type
.t
& type
->t
& VT_ARRAY
)
8136 && sym
->type
.ref
->c
> type
->ref
->c
) {
8137 /* flex array was already declared with explicit size
8139 int arr[] = { 1,2,3 }; */
8140 type
->ref
->c
= sym
->type
.ref
->c
;
8141 size
= type_size(type
, &align
);
8143 patch_storage(sym
, ad
, type
);
8144 /* we accept several definitions of the same global variable. */
8145 if (!has_init
&& sym
->c
&& elfsym(sym
)->st_shndx
!= SHN_UNDEF
)
8150 /* allocate symbol in corresponding section */
8154 while ((tp
->t
& (VT_BTYPE
|VT_ARRAY
)) == (VT_PTR
|VT_ARRAY
))
8155 tp
= &tp
->ref
->type
;
8156 if (tp
->t
& VT_CONSTANT
) {
8157 sec
= rodata_section
;
8158 } else if (has_init
) {
8160 /*if (tcc_state->g_debug & 4)
8161 tcc_warning("rw data: %s", get_tok_str(v, 0));*/
8162 } else if (tcc_state
->nocommon
)
8167 addr
= section_add(sec
, size
, align
);
8168 #ifdef CONFIG_TCC_BCHECK
8169 /* add padding if bound check */
8171 section_add(sec
, 1, 1);
8174 addr
= align
; /* SHN_COMMON is special, symbol value is align */
8175 sec
= common_section
;
8180 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
8181 patch_storage(sym
, ad
, NULL
);
8183 /* update symbol definition */
8184 put_extern_sym(sym
, sec
, addr
, size
);
8186 /* push global reference */
8187 vpush_ref(type
, sec
, addr
, size
);
8192 #ifdef CONFIG_TCC_BCHECK
8193 /* handles bounds now because the symbol must be defined
8194 before for the relocation */
8198 greloca(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_PTR
, 0);
8199 /* then add global bound info */
8200 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(addr_t
));
8201 bounds_ptr
[0] = 0; /* relocated */
8202 bounds_ptr
[1] = size
;
8207 if (type
->t
& VT_VLA
) {
8213 /* save before-VLA stack pointer if needed */
8214 if (cur_scope
->vla
.num
== 0) {
8215 if (cur_scope
->prev
&& cur_scope
->prev
->vla
.num
) {
8216 cur_scope
->vla
.locorig
= cur_scope
->prev
->vla
.loc
;
8218 gen_vla_sp_save(loc
-= PTR_SIZE
);
8219 cur_scope
->vla
.locorig
= loc
;
8223 vpush_type_size(type
, &a
);
8224 gen_vla_alloc(type
, a
);
8225 #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
8226 /* on _WIN64, because of the function args scratch area, the
8227 result of alloca differs from RSP and is returned in RAX. */
8228 gen_vla_result(addr
), addr
= (loc
-= PTR_SIZE
);
8230 gen_vla_sp_save(addr
);
8231 cur_scope
->vla
.loc
= addr
;
8232 cur_scope
->vla
.num
++;
8233 } else if (has_init
) {
8235 decl_initializer(&p
, type
, addr
, DIF_FIRST
);
8236 /* patch flexible array member size back to -1, */
8237 /* for possible subsequent similar declarations */
8239 flexible_array
->type
.ref
->c
= -1;
8243 /* restore parse state if needed */
8249 nocode_wanted
= saved_nocode_wanted
;
8252 /* generate vla code saved in post_type() */
8253 static void func_vla_arg_code(Sym
*arg
)
8256 TokenString
*vla_array_tok
= NULL
;
8259 func_vla_arg_code(arg
->type
.ref
);
8261 if ((arg
->type
.t
& VT_VLA
) && arg
->type
.ref
->vla_array_str
) {
8262 loc
-= type_size(&int_type
, &align
);
8264 arg
->type
.ref
->c
= loc
;
8267 vla_array_tok
= tok_str_alloc();
8268 vla_array_tok
->str
= arg
->type
.ref
->vla_array_str
;
8269 begin_macro(vla_array_tok
, 1);
8274 vpush_type_size(&arg
->type
.ref
->type
, &align
);
8276 vset(&int_type
, VT_LOCAL
|VT_LVAL
, arg
->type
.ref
->c
);
8283 static void func_vla_arg(Sym
*sym
)
8287 for (arg
= sym
->type
.ref
->next
; arg
; arg
= arg
->next
)
8288 if (arg
->type
.t
& VT_VLA
)
8289 func_vla_arg_code(arg
);
8292 /* parse a function defined by symbol 'sym' and generate its code in
8293 'cur_text_section' */
8294 static void gen_function(Sym
*sym
)
8296 struct scope f
= { 0 };
8297 cur_scope
= root_scope
= &f
;
8299 ind
= cur_text_section
->data_offset
;
8300 if (sym
->a
.aligned
) {
8301 size_t newoff
= section_add(cur_text_section
, 0,
8302 1 << (sym
->a
.aligned
- 1));
8303 gen_fill_nops(newoff
- ind
);
8305 /* NOTE: we patch the symbol size later */
8306 put_extern_sym(sym
, cur_text_section
, ind
, 0);
8307 if (sym
->type
.ref
->f
.func_ctor
)
8308 add_array (tcc_state
, ".init_array", sym
->c
);
8309 if (sym
->type
.ref
->f
.func_dtor
)
8310 add_array (tcc_state
, ".fini_array", sym
->c
);
8312 funcname
= get_tok_str(sym
->v
, NULL
);
8314 func_vt
= sym
->type
.ref
->type
;
8315 func_var
= sym
->type
.ref
->f
.func_type
== FUNC_ELLIPSIS
;
8317 /* put debug symbol */
8318 tcc_debug_funcstart(tcc_state
, sym
);
8319 /* push a dummy symbol to enable local sym storage */
8320 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
8321 local_scope
= 1; /* for function parameters */
8323 tcc_debug_prolog_epilog(tcc_state
, 0);
8326 clear_temp_local_var_list();
8331 /* reset local stack */
8332 pop_local_syms(NULL
, 0);
8333 tcc_debug_prolog_epilog(tcc_state
, 1);
8335 cur_text_section
->data_offset
= ind
;
8337 label_pop(&global_label_stack
, NULL
, 0);
8338 sym_pop(&all_cleanups
, NULL
, 0);
8339 /* patch symbol size */
8340 elfsym(sym
)->st_size
= ind
- func_ind
;
8341 /* end of function */
8342 tcc_debug_funcend(tcc_state
, ind
- func_ind
);
8343 /* It's better to crash than to generate wrong code */
8344 cur_text_section
= NULL
;
8345 funcname
= ""; /* for safety */
8346 func_vt
.t
= VT_VOID
; /* for safety */
8347 func_var
= 0; /* for safety */
8348 ind
= 0; /* for safety */
8350 nocode_wanted
= DATA_ONLY_WANTED
;
8352 /* do this after funcend debug info */
8356 static void gen_inline_functions(TCCState
*s
)
8359 int inline_generated
, i
;
8360 struct InlineFunc
*fn
;
8362 tcc_open_bf(s
, ":inline:", 0);
8363 /* iterate while inline function are referenced */
8365 inline_generated
= 0;
8366 for (i
= 0; i
< s
->nb_inline_fns
; ++i
) {
8367 fn
= s
->inline_fns
[i
];
8369 if (sym
&& (sym
->c
|| !(sym
->type
.t
& VT_INLINE
))) {
8370 /* the function was used or forced (and then not internal):
8371 generate its code and convert it to a normal function */
8373 tcc_debug_putfile(s
, fn
->filename
);
8374 begin_macro(fn
->func_str
, 1);
8376 cur_text_section
= text_section
;
8380 inline_generated
= 1;
8383 } while (inline_generated
);
8387 static void free_inline_functions(TCCState
*s
)
8390 /* free tokens of unused inline functions */
8391 for (i
= 0; i
< s
->nb_inline_fns
; ++i
) {
8392 struct InlineFunc
*fn
= s
->inline_fns
[i
];
8394 tok_str_free(fn
->func_str
);
8396 dynarray_reset(&s
->inline_fns
, &s
->nb_inline_fns
);
8399 static void do_Static_assert(void)
8407 msg
= "_Static_assert fail";
8410 msg
= parse_mult_str("string constant")->data
;
8414 tcc_error("%s", msg
);
8418 /* 'l' is VT_LOCAL or VT_CONST to define default storage type
8419 or VT_CMP if parsing old style parameter list
8420 or VT_JMP if parsing c99 for decl: for (int i = 0, ...) */
8421 static int decl(int l
)
8423 int v
, has_init
, r
, oldint
;
8426 AttributeDef ad
, adbase
;
8430 if (tok
== TOK_STATIC_ASSERT
) {
8436 if (!parse_btype(&btype
, &adbase
, l
== VT_LOCAL
)) {
8439 /* skip redundant ';' if not in old parameter decl scope */
8440 if (tok
== ';' && l
!= VT_CMP
) {
8446 if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
8447 /* global asm block */
8451 if (tok
>= TOK_UIDENT
) {
8452 /* special test for old K&R protos without explicit int
8453 type. Only accepted when defining global data */
8458 expect("declaration");
8464 if ((btype
.t
& VT_BTYPE
) == VT_STRUCT
) {
8466 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
)
8467 tcc_warning("unnamed struct/union that defines no instances");
8471 if (IS_ENUM(btype
.t
)) {
8477 while (1) { /* iterate thru each declaration */
8480 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8484 type_to_str(buf
, sizeof(buf
), &type
, get_tok_str(v
, NULL
));
8485 printf("type = '%s'\n", buf
);
8488 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8489 if ((type
.t
& VT_STATIC
) && (l
!= VT_CONST
))
8490 tcc_error("function without file scope cannot be static");
8491 /* if old style function prototype, we accept a
8494 if (sym
->f
.func_type
== FUNC_OLD
&& l
== VT_CONST
) {
8498 #if defined TCC_TARGET_MACHO || defined TARGETOS_ANDROID
8499 if (sym
->f
.func_alwinl
8500 && ((type
.t
& (VT_EXTERN
| VT_INLINE
))
8501 == (VT_EXTERN
| VT_INLINE
))) {
8502 /* always_inline functions must be handled as if they
8503 don't generate multiple global defs, even if extern
8504 inline, i.e. GNU inline semantics for those. Rewrite
8505 them into static inline. */
8506 type
.t
&= ~VT_EXTERN
;
8507 type
.t
|= VT_STATIC
;
8510 /* always compile 'extern inline' */
8511 if (type
.t
& VT_EXTERN
)
8512 type
.t
&= ~VT_INLINE
;
8514 } else if (oldint
) {
8515 tcc_warning("type defaults to int");
8518 if (gnu_ext
&& (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
8519 ad
.asm_label
= asm_label_instr();
8520 /* parse one last attribute list, after asm label */
8521 parse_attribute(&ad
);
8523 /* gcc does not allow __asm__("label") with function definition,
8530 #ifdef TCC_TARGET_PE
8531 if (ad
.a
.dllimport
|| ad
.a
.dllexport
) {
8532 if (type
.t
& VT_STATIC
)
8533 tcc_error("cannot have dll linkage with static");
8534 if (type
.t
& VT_TYPEDEF
) {
8535 tcc_warning("'%s' attribute ignored for typedef",
8536 ad
.a
.dllimport
? (ad
.a
.dllimport
= 0, "dllimport") :
8537 (ad
.a
.dllexport
= 0, "dllexport"));
8538 } else if (ad
.a
.dllimport
) {
8539 if ((type
.t
& VT_BTYPE
) == VT_FUNC
)
8542 type
.t
|= VT_EXTERN
;
8548 tcc_error("cannot use local functions");
8549 if ((type
.t
& VT_BTYPE
) != VT_FUNC
)
8550 expect("function definition");
8552 /* reject abstract declarators in function definition
8553 make old style params without decl have int type */
8555 while ((sym
= sym
->next
) != NULL
) {
8556 if (!(sym
->v
& ~SYM_FIELD
))
8557 expect("identifier");
8558 if (sym
->type
.t
== VT_VOID
)
8559 sym
->type
= int_type
;
8562 /* apply post-declaraton attributes */
8563 merge_funcattr(&type
.ref
->f
, &ad
.f
);
8565 /* put function symbol */
8566 type
.t
&= ~VT_EXTERN
;
8567 sym
= external_sym(v
, &type
, 0, &ad
);
8569 /* static inline functions are just recorded as a kind
8570 of macro. Their code will be emitted at the end of
8571 the compilation unit only if they are used */
8572 if (sym
->type
.t
& VT_INLINE
) {
8573 struct InlineFunc
*fn
;
8574 fn
= tcc_malloc(sizeof *fn
+ strlen(file
->filename
));
8575 strcpy(fn
->filename
, file
->filename
);
8577 skip_or_save_block(&fn
->func_str
);
8578 dynarray_add(&tcc_state
->inline_fns
,
8579 &tcc_state
->nb_inline_fns
, fn
);
8581 /* compute text section */
8582 cur_text_section
= ad
.section
;
8583 if (!cur_text_section
)
8584 cur_text_section
= text_section
;
8590 /* find parameter in function parameter list */
8591 for (sym
= func_vt
.ref
->next
; sym
; sym
= sym
->next
)
8592 if ((sym
->v
& ~SYM_FIELD
) == v
)
8594 tcc_error("declaration for parameter '%s' but no such parameter",
8595 get_tok_str(v
, NULL
));
8597 if (type
.t
& VT_STORAGE
) /* 'register' is okay */
8598 tcc_error("storage class specified for '%s'",
8599 get_tok_str(v
, NULL
));
8600 if (sym
->type
.t
!= VT_VOID
)
8601 tcc_error("redefinition of parameter '%s'",
8602 get_tok_str(v
, NULL
));
8603 convert_parameter_type(&type
);
8605 } else if (type
.t
& VT_TYPEDEF
) {
8606 /* save typedefed type */
8607 /* XXX: test storage specifiers ? */
8609 if (sym
&& sym
->sym_scope
== local_scope
) {
8610 if (!is_compatible_types(&sym
->type
, &type
)
8611 || !(sym
->type
.t
& VT_TYPEDEF
))
8612 tcc_error("incompatible redefinition of '%s'",
8613 get_tok_str(v
, NULL
));
8616 sym
= sym_push(v
, &type
, 0, 0);
8619 if ((type
.t
& VT_BTYPE
) == VT_FUNC
)
8620 merge_funcattr(&sym
->type
.ref
->f
, &ad
.f
);
8622 tcc_debug_typedef (tcc_state
, sym
);
8623 } else if ((type
.t
& VT_BTYPE
) == VT_VOID
8624 && !(type
.t
& VT_EXTERN
)) {
8625 tcc_error("declaration of void object");
8628 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8629 /* external function definition */
8630 /* specific case for func_call attribute */
8631 merge_funcattr(&type
.ref
->f
, &ad
.f
);
8632 } else if (!(type
.t
& VT_ARRAY
)) {
8633 /* not lvalue if array */
8636 has_init
= (tok
== '=');
8637 if (has_init
&& (type
.t
& VT_VLA
))
8638 tcc_error("variable length array cannot be initialized");
8639 if (((type
.t
& VT_EXTERN
) && (!has_init
|| l
!= VT_CONST
))
8640 || (type
.t
& VT_BTYPE
) == VT_FUNC
8641 /* as with GCC, uninitialized global arrays with no size
8642 are considered extern: */
8643 || ((type
.t
& VT_ARRAY
) && !has_init
8644 && l
== VT_CONST
&& type
.ref
->c
< 0)
8646 /* external variable or function */
8647 type
.t
|= VT_EXTERN
;
8648 sym
= external_sym(v
, &type
, r
, &ad
);
8649 if (ad
.alias_target
) {
8650 /* Aliases need to be emitted when their target
8651 symbol is emitted, even if perhaps unreferenced.
8652 We only support the case where the base is
8653 already defined, otherwise we would need
8654 deferring to emit the aliases until the end of
8655 the compile unit. */
8656 Sym
*alias_target
= sym_find(ad
.alias_target
);
8657 ElfSym
*esym
= elfsym(alias_target
);
8659 tcc_error("unsupported forward __alias__ attribute");
8660 put_extern_sym2(sym
, esym
->st_shndx
,
8661 esym
->st_value
, esym
->st_size
, 1);
8664 if (l
== VT_CONST
|| (type
.t
& VT_STATIC
))
8670 else if (l
== VT_CONST
)
8671 /* uninitialized global variables may be overridden */
8672 type
.t
|= VT_EXTERN
;
8673 decl_initializer_alloc(&type
, &ad
, r
, has_init
, v
, l
== VT_CONST
);
8689 /* ------------------------------------------------------------------------- */
8692 /* ------------------------------------------------------------------------- */