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 in_generic
;
48 static int section_sym
;
51 static SValue _vstack
[1 + VSTACK_SIZE
];
52 #define vstack (_vstack + 1)
54 ST_DATA
int const_wanted
; /* true if constant wanted */
55 ST_DATA
int nocode_wanted
; /* no code generation wanted */
56 #define unevalmask 0xffff /* unevaluated subexpression */
57 #define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
58 #define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */
60 /* Automagical code suppression ----> */
61 #define CODE_OFF() (nocode_wanted |= 0x20000000)
62 #define CODE_ON() (nocode_wanted &= ~0x20000000)
64 /* Clear 'nocode_wanted' at label if it was used */
65 ST_FUNC
void gsym(int t
) { if (t
) { gsym_addr(t
, ind
); CODE_ON(); }}
66 static int gind(void) { CODE_ON(); return ind
; }
68 /* Set 'nocode_wanted' after unconditional jumps */
69 static void gjmp_addr_acs(int t
) { gjmp_addr(t
); CODE_OFF(); }
70 static int gjmp_acs(int t
) { t
= gjmp(t
); CODE_OFF(); return t
; }
72 /* These are #undef'd at the end of this file */
73 #define gjmp_addr gjmp_addr_acs
77 ST_DATA
int global_expr
; /* true if compound literals must be allocated globally (used during initializers parsing */
78 ST_DATA CType func_vt
; /* current function return type (used by return instruction) */
79 ST_DATA
int func_var
; /* true if current function is variadic (used by return instruction) */
81 static int last_line_num
, new_file
, func_ind
; /* debug info control */
82 ST_DATA
const char *funcname
;
83 ST_DATA CType int_type
, func_old_type
, char_pointer_type
;
86 #define VT_SIZE_T (VT_INT | VT_UNSIGNED)
87 #define VT_PTRDIFF_T VT_INT
89 #define VT_SIZE_T (VT_LLONG | VT_UNSIGNED)
90 #define VT_PTRDIFF_T VT_LLONG
92 #define VT_SIZE_T (VT_LONG | VT_LLONG | VT_UNSIGNED)
93 #define VT_PTRDIFF_T (VT_LONG | VT_LLONG)
96 ST_DATA
struct switch_t
{
100 } **p
; int n
; /* list of case ranges */
101 int def_sym
; /* default symbol */
104 struct switch_t
*prev
;
106 } *cur_switch
; /* current switch */
108 #define MAX_TEMP_LOCAL_VARIABLE_NUMBER 8
109 /*list of temporary local variables on the stack in current function. */
110 ST_DATA
struct temp_local_variable
{
111 int location
; //offset on stack. Svalue.c.i
114 } arr_temp_local_vars
[MAX_TEMP_LOCAL_VARIABLE_NUMBER
];
115 short nb_temp_local_vars
;
117 static struct scope
{
119 struct { int loc
, num
; } vla
;
120 struct { Sym
*s
; int n
; } cl
;
123 } *cur_scope
, *loop_scope
, *root_scope
;
128 } default_debug
[] = {
129 { VT_INT
, "int:t1=r1;-2147483648;2147483647;", },
130 { VT_BYTE
, "char:t2=r2;0;127;", },
132 { VT_LONG
| VT_INT
, "long int:t3=r3;-2147483648;2147483647;", },
134 { VT_LLONG
| VT_LONG
, "long int:t3=r3;-9223372036854775808;9223372036854775807;", },
136 { VT_INT
| VT_UNSIGNED
, "unsigned int:t4=r4;0;4294967295;", },
138 { VT_LONG
| VT_INT
| VT_UNSIGNED
, "long unsigned int:t5=r5;0;4294967295;", },
140 { VT_LLONG
| VT_LONG
| VT_UNSIGNED
, "long unsigned int:t5=r5;0;-1;", },
142 { VT_QLONG
, "__int128:t6=r6;0;-1;", },
143 { VT_QLONG
| VT_UNSIGNED
, "__int128 unsigned:t7=r7;0;-1;", },
144 { VT_LLONG
, "long long int:t8=r8;-9223372036854775808;9223372036854775807;", },
145 { VT_LLONG
| VT_UNSIGNED
, "long long unsigned int:t9=r9;0;-1;", },
146 { VT_SHORT
, "short int:t10=r10;-32768;32767;", },
147 { VT_SHORT
| VT_UNSIGNED
, "short unsigned int:t11=r11;0;65535;", },
148 { VT_BYTE
| VT_DEFSIGN
, "signed char:t12=r12;-128;127;", },
149 { VT_BYTE
| VT_DEFSIGN
| VT_UNSIGNED
, "unsigned char:t13=r13;0;255;", },
150 { VT_FLOAT
, "float:t14=r1;4;0;", },
151 { VT_DOUBLE
, "double:t15=r1;8;0;", },
152 { VT_LDOUBLE
, "long double:t16=r1;16;0;", },
153 { -1, "_Float32:t17=r1;4;0;", },
154 { -1, "_Float64:t18=r1;8;0;", },
155 { -1, "_Float128:t19=r1;16;0;", },
156 { -1, "_Float32x:t20=r1;8;0;", },
157 { -1, "_Float64x:t21=r1;16;0;", },
158 { -1, "_Decimal32:t22=r1;4;0;", },
159 { -1, "_Decimal64:t23=r1;8;0;", },
160 { -1, "_Decimal128:t24=r1;16;0;", },
161 { VT_VOID
, "void:t25=25", },
164 static int debug_next_type
;
166 static struct debug_hash
{
171 static int n_debug_hash
;
173 static struct debug_info
{
184 struct debug_info
*child
, *next
, *last
, *parent
;
185 } *debug_info
, *debug_info_root
;
187 static CString debug_str
;
189 /********************************************************/
191 #define precedence_parser
192 static void init_prec(void);
194 /********************************************************/
195 #ifndef CONFIG_TCC_ASM
196 ST_FUNC
void asm_instr(void)
198 tcc_error("inline asm() not supported");
200 ST_FUNC
void asm_global_instr(void)
202 tcc_error("inline asm() not supported");
206 /* ------------------------------------------------------------------------- */
207 static void gen_cast(CType
*type
);
208 static void gen_cast_s(int t
);
209 static inline CType
*pointed_type(CType
*type
);
210 static int is_compatible_types(CType
*type1
, CType
*type2
);
211 static int parse_btype(CType
*type
, AttributeDef
*ad
);
212 static CType
*type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
213 static void parse_expr_type(CType
*type
);
214 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
);
215 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
, int flags
);
216 static void block(int is_expr
);
217 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
, int has_init
, int v
, int scope
);
218 static void decl(int l
);
219 static int decl0(int l
, int is_for_loop_init
, Sym
*);
220 static void expr_eq(void);
221 static void vla_runtime_type_size(CType
*type
, int *a
);
222 static int is_compatible_unqualified_types(CType
*type1
, CType
*type2
);
223 static inline int64_t expr_const64(void);
224 static void vpush64(int ty
, unsigned long long v
);
225 static void vpush(CType
*type
);
226 static int gvtst(int inv
, int t
);
227 static void gen_inline_functions(TCCState
*s
);
228 static void free_inline_functions(TCCState
*s
);
229 static void skip_or_save_block(TokenString
**str
);
230 static void gv_dup(void);
231 static int get_temp_local_var(int size
,int align
);
232 static void clear_temp_local_var_list();
233 static void cast_error(CType
*st
, CType
*dt
);
235 ST_INLN
int is_float(int t
)
237 int bt
= t
& VT_BTYPE
;
238 return bt
== VT_LDOUBLE
244 static inline int is_integer_btype(int bt
)
253 static int btype_size(int bt
)
255 return bt
== VT_BYTE
|| bt
== VT_BOOL
? 1 :
259 bt
== VT_PTR
? PTR_SIZE
: 0;
262 /* returns function return register from type */
263 static int R_RET(int t
)
267 #ifdef TCC_TARGET_X86_64
268 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
270 #elif defined TCC_TARGET_RISCV64
271 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
277 /* returns 2nd function return register, if any */
278 static int R2_RET(int t
)
284 #elif defined TCC_TARGET_X86_64
289 #elif defined TCC_TARGET_RISCV64
296 /* returns true for two-word types */
297 #define USING_TWO_WORDS(t) (R2_RET(t) != VT_CONST)
299 /* put function return registers to stack value */
300 static void PUT_R_RET(SValue
*sv
, int t
)
302 sv
->r
= R_RET(t
), sv
->r2
= R2_RET(t
);
305 /* returns function return register class for type t */
306 static int RC_RET(int t
)
308 return reg_classes
[R_RET(t
)] & ~(RC_FLOAT
| RC_INT
);
311 /* returns generic register class for type t */
312 static int RC_TYPE(int t
)
316 #ifdef TCC_TARGET_X86_64
317 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
319 if ((t
& VT_BTYPE
) == VT_QFLOAT
)
321 #elif defined TCC_TARGET_RISCV64
322 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
328 /* returns 2nd register class corresponding to t and rc */
329 static int RC2_TYPE(int t
, int rc
)
331 if (!USING_TWO_WORDS(t
))
346 /* we use our own 'finite' function to avoid potential problems with
347 non standard math libs */
348 /* XXX: endianness dependent */
349 ST_FUNC
int ieee_finite(double d
)
352 memcpy(p
, &d
, sizeof(double));
353 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
356 /* compiling intel long double natively */
357 #if (defined __i386__ || defined __x86_64__) \
358 && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
359 # define TCC_IS_NATIVE_387
362 ST_FUNC
void test_lvalue(void)
364 if (!(vtop
->r
& VT_LVAL
))
368 ST_FUNC
void check_vstack(void)
370 if (vtop
!= vstack
- 1)
371 tcc_error("internal compiler error: vstack leak (%d)",
372 (int)(vtop
- vstack
+ 1));
375 /* ------------------------------------------------------------------------- */
376 /* vstack debugging aid */
379 void pv (const char *lbl
, int a
, int b
)
382 for (i
= a
; i
< a
+ b
; ++i
) {
383 SValue
*p
= &vtop
[-i
];
384 printf("%s vtop[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n",
385 lbl
, i
, p
->type
.t
, p
->r
, p
->r2
, (int)p
->c
.i
);
390 /* ------------------------------------------------------------------------- */
391 /* start of translation unit info */
392 ST_FUNC
void tcc_debug_start(TCCState
*s1
)
398 /* file info: full path + filename */
399 section_sym
= put_elf_sym(symtab_section
, 0, 0,
400 ELFW(ST_INFO
)(STB_LOCAL
, STT_SECTION
), 0,
401 text_section
->sh_num
, NULL
);
402 getcwd(buf
, sizeof(buf
));
404 normalize_slashes(buf
);
406 pstrcat(buf
, sizeof(buf
), "/");
407 debug_next_type
= sizeof(default_debug
) / sizeof(default_debug
[0]);
408 put_stabs_r(s1
, buf
, N_SO
, 0, 0,
409 text_section
->data_offset
, text_section
, section_sym
);
410 put_stabs_r(s1
, file
->prev
->filename
, N_SO
, 0, 0,
411 text_section
->data_offset
, text_section
, section_sym
);
412 for (i
= 0; i
< sizeof (default_debug
) / sizeof (default_debug
[0]); i
++)
413 put_stabs(s1
, default_debug
[i
].name
, N_LSYM
, 0, 0, 0);
414 new_file
= last_line_num
= 0;
416 /* we're currently 'including' the <command line> */
420 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
421 symbols can be safely used */
422 put_elf_sym(symtab_section
, 0, 0,
423 ELFW(ST_INFO
)(STB_LOCAL
, STT_FILE
), 0,
424 SHN_ABS
, file
->filename
);
427 static void tcc_debug_stabs (const char *str
, int type
, unsigned long value
,
428 Section
*sec
, int sym_index
)
434 (struct debug_sym
*)tcc_realloc (debug_info
->sym
,
435 sizeof(struct debug_sym
) *
436 (debug_info
->n_sym
+ 1));
437 s
= debug_info
->sym
+ debug_info
->n_sym
++;
440 s
->str
= tcc_strdup(str
);
442 s
->sym_index
= sym_index
;
445 put_stabs_r (tcc_state
, str
, type
, 0, 0, value
, sec
, sym_index
);
447 put_stabs (tcc_state
, str
, type
, 0, 0, value
);
450 static void tcc_debug_stabn(int type
, int value
)
452 if (!tcc_state
->do_debug
)
454 if (type
== N_LBRAC
) {
455 struct debug_info
*info
=
456 (struct debug_info
*) tcc_mallocz(sizeof (*info
));
459 info
->parent
= debug_info
;
461 if (debug_info
->child
) {
462 if (debug_info
->child
->last
)
463 debug_info
->child
->last
->next
= info
;
465 debug_info
->child
->next
= info
;
466 debug_info
->child
->last
= info
;
469 debug_info
->child
= info
;
472 debug_info_root
= info
;
476 debug_info
->end
= value
;
477 debug_info
= debug_info
->parent
;
481 static void tcc_get_debug_info(Sym
*s
, CString
*result
)
490 type
= t
->type
.t
& ~(VT_EXTERN
| VT_STATIC
| VT_CONSTANT
| VT_VOLATILE
);
491 if ((type
& VT_BTYPE
) != VT_BYTE
)
493 if (type
== VT_PTR
|| type
== (VT_PTR
| VT_ARRAY
))
494 n
++, t
= t
->type
.ref
;
498 if ((type
& VT_BTYPE
) == VT_STRUCT
) {
502 for (i
= 0; i
< n_debug_hash
; i
++) {
503 if (t
== debug_hash
[i
].type
) {
504 debug_type
= debug_hash
[i
].debug_type
;
508 if (debug_type
== -1) {
509 debug_type
= ++debug_next_type
;
510 debug_hash
= (struct debug_hash
*)
511 tcc_realloc (debug_hash
,
512 (n_debug_hash
+ 1) * sizeof(*debug_hash
));
513 debug_hash
[n_debug_hash
].debug_type
= debug_type
;
514 debug_hash
[n_debug_hash
++].type
= t
;
516 cstr_printf (&str
, "%s:T%d=%c%d",
517 (t
->v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
518 ? "" : get_tok_str(t
->v
& ~SYM_STRUCT
, NULL
),
520 IS_UNION (t
->type
.t
) ? 'u' : 's',
523 int pos
, size
, align
;
526 cstr_printf (&str
, "%s:",
527 (t
->v
& ~SYM_FIELD
) >= SYM_FIRST_ANOM
528 ? "" : get_tok_str(t
->v
& ~SYM_FIELD
, NULL
));
529 tcc_get_debug_info (t
, &str
);
530 if (t
->type
.t
& VT_BITFIELD
) {
531 pos
= t
->c
* 8 + BIT_POS(t
->type
.t
);
532 size
= BIT_SIZE(t
->type
.t
);
536 size
= type_size(&t
->type
, &align
) * 8;
538 cstr_printf (&str
, ",%d,%d;", pos
, size
);
540 cstr_printf (&str
, ";");
541 tcc_debug_stabs(str
.data
, N_LSYM
, 0, NULL
, 0);
545 else if (IS_ENUM(type
)) {
546 Sym
*e
= t
= t
->type
.ref
;
548 debug_type
= ++debug_next_type
;
550 cstr_printf (&str
, "%s:T%d=e",
551 (t
->v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
552 ? "" : get_tok_str(t
->v
& ~SYM_STRUCT
, NULL
),
556 cstr_printf (&str
, "%s:",
557 (t
->v
& ~SYM_FIELD
) >= SYM_FIRST_ANOM
558 ? "" : get_tok_str(t
->v
& ~SYM_FIELD
, NULL
));
559 cstr_printf (&str
, e
->type
.t
& VT_UNSIGNED
? "%llu," : "%lld,",
562 cstr_printf (&str
, ";");
563 tcc_debug_stabs(str
.data
, N_LSYM
, 0, NULL
, 0);
567 type
&= ~VT_STRUCT_MASK
;
569 debug_type
<= sizeof(default_debug
) / sizeof(default_debug
[0]);
571 if (default_debug
[debug_type
- 1].type
== type
)
573 if (debug_type
> sizeof(default_debug
) / sizeof(default_debug
[0]))
577 cstr_printf (result
, "%d=", ++debug_next_type
);
580 type
= t
->type
.t
& ~(VT_EXTERN
| VT_STATIC
| VT_CONSTANT
| VT_VOLATILE
);
581 if ((type
& VT_BTYPE
) != VT_BYTE
)
584 cstr_printf (result
, "%d=*", ++debug_next_type
);
585 else if (type
== (VT_PTR
| VT_ARRAY
))
586 cstr_printf (result
, "%d=ar1;0;%d;",
587 ++debug_next_type
, t
->type
.ref
->c
- 1);
592 cstr_printf (result
, "%d", debug_type
);
595 static void tcc_debug_finish (struct debug_info
*cur
)
599 struct debug_info
*next
= cur
->next
;
601 for (i
= 0; i
< cur
->n_sym
; i
++) {
602 struct debug_sym
*s
= &cur
->sym
[i
];
605 put_stabs_r(tcc_state
, s
->str
, s
->type
, 0, 0, s
->value
,
606 s
->sec
, s
->sym_index
);
608 put_stabs(tcc_state
, s
->str
, s
->type
, 0, 0, s
->value
);
612 put_stabn(tcc_state
, N_LBRAC
, 0, 0, cur
->start
);
613 tcc_debug_finish (cur
->child
);
614 put_stabn(tcc_state
, N_RBRAC
, 0, 0, cur
->end
);
620 static void tcc_add_debug_info(int param
, Sym
*s
, Sym
*e
)
622 if (!tcc_state
->do_debug
)
624 for (; s
!= e
; s
= s
->prev
) {
625 if (!s
->v
|| (s
->r
& VT_VALMASK
) != VT_LOCAL
)
627 cstr_reset (&debug_str
);
628 cstr_printf (&debug_str
, "%s:%s", get_tok_str(s
->v
, NULL
), param
? "p" : "");
629 tcc_get_debug_info(s
, &debug_str
);
630 tcc_debug_stabs(debug_str
.data
, param
? N_PSYM
: N_LSYM
, s
->c
, NULL
, 0);
634 /* put end of translation unit info */
635 ST_FUNC
void tcc_debug_end(TCCState
*s1
)
639 put_stabs_r(s1
, NULL
, N_SO
, 0, 0,
640 text_section
->data_offset
, text_section
, section_sym
);
641 tcc_free(debug_hash
);
646 static BufferedFile
* put_new_file(TCCState
*s1
)
648 BufferedFile
*f
= file
;
649 /* use upper file if from inline ":asm:" */
650 if (f
->filename
[0] == ':')
653 put_stabs_r(s1
, f
->filename
, N_SOL
, 0, 0, ind
, text_section
, section_sym
);
654 new_file
= last_line_num
= 0;
659 /* generate line number info */
660 ST_FUNC
void tcc_debug_line(TCCState
*s1
)
664 || cur_text_section
!= text_section
665 || !(f
= put_new_file(s1
))
666 || last_line_num
== f
->line_num
)
668 if (func_ind
!= -1) {
669 put_stabn(s1
, N_SLINE
, 0, f
->line_num
, ind
- func_ind
);
671 /* from tcc_assemble */
672 put_stabs_r(s1
, NULL
, N_SLINE
, 0, f
->line_num
, ind
, text_section
, section_sym
);
674 last_line_num
= f
->line_num
;
677 /* put function symbol */
678 ST_FUNC
void tcc_debug_funcstart(TCCState
*s1
, Sym
*sym
)
681 if (!s1
->do_debug
|| !(f
= put_new_file(s1
)))
683 tcc_debug_stabn(N_LBRAC
, ind
- func_ind
);
684 cstr_reset (&debug_str
);
685 cstr_printf(&debug_str
, "%s:%c", funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
686 tcc_get_debug_info(sym
->type
.ref
, &debug_str
);
687 put_stabs_r(s1
, debug_str
.data
, N_FUN
, 0, f
->line_num
, 0, cur_text_section
, sym
->c
);
691 /* put function size */
692 ST_FUNC
void tcc_debug_funcend(TCCState
*s1
, int size
)
696 tcc_debug_stabn(N_RBRAC
, size
);
697 tcc_debug_finish (debug_info_root
);
698 debug_info_root
= NULL
;
700 cstr_free (&debug_str
);
703 /* put alternative filename */
704 ST_FUNC
void tcc_debug_putfile(TCCState
*s1
, const char *filename
)
706 if (0 == strcmp(file
->filename
, filename
))
708 pstrcpy(file
->filename
, sizeof(file
->filename
), filename
);
712 /* begin of #include */
713 ST_FUNC
void tcc_debug_bincl(TCCState
*s1
)
717 put_stabs(s1
, file
->filename
, N_BINCL
, 0, 0, 0);
721 /* end of #include */
722 ST_FUNC
void tcc_debug_eincl(TCCState
*s1
)
726 put_stabn(s1
, N_EINCL
, 0, 0, 0);
730 /* ------------------------------------------------------------------------- */
731 /* initialize vstack and types. This must be done also for tcc -E */
732 ST_FUNC
void tccgen_init(TCCState
*s1
)
735 memset(vtop
, 0, sizeof *vtop
);
737 /* define some often used types */
739 char_pointer_type
.t
= VT_BYTE
;
740 mk_pointer(&char_pointer_type
);
741 func_old_type
.t
= VT_FUNC
;
742 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, 0, 0);
743 func_old_type
.ref
->f
.func_call
= FUNC_CDECL
;
744 func_old_type
.ref
->f
.func_type
= FUNC_OLD
;
745 #ifdef precedence_parser
750 ST_FUNC
int tccgen_compile(TCCState
*s1
)
752 cur_text_section
= NULL
;
754 anon_sym
= SYM_FIRST_ANOM
;
757 nocode_wanted
= 0x80000000;
761 #ifdef TCC_TARGET_ARM
765 printf("%s: **** new file\n", file
->filename
);
767 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
| PARSE_FLAG_TOK_STR
;
770 gen_inline_functions(s1
);
772 /* end of translation unit info */
777 ST_FUNC
void tccgen_finish(TCCState
*s1
)
779 free_inline_functions(s1
);
780 sym_pop(&global_stack
, NULL
, 0);
781 sym_pop(&local_stack
, NULL
, 0);
782 /* free preprocessor macros */
785 dynarray_reset(&sym_pools
, &nb_sym_pools
);
786 sym_free_first
= NULL
;
789 /* ------------------------------------------------------------------------- */
790 ST_FUNC ElfSym
*elfsym(Sym
*s
)
794 return &((ElfSym
*)symtab_section
->data
)[s
->c
];
797 /* apply storage attributes to Elf symbol */
798 ST_FUNC
void update_storage(Sym
*sym
)
801 int sym_bind
, old_sym_bind
;
807 if (sym
->a
.visibility
)
808 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
811 if (sym
->type
.t
& (VT_STATIC
| VT_INLINE
))
812 sym_bind
= STB_LOCAL
;
813 else if (sym
->a
.weak
)
816 sym_bind
= STB_GLOBAL
;
817 old_sym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
818 if (sym_bind
!= old_sym_bind
) {
819 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, ELFW(ST_TYPE
)(esym
->st_info
));
823 if (sym
->a
.dllimport
)
824 esym
->st_other
|= ST_PE_IMPORT
;
825 if (sym
->a
.dllexport
)
826 esym
->st_other
|= ST_PE_EXPORT
;
830 printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n",
831 get_tok_str(sym
->v
, NULL
),
832 sym_bind
== STB_WEAK
? 'w' : sym_bind
== STB_LOCAL
? 'l' : 'g',
840 /* ------------------------------------------------------------------------- */
841 /* update sym->c so that it points to an external symbol in section
842 'section' with value 'value' */
844 ST_FUNC
void put_extern_sym2(Sym
*sym
, int sh_num
,
845 addr_t value
, unsigned long size
,
846 int can_add_underscore
)
848 int sym_type
, sym_bind
, info
, other
, t
;
852 #ifdef CONFIG_TCC_BCHECK
856 name
= get_tok_str(sym
->v
, NULL
);
857 #ifdef CONFIG_TCC_BCHECK
858 if (tcc_state
->do_bounds_check
) {
859 /* XXX: avoid doing that for statics ? */
860 /* if bound checking is activated, we change some function
861 names by adding the "__bound" prefix */
864 /* XXX: we rely only on malloc hooks */
886 strcpy(buf
, "__bound_");
894 if ((t
& VT_BTYPE
) == VT_FUNC
) {
896 } else if ((t
& VT_BTYPE
) == VT_VOID
) {
897 sym_type
= STT_NOTYPE
;
899 sym_type
= STT_OBJECT
;
901 if (t
& (VT_STATIC
| VT_INLINE
))
902 sym_bind
= STB_LOCAL
;
904 sym_bind
= STB_GLOBAL
;
907 if (sym_type
== STT_FUNC
&& sym
->type
.ref
) {
908 Sym
*ref
= sym
->type
.ref
;
909 if (ref
->a
.nodecorate
) {
910 can_add_underscore
= 0;
912 if (ref
->f
.func_call
== FUNC_STDCALL
&& can_add_underscore
) {
913 sprintf(buf1
, "_%s@%d", name
, ref
->f
.func_args
* PTR_SIZE
);
915 other
|= ST_PE_STDCALL
;
916 can_add_underscore
= 0;
920 if (tcc_state
->leading_underscore
&& can_add_underscore
) {
922 pstrcpy(buf1
+ 1, sizeof(buf1
) - 1, name
);
926 name
= get_tok_str(sym
->asm_label
, NULL
);
927 info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
928 sym
->c
= put_elf_sym(symtab_section
, value
, size
, info
, other
, sh_num
, name
);
929 if (tcc_state
->do_debug
&& sym_type
!= STT_FUNC
&& sym
->v
< SYM_FIRST_ANOM
) {
933 cstr_printf (&str
, "%s:%c", get_tok_str(sym
->v
, NULL
),
934 debug_info
? 'V' : sym_bind
== STB_GLOBAL
? 'G' : 'S');
935 tcc_get_debug_info(sym
, &str
);
936 if (sym_bind
== STB_GLOBAL
)
937 tcc_debug_stabs(str
.data
, N_GSYM
, 0, NULL
, 0);
939 tcc_debug_stabs(str
.data
,
940 (t
& VT_STATIC
) && data_section
->sh_num
== sh_num
941 ? N_STSYM
: N_LCSYM
, 0,
942 data_section
->sh_num
== sh_num
? data_section
:
943 bss_section
->sh_num
== sh_num
? bss_section
:
944 common_section
->sh_num
== sh_num
? common_section
:
945 text_section
, sym
->c
);
950 esym
->st_value
= value
;
951 esym
->st_size
= size
;
952 esym
->st_shndx
= sh_num
;
957 ST_FUNC
void put_extern_sym(Sym
*sym
, Section
*section
,
958 addr_t value
, unsigned long size
)
960 int sh_num
= section
? section
->sh_num
: SHN_UNDEF
;
961 put_extern_sym2(sym
, sh_num
, value
, size
, 1);
964 /* add a new relocation entry to symbol 'sym' in section 's' */
965 ST_FUNC
void greloca(Section
*s
, Sym
*sym
, unsigned long offset
, int type
,
970 if (nocode_wanted
&& s
== cur_text_section
)
975 put_extern_sym(sym
, NULL
, 0, 0);
979 /* now we can add ELF relocation info */
980 put_elf_reloca(symtab_section
, s
, offset
, type
, c
, addend
);
984 ST_FUNC
void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
986 greloca(s
, sym
, offset
, type
, 0);
990 /* ------------------------------------------------------------------------- */
991 /* symbol allocator */
992 static Sym
*__sym_malloc(void)
994 Sym
*sym_pool
, *sym
, *last_sym
;
997 sym_pool
= tcc_malloc(SYM_POOL_NB
* sizeof(Sym
));
998 dynarray_add(&sym_pools
, &nb_sym_pools
, sym_pool
);
1000 last_sym
= sym_free_first
;
1002 for(i
= 0; i
< SYM_POOL_NB
; i
++) {
1003 sym
->next
= last_sym
;
1007 sym_free_first
= last_sym
;
1011 static inline Sym
*sym_malloc(void)
1015 sym
= sym_free_first
;
1017 sym
= __sym_malloc();
1018 sym_free_first
= sym
->next
;
1021 sym
= tcc_malloc(sizeof(Sym
));
1026 ST_INLN
void sym_free(Sym
*sym
)
1029 sym
->next
= sym_free_first
;
1030 sym_free_first
= sym
;
1036 /* push, without hashing */
1037 ST_FUNC Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1042 memset(s
, 0, sizeof *s
);
1052 /* find a symbol and return its associated structure. 's' is the top
1053 of the symbol stack */
1054 ST_FUNC Sym
*sym_find2(Sym
*s
, int v
)
1059 else if (s
->v
== -1)
1066 /* structure lookup */
1067 ST_INLN Sym
*struct_find(int v
)
1070 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1072 return table_ident
[v
]->sym_struct
;
1075 /* find an identifier */
1076 ST_INLN Sym
*sym_find(int v
)
1079 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1081 return table_ident
[v
]->sym_identifier
;
1084 static int sym_scope(Sym
*s
)
1086 if (IS_ENUM_VAL (s
->type
.t
))
1087 return s
->type
.ref
->sym_scope
;
1089 return s
->sym_scope
;
1092 /* push a given symbol on the symbol stack */
1093 ST_FUNC Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1102 s
= sym_push2(ps
, v
, type
->t
, c
);
1103 s
->type
.ref
= type
->ref
;
1105 /* don't record fields or anonymous symbols */
1107 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1108 /* record symbol in token array */
1109 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1111 ps
= &ts
->sym_struct
;
1113 ps
= &ts
->sym_identifier
;
1116 s
->sym_scope
= local_scope
;
1117 if (s
->prev_tok
&& sym_scope(s
->prev_tok
) == s
->sym_scope
)
1118 tcc_error("redeclaration of '%s'",
1119 get_tok_str(v
& ~SYM_STRUCT
, NULL
));
1124 /* push a global identifier */
1125 ST_FUNC Sym
*global_identifier_push(int v
, int t
, int c
)
1128 s
= sym_push2(&global_stack
, v
, t
, c
);
1129 s
->r
= VT_CONST
| VT_SYM
;
1130 /* don't record anonymous symbol */
1131 if (v
< SYM_FIRST_ANOM
) {
1132 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1133 /* modify the top most local identifier, so that sym_identifier will
1134 point to 's' when popped; happens when called from inline asm */
1135 while (*ps
!= NULL
&& (*ps
)->sym_scope
)
1136 ps
= &(*ps
)->prev_tok
;
1143 /* pop symbols until top reaches 'b'. If KEEP is non-zero don't really
1144 pop them yet from the list, but do remove them from the token array. */
1145 ST_FUNC
void sym_pop(Sym
**ptop
, Sym
*b
, int keep
)
1155 /* remove symbol in token array */
1157 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1158 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1160 ps
= &ts
->sym_struct
;
1162 ps
= &ts
->sym_identifier
;
1173 /* ------------------------------------------------------------------------- */
1174 static void vcheck_cmp(void)
1176 /* cannot let cpu flags if other instruction are generated. Also
1177 avoid leaving VT_JMP anywhere except on the top of the stack
1178 because it would complicate the code generator.
1180 Don't do this when nocode_wanted. vtop might come from
1181 !nocode_wanted regions (see 88_codeopt.c) and transforming
1182 it to a register without actually generating code is wrong
1183 as their value might still be used for real. All values
1184 we push under nocode_wanted will eventually be popped
1185 again, so that the VT_CMP/VT_JMP value will be in vtop
1186 when code is unsuppressed again. */
1188 if (vtop
->r
== VT_CMP
&& !nocode_wanted
)
1192 static void vsetc(CType
*type
, int r
, CValue
*vc
)
1194 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
1195 tcc_error("memory full (vstack)");
1200 vtop
->r2
= VT_CONST
;
1205 ST_FUNC
void vswap(void)
1215 /* pop stack value */
1216 ST_FUNC
void vpop(void)
1219 v
= vtop
->r
& VT_VALMASK
;
1220 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1221 /* for x86, we need to pop the FP stack */
1222 if (v
== TREG_ST0
) {
1223 o(0xd8dd); /* fstp %st(0) */
1227 /* need to put correct jump if && or || without test */
1234 /* push constant of type "type" with useless value */
1235 static void vpush(CType
*type
)
1237 vset(type
, VT_CONST
, 0);
1240 /* push arbitrary 64bit constant */
1241 static void vpush64(int ty
, unsigned long long v
)
1248 vsetc(&ctype
, VT_CONST
, &cval
);
1251 /* push integer constant */
1252 ST_FUNC
void vpushi(int v
)
1257 /* push a pointer sized constant */
1258 static void vpushs(addr_t v
)
1260 vpush64(VT_SIZE_T
, v
);
1263 /* push long long constant */
1264 static inline void vpushll(long long v
)
1266 vpush64(VT_LLONG
, v
);
1269 ST_FUNC
void vset(CType
*type
, int r
, int v
)
1273 vsetc(type
, r
, &cval
);
1276 static void vseti(int r
, int v
)
1284 ST_FUNC
void vpushv(SValue
*v
)
1286 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
1287 tcc_error("memory full (vstack)");
1292 static void vdup(void)
1297 /* rotate n first stack elements to the bottom
1298 I1 ... In -> I2 ... In I1 [top is right]
1300 ST_FUNC
void vrotb(int n
)
1307 for(i
=-n
+1;i
!=0;i
++)
1308 vtop
[i
] = vtop
[i
+1];
1312 /* rotate the n elements before entry e towards the top
1313 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1315 ST_FUNC
void vrote(SValue
*e
, int n
)
1322 for(i
= 0;i
< n
- 1; i
++)
1327 /* rotate n first stack elements to the top
1328 I1 ... In -> In I1 ... I(n-1) [top is right]
1330 ST_FUNC
void vrott(int n
)
1335 /* ------------------------------------------------------------------------- */
1336 /* vtop->r = VT_CMP means CPU-flags have been set from comparison or test. */
1338 /* called from generators to set the result from relational ops */
1339 ST_FUNC
void vset_VT_CMP(int op
)
1347 /* called once before asking generators to load VT_CMP to a register */
1348 static void vset_VT_JMP(void)
1350 int op
= vtop
->cmp_op
;
1352 if (vtop
->jtrue
|| vtop
->jfalse
) {
1353 /* we need to jump to 'mov $0,%R' or 'mov $1,%R' */
1354 int inv
= op
& (op
< 2); /* small optimization */
1355 vseti(VT_JMP
+inv
, gvtst(inv
, 0));
1357 /* otherwise convert flags (rsp. 0/1) to register */
1359 if (op
< 2) /* doesn't seem to happen */
1364 /* Set CPU Flags, doesn't yet jump */
1365 static void gvtst_set(int inv
, int t
)
1369 if (vtop
->r
!= VT_CMP
) {
1372 if (vtop
->r
!= VT_CMP
) /* must be VT_CONST then */
1373 vset_VT_CMP(vtop
->c
.i
!= 0);
1376 p
= inv
? &vtop
->jfalse
: &vtop
->jtrue
;
1377 *p
= gjmp_append(*p
, t
);
1380 /* Generate value test
1382 * Generate a test for any value (jump, comparison and integers) */
1383 static int gvtst(int inv
, int t
)
1388 t
= vtop
->jtrue
, u
= vtop
->jfalse
;
1390 x
= u
, u
= t
, t
= x
;
1393 /* jump to the wanted target */
1395 t
= gjmp_cond(op
^ inv
, t
);
1398 /* resolve complementary jumps to here */
1405 /* generate a zero or nozero test */
1406 static void gen_test_zero(int op
)
1408 if (vtop
->r
== VT_CMP
) {
1412 vtop
->jfalse
= vtop
->jtrue
;
1422 /* ------------------------------------------------------------------------- */
1423 /* push a symbol value of TYPE */
1424 static inline void vpushsym(CType
*type
, Sym
*sym
)
1428 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
1432 /* Return a static symbol pointing to a section */
1433 ST_FUNC Sym
*get_sym_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
1439 sym
= sym_push(v
, type
, VT_CONST
| VT_SYM
, 0);
1440 sym
->type
.t
|= VT_STATIC
;
1441 put_extern_sym(sym
, sec
, offset
, size
);
1445 /* push a reference to a section offset by adding a dummy symbol */
1446 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
1448 vpushsym(type
, get_sym_ref(type
, sec
, offset
, size
));
1451 /* define a new external reference to a symbol 'v' of type 'u' */
1452 ST_FUNC Sym
*external_global_sym(int v
, CType
*type
)
1458 /* push forward reference */
1459 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
1460 s
->type
.ref
= type
->ref
;
1461 } else if (IS_ASM_SYM(s
)) {
1462 s
->type
.t
= type
->t
| (s
->type
.t
& VT_EXTERN
);
1463 s
->type
.ref
= type
->ref
;
1469 /* Merge symbol attributes. */
1470 static void merge_symattr(struct SymAttr
*sa
, struct SymAttr
*sa1
)
1472 if (sa1
->aligned
&& !sa
->aligned
)
1473 sa
->aligned
= sa1
->aligned
;
1474 sa
->packed
|= sa1
->packed
;
1475 sa
->weak
|= sa1
->weak
;
1476 if (sa1
->visibility
!= STV_DEFAULT
) {
1477 int vis
= sa
->visibility
;
1478 if (vis
== STV_DEFAULT
1479 || vis
> sa1
->visibility
)
1480 vis
= sa1
->visibility
;
1481 sa
->visibility
= vis
;
1483 sa
->dllexport
|= sa1
->dllexport
;
1484 sa
->nodecorate
|= sa1
->nodecorate
;
1485 sa
->dllimport
|= sa1
->dllimport
;
1488 /* Merge function attributes. */
1489 static void merge_funcattr(struct FuncAttr
*fa
, struct FuncAttr
*fa1
)
1491 if (fa1
->func_call
&& !fa
->func_call
)
1492 fa
->func_call
= fa1
->func_call
;
1493 if (fa1
->func_type
&& !fa
->func_type
)
1494 fa
->func_type
= fa1
->func_type
;
1495 if (fa1
->func_args
&& !fa
->func_args
)
1496 fa
->func_args
= fa1
->func_args
;
1499 /* Merge attributes. */
1500 static void merge_attr(AttributeDef
*ad
, AttributeDef
*ad1
)
1502 merge_symattr(&ad
->a
, &ad1
->a
);
1503 merge_funcattr(&ad
->f
, &ad1
->f
);
1506 ad
->section
= ad1
->section
;
1507 if (ad1
->alias_target
)
1508 ad
->alias_target
= ad1
->alias_target
;
1510 ad
->asm_label
= ad1
->asm_label
;
1512 ad
->attr_mode
= ad1
->attr_mode
;
1515 /* Merge some type attributes. */
1516 static void patch_type(Sym
*sym
, CType
*type
)
1518 if (!(type
->t
& VT_EXTERN
) || IS_ENUM_VAL(sym
->type
.t
)) {
1519 if (!(sym
->type
.t
& VT_EXTERN
))
1520 tcc_error("redefinition of '%s'", get_tok_str(sym
->v
, NULL
));
1521 sym
->type
.t
&= ~VT_EXTERN
;
1524 if (IS_ASM_SYM(sym
)) {
1525 /* stay static if both are static */
1526 sym
->type
.t
= type
->t
& (sym
->type
.t
| ~VT_STATIC
);
1527 sym
->type
.ref
= type
->ref
;
1530 if (!is_compatible_types(&sym
->type
, type
)) {
1531 tcc_error("incompatible types for redefinition of '%s'",
1532 get_tok_str(sym
->v
, NULL
));
1534 } else if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
) {
1535 int static_proto
= sym
->type
.t
& VT_STATIC
;
1536 /* warn if static follows non-static function declaration */
1537 if ((type
->t
& VT_STATIC
) && !static_proto
1538 /* XXX this test for inline shouldn't be here. Until we
1539 implement gnu-inline mode again it silences a warning for
1540 mingw caused by our workarounds. */
1541 && !((type
->t
| sym
->type
.t
) & VT_INLINE
))
1542 tcc_warning("static storage ignored for redefinition of '%s'",
1543 get_tok_str(sym
->v
, NULL
));
1545 /* set 'inline' if both agree or if one has static */
1546 if ((type
->t
| sym
->type
.t
) & VT_INLINE
) {
1547 if (!((type
->t
^ sym
->type
.t
) & VT_INLINE
)
1548 || ((type
->t
| sym
->type
.t
) & VT_STATIC
))
1549 static_proto
|= VT_INLINE
;
1552 if (0 == (type
->t
& VT_EXTERN
)) {
1553 /* put complete type, use static from prototype */
1554 sym
->type
.t
= (type
->t
& ~(VT_STATIC
|VT_INLINE
)) | static_proto
;
1555 sym
->type
.ref
= type
->ref
;
1557 sym
->type
.t
&= ~VT_INLINE
| static_proto
;
1560 if (sym
->type
.ref
->f
.func_type
== FUNC_OLD
1561 && type
->ref
->f
.func_type
!= FUNC_OLD
) {
1562 sym
->type
.ref
= type
->ref
;
1566 if ((sym
->type
.t
& VT_ARRAY
) && type
->ref
->c
>= 0) {
1567 /* set array size if it was omitted in extern declaration */
1568 sym
->type
.ref
->c
= type
->ref
->c
;
1570 if ((type
->t
^ sym
->type
.t
) & VT_STATIC
)
1571 tcc_warning("storage mismatch for redefinition of '%s'",
1572 get_tok_str(sym
->v
, NULL
));
1576 /* Merge some storage attributes. */
1577 static void patch_storage(Sym
*sym
, AttributeDef
*ad
, CType
*type
)
1580 patch_type(sym
, type
);
1582 #ifdef TCC_TARGET_PE
1583 if (sym
->a
.dllimport
!= ad
->a
.dllimport
)
1584 tcc_error("incompatible dll linkage for redefinition of '%s'",
1585 get_tok_str(sym
->v
, NULL
));
1587 merge_symattr(&sym
->a
, &ad
->a
);
1589 sym
->asm_label
= ad
->asm_label
;
1590 update_storage(sym
);
1593 /* copy sym to other stack */
1594 static Sym
*sym_copy(Sym
*s0
, Sym
**ps
)
1597 s
= sym_malloc(), *s
= *s0
;
1598 s
->prev
= *ps
, *ps
= s
;
1599 if (s
->v
< SYM_FIRST_ANOM
) {
1600 ps
= &table_ident
[s
->v
- TOK_IDENT
]->sym_identifier
;
1601 s
->prev_tok
= *ps
, *ps
= s
;
1606 /* copy s->type.ref to stack 'ps' for VT_FUNC and VT_PTR */
1607 static void sym_copy_ref(Sym
*s
, Sym
**ps
)
1609 int bt
= s
->type
.t
& VT_BTYPE
;
1610 if (bt
== VT_FUNC
|| bt
== VT_PTR
) {
1611 Sym
**sp
= &s
->type
.ref
;
1612 for (s
= *sp
, *sp
= NULL
; s
; s
= s
->next
) {
1613 Sym
*s2
= sym_copy(s
, ps
);
1614 sp
= &(*sp
= s2
)->next
;
1615 sym_copy_ref(s2
, ps
);
1620 /* define a new external reference to a symbol 'v' */
1621 static Sym
*external_sym(int v
, CType
*type
, int r
, AttributeDef
*ad
)
1625 /* look for global symbol */
1627 while (s
&& s
->sym_scope
)
1631 /* push forward reference */
1632 s
= global_identifier_push(v
, type
->t
, 0);
1635 s
->asm_label
= ad
->asm_label
;
1636 s
->type
.ref
= type
->ref
;
1637 /* copy type to the global stack */
1639 sym_copy_ref(s
, &global_stack
);
1641 patch_storage(s
, ad
, type
);
1643 /* push variables on local_stack if any */
1644 if (local_stack
&& (s
->type
.t
& VT_BTYPE
) != VT_FUNC
)
1645 s
= sym_copy(s
, &local_stack
);
1649 /* push a reference to global symbol v */
1650 ST_FUNC
void vpush_global_sym(CType
*type
, int v
)
1652 vpushsym(type
, external_global_sym(v
, type
));
1655 /* save registers up to (vtop - n) stack entry */
1656 ST_FUNC
void save_regs(int n
)
1659 for(p
= vstack
, p1
= vtop
- n
; p
<= p1
; p
++)
1663 /* save r to the memory stack, and mark it as being free */
1664 ST_FUNC
void save_reg(int r
)
1666 save_reg_upstack(r
, 0);
1669 /* save r to the memory stack, and mark it as being free,
1670 if seen up to (vtop - n) stack entry */
1671 ST_FUNC
void save_reg_upstack(int r
, int n
)
1673 int l
, size
, align
, bt
;
1676 if ((r
&= VT_VALMASK
) >= VT_CONST
)
1681 for(p
= vstack
, p1
= vtop
- n
; p
<= p1
; p
++) {
1682 if ((p
->r
& VT_VALMASK
) == r
|| p
->r2
== r
) {
1683 /* must save value on stack if not already done */
1685 bt
= p
->type
.t
& VT_BTYPE
;
1688 if ((p
->r
& VT_LVAL
) || bt
== VT_FUNC
)
1691 size
= type_size(&sv
.type
, &align
);
1692 l
= get_temp_local_var(size
,align
);
1693 sv
.r
= VT_LOCAL
| VT_LVAL
;
1695 store(p
->r
& VT_VALMASK
, &sv
);
1696 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1697 /* x86 specific: need to pop fp register ST0 if saved */
1698 if (r
== TREG_ST0
) {
1699 o(0xd8dd); /* fstp %st(0) */
1702 /* special long long case */
1703 if (p
->r2
< VT_CONST
&& USING_TWO_WORDS(bt
)) {
1708 /* mark that stack entry as being saved on the stack */
1709 if (p
->r
& VT_LVAL
) {
1710 /* also clear the bounded flag because the
1711 relocation address of the function was stored in
1713 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
1715 p
->r
= VT_LVAL
| VT_LOCAL
;
1723 #ifdef TCC_TARGET_ARM
1724 /* find a register of class 'rc2' with at most one reference on stack.
1725 * If none, call get_reg(rc) */
1726 ST_FUNC
int get_reg_ex(int rc
, int rc2
)
1731 for(r
=0;r
<NB_REGS
;r
++) {
1732 if (reg_classes
[r
] & rc2
) {
1735 for(p
= vstack
; p
<= vtop
; p
++) {
1736 if ((p
->r
& VT_VALMASK
) == r
||
1748 /* find a free register of class 'rc'. If none, save one register */
1749 ST_FUNC
int get_reg(int rc
)
1754 /* find a free register */
1755 for(r
=0;r
<NB_REGS
;r
++) {
1756 if (reg_classes
[r
] & rc
) {
1759 for(p
=vstack
;p
<=vtop
;p
++) {
1760 if ((p
->r
& VT_VALMASK
) == r
||
1769 /* no register left : free the first one on the stack (VERY
1770 IMPORTANT to start from the bottom to ensure that we don't
1771 spill registers used in gen_opi()) */
1772 for(p
=vstack
;p
<=vtop
;p
++) {
1773 /* look at second register (if long long) */
1775 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
1777 r
= p
->r
& VT_VALMASK
;
1778 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
1784 /* Should never comes here */
1788 /* find a free temporary local variable (return the offset on stack) match the size and align. If none, add new temporary stack variable*/
1789 static int get_temp_local_var(int size
,int align
){
1791 struct temp_local_variable
*temp_var
;
1798 for(i
=0;i
<nb_temp_local_vars
;i
++){
1799 temp_var
=&arr_temp_local_vars
[i
];
1800 if(temp_var
->size
<size
||align
!=temp_var
->align
){
1803 /*check if temp_var is free*/
1805 for(p
=vstack
;p
<=vtop
;p
++) {
1807 if(r
==VT_LOCAL
||r
==VT_LLOCAL
){
1808 if(p
->c
.i
==temp_var
->location
){
1815 found_var
=temp_var
->location
;
1821 loc
= (loc
- size
) & -align
;
1822 if(nb_temp_local_vars
<MAX_TEMP_LOCAL_VARIABLE_NUMBER
){
1823 temp_var
=&arr_temp_local_vars
[i
];
1824 temp_var
->location
=loc
;
1825 temp_var
->size
=size
;
1826 temp_var
->align
=align
;
1827 nb_temp_local_vars
++;
1834 static void clear_temp_local_var_list(){
1835 nb_temp_local_vars
=0;
1838 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
1840 static void move_reg(int r
, int s
, int t
)
1854 /* get address of vtop (vtop MUST BE an lvalue) */
1855 ST_FUNC
void gaddrof(void)
1857 vtop
->r
&= ~VT_LVAL
;
1858 /* tricky: if saved lvalue, then we can go back to lvalue */
1859 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
1860 vtop
->r
= (vtop
->r
& ~VT_VALMASK
) | VT_LOCAL
| VT_LVAL
;
1863 #ifdef CONFIG_TCC_BCHECK
1864 /* generate lvalue bound code */
1865 static void gbound(void)
1869 vtop
->r
&= ~VT_MUSTBOUND
;
1870 /* if lvalue, then use checking code before dereferencing */
1871 if (vtop
->r
& VT_LVAL
) {
1872 /* if not VT_BOUNDED value, then make one */
1873 if (!(vtop
->r
& VT_BOUNDED
)) {
1874 /* must save type because we must set it to int to get pointer */
1876 vtop
->type
.t
= VT_PTR
;
1879 gen_bounded_ptr_add();
1883 /* then check for dereferencing */
1884 gen_bounded_ptr_deref();
1888 /* we need to call __bound_ptr_add before we start to load function
1889 args into registers */
1890 ST_FUNC
void gbound_args(int nb_args
)
1893 for (i
= 1; i
<= nb_args
; ++i
)
1894 if (vtop
[1 - i
].r
& VT_MUSTBOUND
) {
1901 /* Add bounds for local symbols from S to E (via ->prev) */
1902 static void add_local_bounds(Sym
*s
, Sym
*e
)
1904 for (; s
!= e
; s
= s
->prev
) {
1905 if (!s
->v
|| (s
->r
& VT_VALMASK
) != VT_LOCAL
)
1907 /* Add arrays/structs/unions because we always take address */
1908 if ((s
->type
.t
& VT_ARRAY
)
1909 || (s
->type
.t
& VT_BTYPE
) == VT_STRUCT
1910 || s
->a
.addrtaken
) {
1911 /* add local bound info */
1912 int align
, size
= type_size(&s
->type
, &align
);
1913 addr_t
*bounds_ptr
= section_ptr_add(lbounds_section
,
1914 2 * sizeof(addr_t
));
1915 bounds_ptr
[0] = s
->c
;
1916 bounds_ptr
[1] = size
;
1922 /* Wrapper around sym_pop, that potentially also registers local bounds. */
1923 static void pop_local_syms(int param
, Sym
**ptop
, Sym
*b
, int keep
, int ellipsis
)
1925 #ifdef CONFIG_TCC_BCHECK
1926 if (!ellipsis
&& !keep
&& tcc_state
->do_bounds_check
)
1927 add_local_bounds(*ptop
, b
);
1929 tcc_add_debug_info (param
, *ptop
, b
);
1930 sym_pop(ptop
, b
, keep
);
1933 static void incr_bf_adr(int o
)
1935 vtop
->type
= char_pointer_type
;
1939 vtop
->type
.t
= VT_BYTE
| VT_UNSIGNED
;
1943 /* single-byte load mode for packed or otherwise unaligned bitfields */
1944 static void load_packed_bf(CType
*type
, int bit_pos
, int bit_size
)
1947 save_reg_upstack(vtop
->r
, 1);
1948 vpush64(type
->t
& VT_BTYPE
, 0); // B X
1949 bits
= 0, o
= bit_pos
>> 3, bit_pos
&= 7;
1958 vpushi(bit_pos
), gen_op(TOK_SHR
), bit_pos
= 0; // X B Y
1960 vpushi((1 << n
) - 1), gen_op('&');
1963 vpushi(bits
), gen_op(TOK_SHL
);
1966 bits
+= n
, bit_size
-= n
, o
= 1;
1969 if (!(type
->t
& VT_UNSIGNED
)) {
1970 n
= ((type
->t
& VT_BTYPE
) == VT_LLONG
? 64 : 32) - bits
;
1971 vpushi(n
), gen_op(TOK_SHL
);
1972 vpushi(n
), gen_op(TOK_SAR
);
1976 /* single-byte store mode for packed or otherwise unaligned bitfields */
1977 static void store_packed_bf(int bit_pos
, int bit_size
)
1979 int bits
, n
, o
, m
, c
;
1981 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
1983 save_reg_upstack(vtop
->r
, 1);
1984 bits
= 0, o
= bit_pos
>> 3, bit_pos
&= 7;
1986 incr_bf_adr(o
); // X B
1988 c
? vdup() : gv_dup(); // B V X
1991 vpushi(bits
), gen_op(TOK_SHR
);
1993 vpushi(bit_pos
), gen_op(TOK_SHL
);
1998 m
= ((1 << n
) - 1) << bit_pos
;
1999 vpushi(m
), gen_op('&'); // X B V1
2000 vpushv(vtop
-1); // X B V1 B
2001 vpushi(m
& 0x80 ? ~m
& 0x7f : ~m
);
2002 gen_op('&'); // X B V1 B1
2003 gen_op('|'); // X B V2
2005 vdup(), vtop
[-1] = vtop
[-2]; // X B B V2
2006 vstore(), vpop(); // X B
2007 bits
+= n
, bit_size
-= n
, bit_pos
= 0, o
= 1;
2012 static int adjust_bf(SValue
*sv
, int bit_pos
, int bit_size
)
2015 if (0 == sv
->type
.ref
)
2017 t
= sv
->type
.ref
->auxtype
;
2018 if (t
!= -1 && t
!= VT_STRUCT
) {
2019 sv
->type
.t
= (sv
->type
.t
& ~VT_BTYPE
) | t
;
2025 /* store vtop a register belonging to class 'rc'. lvalues are
2026 converted to values. Cannot be used if cannot be converted to
2027 register value (such as structures). */
2028 ST_FUNC
int gv(int rc
)
2030 int r
, r2
, r_ok
, r2_ok
, rc2
, bt
;
2031 int bit_pos
, bit_size
, size
, align
;
2033 /* NOTE: get_reg can modify vstack[] */
2034 if (vtop
->type
.t
& VT_BITFIELD
) {
2037 bit_pos
= BIT_POS(vtop
->type
.t
);
2038 bit_size
= BIT_SIZE(vtop
->type
.t
);
2039 /* remove bit field info to avoid loops */
2040 vtop
->type
.t
&= ~VT_STRUCT_MASK
;
2043 type
.t
= vtop
->type
.t
& VT_UNSIGNED
;
2044 if ((vtop
->type
.t
& VT_BTYPE
) == VT_BOOL
)
2045 type
.t
|= VT_UNSIGNED
;
2047 r
= adjust_bf(vtop
, bit_pos
, bit_size
);
2049 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
)
2054 if (r
== VT_STRUCT
) {
2055 load_packed_bf(&type
, bit_pos
, bit_size
);
2057 int bits
= (type
.t
& VT_BTYPE
) == VT_LLONG
? 64 : 32;
2058 /* cast to int to propagate signedness in following ops */
2060 /* generate shifts */
2061 vpushi(bits
- (bit_pos
+ bit_size
));
2063 vpushi(bits
- bit_size
);
2064 /* NOTE: transformed to SHR if unsigned */
2069 if (is_float(vtop
->type
.t
) &&
2070 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2071 unsigned long offset
;
2072 /* CPUs usually cannot use float constants, so we store them
2073 generically in data segment */
2074 size
= type_size(&vtop
->type
, &align
);
2076 size
= 0, align
= 1;
2077 offset
= section_add(data_section
, size
, align
);
2078 vpush_ref(&vtop
->type
, data_section
, offset
, size
);
2080 init_putv(&vtop
->type
, data_section
, offset
);
2083 #ifdef CONFIG_TCC_BCHECK
2084 if (vtop
->r
& VT_MUSTBOUND
)
2088 bt
= vtop
->type
.t
& VT_BTYPE
;
2090 #ifdef TCC_TARGET_RISCV64
2092 if (bt
== VT_LDOUBLE
&& rc
== RC_FLOAT
)
2095 rc2
= RC2_TYPE(bt
, rc
);
2097 /* need to reload if:
2099 - lvalue (need to dereference pointer)
2100 - already a register, but not in the right class */
2101 r
= vtop
->r
& VT_VALMASK
;
2102 r_ok
= !(vtop
->r
& VT_LVAL
) && (r
< VT_CONST
) && (reg_classes
[r
] & rc
);
2103 r2_ok
= !rc2
|| ((vtop
->r2
< VT_CONST
) && (reg_classes
[vtop
->r2
] & rc2
));
2105 if (!r_ok
|| !r2_ok
) {
2109 int load_type
= (bt
== VT_QFLOAT
) ? VT_DOUBLE
: VT_PTRDIFF_T
;
2110 int original_type
= vtop
->type
.t
;
2112 /* two register type load :
2113 expand to two words temporarily */
2114 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2116 unsigned long long ll
= vtop
->c
.i
;
2117 vtop
->c
.i
= ll
; /* first word */
2119 vtop
->r
= r
; /* save register value */
2120 vpushi(ll
>> 32); /* second word */
2121 } else if (vtop
->r
& VT_LVAL
) {
2122 /* We do not want to modifier the long long pointer here.
2123 So we save any other instances down the stack */
2124 save_reg_upstack(vtop
->r
, 1);
2125 /* load from memory */
2126 vtop
->type
.t
= load_type
;
2129 vtop
[-1].r
= r
; /* save register value */
2130 /* increment pointer to get second word */
2131 vtop
->type
.t
= VT_PTRDIFF_T
;
2136 vtop
->type
.t
= load_type
;
2138 /* move registers */
2141 if (r2_ok
&& vtop
->r2
< VT_CONST
)
2144 vtop
[-1].r
= r
; /* save register value */
2145 vtop
->r
= vtop
[-1].r2
;
2147 /* Allocate second register. Here we rely on the fact that
2148 get_reg() tries first to free r2 of an SValue. */
2152 /* write second register */
2155 vtop
->type
.t
= original_type
;
2157 if (vtop
->r
== VT_CMP
)
2159 /* one register type load */
2164 #ifdef TCC_TARGET_C67
2165 /* uses register pairs for doubles */
2166 if (bt
== VT_DOUBLE
)
2173 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2174 ST_FUNC
void gv2(int rc1
, int rc2
)
2176 /* generate more generic register first. But VT_JMP or VT_CMP
2177 values must be generated first in all cases to avoid possible
2179 if (vtop
->r
!= VT_CMP
&& rc1
<= rc2
) {
2184 /* test if reload is needed for first register */
2185 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
2195 /* test if reload is needed for first register */
2196 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
2203 /* expand 64bit on stack in two ints */
2204 ST_FUNC
void lexpand(void)
2207 u
= vtop
->type
.t
& (VT_DEFSIGN
| VT_UNSIGNED
);
2208 v
= vtop
->r
& (VT_VALMASK
| VT_LVAL
);
2209 if (v
== VT_CONST
) {
2212 } else if (v
== (VT_LVAL
|VT_CONST
) || v
== (VT_LVAL
|VT_LOCAL
)) {
2218 vtop
[0].r
= vtop
[-1].r2
;
2219 vtop
[0].r2
= vtop
[-1].r2
= VT_CONST
;
2221 vtop
[0].type
.t
= vtop
[-1].type
.t
= VT_INT
| u
;
2226 /* build a long long from two ints */
2227 static void lbuild(int t
)
2229 gv2(RC_INT
, RC_INT
);
2230 vtop
[-1].r2
= vtop
[0].r
;
2231 vtop
[-1].type
.t
= t
;
2236 /* convert stack entry to register and duplicate its value in another
2238 static void gv_dup(void)
2244 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2245 if (t
& VT_BITFIELD
) {
2255 /* stack: H L L1 H1 */
2265 /* duplicate value */
2275 /* generate CPU independent (unsigned) long long operations */
2276 static void gen_opl(int op
)
2278 int t
, a
, b
, op1
, c
, i
;
2280 unsigned short reg_iret
= REG_IRET
;
2281 unsigned short reg_lret
= REG_IRE2
;
2287 func
= TOK___divdi3
;
2290 func
= TOK___udivdi3
;
2293 func
= TOK___moddi3
;
2296 func
= TOK___umoddi3
;
2303 /* call generic long long function */
2304 vpush_global_sym(&func_old_type
, func
);
2309 vtop
->r2
= reg_lret
;
2317 //pv("gen_opl A",0,2);
2323 /* stack: L1 H1 L2 H2 */
2328 vtop
[-2] = vtop
[-3];
2331 /* stack: H1 H2 L1 L2 */
2332 //pv("gen_opl B",0,4);
2338 /* stack: H1 H2 L1 L2 ML MH */
2341 /* stack: ML MH H1 H2 L1 L2 */
2345 /* stack: ML MH H1 L2 H2 L1 */
2350 /* stack: ML MH M1 M2 */
2353 } else if (op
== '+' || op
== '-') {
2354 /* XXX: add non carry method too (for MIPS or alpha) */
2360 /* stack: H1 H2 (L1 op L2) */
2363 gen_op(op1
+ 1); /* TOK_xxxC2 */
2366 /* stack: H1 H2 (L1 op L2) */
2369 /* stack: (L1 op L2) H1 H2 */
2371 /* stack: (L1 op L2) (H1 op H2) */
2379 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
2380 t
= vtop
[-1].type
.t
;
2384 /* stack: L H shift */
2386 /* constant: simpler */
2387 /* NOTE: all comments are for SHL. the other cases are
2388 done by swapping words */
2399 if (op
!= TOK_SAR
) {
2432 /* XXX: should provide a faster fallback on x86 ? */
2435 func
= TOK___ashrdi3
;
2438 func
= TOK___lshrdi3
;
2441 func
= TOK___ashldi3
;
2447 /* compare operations */
2453 /* stack: L1 H1 L2 H2 */
2455 vtop
[-1] = vtop
[-2];
2457 /* stack: L1 L2 H1 H2 */
2461 /* when values are equal, we need to compare low words. since
2462 the jump is inverted, we invert the test too. */
2465 else if (op1
== TOK_GT
)
2467 else if (op1
== TOK_ULT
)
2469 else if (op1
== TOK_UGT
)
2479 /* generate non equal test */
2481 vset_VT_CMP(TOK_NE
);
2485 /* compare low. Always unsigned */
2489 else if (op1
== TOK_LE
)
2491 else if (op1
== TOK_GT
)
2493 else if (op1
== TOK_GE
)
2496 #if 0//def TCC_TARGET_I386
2497 if (op
== TOK_NE
) { gsym(b
); break; }
2498 if (op
== TOK_EQ
) { gsym(a
); break; }
2507 static uint64_t gen_opic_sdiv(uint64_t a
, uint64_t b
)
2509 uint64_t x
= (a
>> 63 ? -a
: a
) / (b
>> 63 ? -b
: b
);
2510 return (a
^ b
) >> 63 ? -x
: x
;
2513 static int gen_opic_lt(uint64_t a
, uint64_t b
)
2515 return (a
^ (uint64_t)1 << 63) < (b
^ (uint64_t)1 << 63);
2518 /* handle integer constant optimizations and various machine
2520 static void gen_opic(int op
)
2522 SValue
*v1
= vtop
- 1;
2524 int t1
= v1
->type
.t
& VT_BTYPE
;
2525 int t2
= v2
->type
.t
& VT_BTYPE
;
2526 int c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2527 int c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2528 uint64_t l1
= c1
? v1
->c
.i
: 0;
2529 uint64_t l2
= c2
? v2
->c
.i
: 0;
2530 int shm
= (t1
== VT_LLONG
) ? 63 : 31;
2532 if (t1
!= VT_LLONG
&& (PTR_SIZE
!= 8 || t1
!= VT_PTR
))
2533 l1
= ((uint32_t)l1
|
2534 (v1
->type
.t
& VT_UNSIGNED
? 0 : -(l1
& 0x80000000)));
2535 if (t2
!= VT_LLONG
&& (PTR_SIZE
!= 8 || t2
!= VT_PTR
))
2536 l2
= ((uint32_t)l2
|
2537 (v2
->type
.t
& VT_UNSIGNED
? 0 : -(l2
& 0x80000000)));
2541 case '+': l1
+= l2
; break;
2542 case '-': l1
-= l2
; break;
2543 case '&': l1
&= l2
; break;
2544 case '^': l1
^= l2
; break;
2545 case '|': l1
|= l2
; break;
2546 case '*': l1
*= l2
; break;
2553 /* if division by zero, generate explicit division */
2555 if (const_wanted
&& !(nocode_wanted
& unevalmask
))
2556 tcc_error("division by zero in constant");
2560 default: l1
= gen_opic_sdiv(l1
, l2
); break;
2561 case '%': l1
= l1
- l2
* gen_opic_sdiv(l1
, l2
); break;
2562 case TOK_UDIV
: l1
= l1
/ l2
; break;
2563 case TOK_UMOD
: l1
= l1
% l2
; break;
2566 case TOK_SHL
: l1
<<= (l2
& shm
); break;
2567 case TOK_SHR
: l1
>>= (l2
& shm
); break;
2569 l1
= (l1
>> 63) ? ~(~l1
>> (l2
& shm
)) : l1
>> (l2
& shm
);
2572 case TOK_ULT
: l1
= l1
< l2
; break;
2573 case TOK_UGE
: l1
= l1
>= l2
; break;
2574 case TOK_EQ
: l1
= l1
== l2
; break;
2575 case TOK_NE
: l1
= l1
!= l2
; break;
2576 case TOK_ULE
: l1
= l1
<= l2
; break;
2577 case TOK_UGT
: l1
= l1
> l2
; break;
2578 case TOK_LT
: l1
= gen_opic_lt(l1
, l2
); break;
2579 case TOK_GE
: l1
= !gen_opic_lt(l1
, l2
); break;
2580 case TOK_LE
: l1
= !gen_opic_lt(l2
, l1
); break;
2581 case TOK_GT
: l1
= gen_opic_lt(l2
, l1
); break;
2583 case TOK_LAND
: l1
= l1
&& l2
; break;
2584 case TOK_LOR
: l1
= l1
|| l2
; break;
2588 if (t1
!= VT_LLONG
&& (PTR_SIZE
!= 8 || t1
!= VT_PTR
))
2589 l1
= ((uint32_t)l1
|
2590 (v1
->type
.t
& VT_UNSIGNED
? 0 : -(l1
& 0x80000000)));
2594 /* if commutative ops, put c2 as constant */
2595 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
2596 op
== '|' || op
== '*' || op
== TOK_EQ
|| op
== TOK_NE
)) {
2598 c2
= c1
; //c = c1, c1 = c2, c2 = c;
2599 l2
= l1
; //l = l1, l1 = l2, l2 = l;
2601 if (!const_wanted
&&
2603 (op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
)) ||
2604 (l1
== -1 && op
== TOK_SAR
))) {
2605 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
2607 } else if (!const_wanted
&&
2608 c2
&& ((l2
== 0 && (op
== '&' || op
== '*')) ||
2610 (l2
== -1 || (l2
== 0xFFFFFFFF && t2
!= VT_LLONG
))) ||
2611 (l2
== 1 && (op
== '%' || op
== TOK_UMOD
)))) {
2612 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
2617 } else if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
2620 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
2621 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
2624 (l2
== -1 || (l2
== 0xFFFFFFFF && t2
!= VT_LLONG
))))) {
2625 /* filter out NOP operations like x*1, x-0, x&-1... */
2627 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
2628 /* try to use shifts instead of muls or divs */
2629 if (l2
> 0 && (l2
& (l2
- 1)) == 0) {
2638 else if (op
== TOK_PDIV
)
2644 } else if (c2
&& (op
== '+' || op
== '-') &&
2645 (((vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == (VT_CONST
| VT_SYM
))
2646 || (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
)) == VT_LOCAL
)) {
2647 /* symbol + constant case */
2651 /* The backends can't always deal with addends to symbols
2652 larger than +-1<<31. Don't construct such. */
2659 /* call low level op generator */
2660 if (t1
== VT_LLONG
|| t2
== VT_LLONG
||
2661 (PTR_SIZE
== 8 && (t1
== VT_PTR
|| t2
== VT_PTR
)))
2669 /* generate a floating point operation with constant propagation */
2670 static void gen_opif(int op
)
2674 #if defined _MSC_VER && defined __x86_64__
2675 /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
2682 /* currently, we cannot do computations with forward symbols */
2683 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2684 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2686 if (v1
->type
.t
== VT_FLOAT
) {
2689 } else if (v1
->type
.t
== VT_DOUBLE
) {
2697 /* NOTE: we only do constant propagation if finite number (not
2698 NaN or infinity) (ANSI spec) */
2699 if (!ieee_finite(f1
) || !ieee_finite(f2
))
2703 case '+': f1
+= f2
; break;
2704 case '-': f1
-= f2
; break;
2705 case '*': f1
*= f2
; break;
2708 /* If not in initializer we need to potentially generate
2709 FP exceptions at runtime, otherwise we want to fold. */
2715 /* XXX: also handles tests ? */
2719 /* XXX: overflow test ? */
2720 if (v1
->type
.t
== VT_FLOAT
) {
2722 } else if (v1
->type
.t
== VT_DOUBLE
) {
2734 /* print a type. If 'varstr' is not NULL, then the variable is also
2735 printed in the type */
2737 /* XXX: add array and function pointers */
2738 static void type_to_str(char *buf
, int buf_size
,
2739 CType
*type
, const char *varstr
)
2751 pstrcat(buf
, buf_size
, "extern ");
2753 pstrcat(buf
, buf_size
, "static ");
2755 pstrcat(buf
, buf_size
, "typedef ");
2757 pstrcat(buf
, buf_size
, "inline ");
2758 if (t
& VT_VOLATILE
)
2759 pstrcat(buf
, buf_size
, "volatile ");
2760 if (t
& VT_CONSTANT
)
2761 pstrcat(buf
, buf_size
, "const ");
2763 if (((t
& VT_DEFSIGN
) && bt
== VT_BYTE
)
2764 || ((t
& VT_UNSIGNED
)
2765 && (bt
== VT_SHORT
|| bt
== VT_INT
|| bt
== VT_LLONG
)
2768 pstrcat(buf
, buf_size
, (t
& VT_UNSIGNED
) ? "unsigned " : "signed ");
2770 buf_size
-= strlen(buf
);
2806 tstr
= "long double";
2808 pstrcat(buf
, buf_size
, tstr
);
2815 pstrcat(buf
, buf_size
, tstr
);
2816 v
= type
->ref
->v
& ~SYM_STRUCT
;
2817 if (v
>= SYM_FIRST_ANOM
)
2818 pstrcat(buf
, buf_size
, "<anonymous>");
2820 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
2825 if (varstr
&& '*' == *varstr
) {
2826 pstrcat(buf1
, sizeof(buf1
), "(");
2827 pstrcat(buf1
, sizeof(buf1
), varstr
);
2828 pstrcat(buf1
, sizeof(buf1
), ")");
2830 pstrcat(buf1
, buf_size
, "(");
2832 while (sa
!= NULL
) {
2834 type_to_str(buf2
, sizeof(buf2
), &sa
->type
, NULL
);
2835 pstrcat(buf1
, sizeof(buf1
), buf2
);
2838 pstrcat(buf1
, sizeof(buf1
), ", ");
2840 if (s
->f
.func_type
== FUNC_ELLIPSIS
)
2841 pstrcat(buf1
, sizeof(buf1
), ", ...");
2842 pstrcat(buf1
, sizeof(buf1
), ")");
2843 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
2848 if (varstr
&& '*' == *varstr
)
2849 snprintf(buf1
, sizeof(buf1
), "(%s)[%d]", varstr
, s
->c
);
2851 snprintf(buf1
, sizeof(buf1
), "%s[%d]", varstr
? varstr
: "", s
->c
);
2852 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
2855 pstrcpy(buf1
, sizeof(buf1
), "*");
2856 if (t
& VT_CONSTANT
)
2857 pstrcat(buf1
, buf_size
, "const ");
2858 if (t
& VT_VOLATILE
)
2859 pstrcat(buf1
, buf_size
, "volatile ");
2861 pstrcat(buf1
, sizeof(buf1
), varstr
);
2862 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
2866 pstrcat(buf
, buf_size
, " ");
2867 pstrcat(buf
, buf_size
, varstr
);
2872 static void type_incompatibility_error(CType
* st
, CType
* dt
, const char* fmt
)
2874 char buf1
[256], buf2
[256];
2875 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
2876 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
2877 tcc_error(fmt
, buf1
, buf2
);
2880 static void type_incompatibility_warning(CType
* st
, CType
* dt
, const char* fmt
)
2882 char buf1
[256], buf2
[256];
2883 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
2884 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
2885 tcc_warning(fmt
, buf1
, buf2
);
2888 static int pointed_size(CType
*type
)
2891 return type_size(pointed_type(type
), &align
);
2894 static void vla_runtime_pointed_size(CType
*type
)
2897 vla_runtime_type_size(pointed_type(type
), &align
);
2900 static inline int is_null_pointer(SValue
*p
)
2902 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
2904 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& (uint32_t)p
->c
.i
== 0) ||
2905 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.i
== 0) ||
2906 ((p
->type
.t
& VT_BTYPE
) == VT_PTR
&&
2907 (PTR_SIZE
== 4 ? (uint32_t)p
->c
.i
== 0 : p
->c
.i
== 0) &&
2908 ((pointed_type(&p
->type
)->t
& VT_BTYPE
) == VT_VOID
) &&
2909 0 == (pointed_type(&p
->type
)->t
& (VT_CONSTANT
| VT_VOLATILE
))
2913 /* compare function types. OLD functions match any new functions */
2914 static int is_compatible_func(CType
*type1
, CType
*type2
)
2920 if (s1
->f
.func_call
!= s2
->f
.func_call
)
2922 if (s1
->f
.func_type
!= s2
->f
.func_type
2923 && s1
->f
.func_type
!= FUNC_OLD
2924 && s2
->f
.func_type
!= FUNC_OLD
)
2926 /* we should check the function return type for FUNC_OLD too
2927 but that causes problems with the internally used support
2928 functions such as TOK_memmove */
2929 if (s1
->f
.func_type
== FUNC_OLD
&& !s1
->next
)
2931 if (s2
->f
.func_type
== FUNC_OLD
&& !s2
->next
)
2934 if (!is_compatible_unqualified_types(&s1
->type
, &s2
->type
))
2945 /* return true if type1 and type2 are the same. If unqualified is
2946 true, qualifiers on the types are ignored.
2948 static int compare_types(CType
*type1
, CType
*type2
, int unqualified
)
2952 t1
= type1
->t
& VT_TYPE
;
2953 t2
= type2
->t
& VT_TYPE
;
2955 /* strip qualifiers before comparing */
2956 t1
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2957 t2
&= ~(VT_CONSTANT
| VT_VOLATILE
);
2960 /* Default Vs explicit signedness only matters for char */
2961 if ((t1
& VT_BTYPE
) != VT_BYTE
) {
2965 /* XXX: bitfields ? */
2970 && !(type1
->ref
->c
< 0
2971 || type2
->ref
->c
< 0
2972 || type1
->ref
->c
== type2
->ref
->c
))
2975 /* test more complicated cases */
2976 bt1
= t1
& VT_BTYPE
;
2977 if (bt1
== VT_PTR
) {
2978 type1
= pointed_type(type1
);
2979 type2
= pointed_type(type2
);
2980 return is_compatible_types(type1
, type2
);
2981 } else if (bt1
== VT_STRUCT
) {
2982 return (type1
->ref
== type2
->ref
);
2983 } else if (bt1
== VT_FUNC
) {
2984 return is_compatible_func(type1
, type2
);
2985 } else if (IS_ENUM(type1
->t
) || IS_ENUM(type2
->t
)) {
2986 return type1
->ref
== type2
->ref
;
2992 /* Check if OP1 and OP2 can be "combined" with operation OP, the combined
2993 type is stored in DEST if non-null (except for pointer plus/minus) . */
2994 static int combine_types(CType
*dest
, SValue
*op1
, SValue
*op2
, int op
)
2996 CType
*type1
= &op1
->type
, *type2
= &op2
->type
, type
;
2997 int t1
= type1
->t
, t2
= type2
->t
, bt1
= t1
& VT_BTYPE
, bt2
= t2
& VT_BTYPE
;
3003 if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
3004 ret
= op
== '?' ? 1 : 0;
3005 /* NOTE: as an extension, we accept void on only one side */
3007 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3008 if (op
== '+') ; /* Handled in caller */
3009 /* http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6 */
3010 /* If one is a null ptr constant the result type is the other. */
3011 else if (is_null_pointer (op2
)) type
= *type1
;
3012 else if (is_null_pointer (op1
)) type
= *type2
;
3013 else if (bt1
!= bt2
) {
3014 /* accept comparison or cond-expr between pointer and integer
3016 if ((op
== '?' || (op
>= TOK_ULT
&& op
<= TOK_LOR
))
3017 && (is_integer_btype(bt1
) || is_integer_btype(bt2
)))
3018 tcc_warning("pointer/integer mismatch in %s",
3019 op
== '?' ? "conditional expression" : "comparison");
3020 else if (op
!= '-' || !is_integer_btype(bt2
))
3022 type
= *(bt1
== VT_PTR
? type1
: type2
);
3024 CType
*pt1
= pointed_type(type1
);
3025 CType
*pt2
= pointed_type(type2
);
3026 int pbt1
= pt1
->t
& VT_BTYPE
;
3027 int pbt2
= pt2
->t
& VT_BTYPE
;
3028 int newquals
, copied
= 0;
3029 if (pbt1
!= VT_VOID
&& pbt2
!= VT_VOID
3030 && !compare_types(pt1
, pt2
, 1/*unqualif*/)) {
3031 if (op
!= '?' && (op
< TOK_ULT
|| op
> TOK_LOR
))
3034 type_incompatibility_warning(type1
, type2
,
3036 ? "pointer type mismatch in conditional expression ('%s' and '%s')"
3037 : "pointer type mismatch in comparison('%s' and '%s')");
3040 /* pointers to void get preferred, otherwise the
3041 pointed to types minus qualifs should be compatible */
3042 type
= *((pbt1
== VT_VOID
) ? type1
: type2
);
3043 /* combine qualifs */
3044 newquals
= ((pt1
->t
| pt2
->t
) & (VT_CONSTANT
| VT_VOLATILE
));
3045 if ((~pointed_type(&type
)->t
& (VT_CONSTANT
| VT_VOLATILE
))
3048 /* copy the pointer target symbol */
3049 type
.ref
= sym_push(SYM_FIELD
, &type
.ref
->type
,
3052 pointed_type(&type
)->t
|= newquals
;
3054 /* pointers to incomplete arrays get converted to
3055 pointers to completed ones if possible */
3056 if (pt1
->t
& VT_ARRAY
3057 && pt2
->t
& VT_ARRAY
3058 && pointed_type(&type
)->ref
->c
< 0
3059 && (pt1
->ref
->c
> 0 || pt2
->ref
->c
> 0))
3062 type
.ref
= sym_push(SYM_FIELD
, &type
.ref
->type
,
3064 pointed_type(&type
)->ref
=
3065 sym_push(SYM_FIELD
, &pointed_type(&type
)->ref
->type
,
3066 0, pointed_type(&type
)->ref
->c
);
3067 pointed_type(&type
)->ref
->c
=
3068 0 < pt1
->ref
->c
? pt1
->ref
->c
: pt2
->ref
->c
;
3072 if (op
>= TOK_ULT
&& op
<= TOK_LOR
)
3074 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
3075 if (op
!= '?' || !compare_types(type1
, type2
, 1))
3078 } else if (is_float(bt1
) || is_float(bt2
)) {
3079 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3080 type
.t
= VT_LDOUBLE
;
3081 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3086 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3087 /* cast to biggest op */
3088 type
.t
= VT_LLONG
| VT_LONG
;
3089 if (bt1
== VT_LLONG
)
3091 if (bt2
== VT_LLONG
)
3093 /* convert to unsigned if it does not fit in a long long */
3094 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3095 (t2
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_LLONG
| VT_UNSIGNED
))
3096 type
.t
|= VT_UNSIGNED
;
3098 /* integer operations */
3099 type
.t
= VT_INT
| (VT_LONG
& (t1
| t2
));
3100 /* convert to unsigned if it does not fit in an integer */
3101 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_INT
| VT_UNSIGNED
) ||
3102 (t2
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_INT
| VT_UNSIGNED
))
3103 type
.t
|= VT_UNSIGNED
;
3110 /* generic gen_op: handles types problems */
3111 ST_FUNC
void gen_op(int op
)
3113 int u
, t1
, t2
, bt1
, bt2
, t
;
3114 CType type1
, combtype
;
3117 t1
= vtop
[-1].type
.t
;
3118 t2
= vtop
[0].type
.t
;
3119 bt1
= t1
& VT_BTYPE
;
3120 bt2
= t2
& VT_BTYPE
;
3122 if (bt1
== VT_FUNC
|| bt2
== VT_FUNC
) {
3123 if (bt2
== VT_FUNC
) {
3124 mk_pointer(&vtop
->type
);
3127 if (bt1
== VT_FUNC
) {
3129 mk_pointer(&vtop
->type
);
3134 } else if (!combine_types(&combtype
, vtop
- 1, vtop
, op
)) {
3135 tcc_error_noabort("invalid operand types for binary operation");
3137 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3138 /* at least one operand is a pointer */
3139 /* relational op: must be both pointers */
3140 if (op
>= TOK_ULT
&& op
<= TOK_LOR
)
3142 /* if both pointers, then it must be the '-' op */
3143 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
3145 tcc_error("cannot use pointers here");
3146 if (vtop
[-1].type
.t
& VT_VLA
) {
3147 vla_runtime_pointed_size(&vtop
[-1].type
);
3149 vpushi(pointed_size(&vtop
[-1].type
));
3153 vtop
->type
.t
= VT_PTRDIFF_T
;
3157 /* exactly one pointer : must be '+' or '-'. */
3158 if (op
!= '-' && op
!= '+')
3159 tcc_error("cannot use pointers here");
3160 /* Put pointer as first operand */
3161 if (bt2
== VT_PTR
) {
3163 t
= t1
, t1
= t2
, t2
= t
;
3166 if ((vtop
[0].type
.t
& VT_BTYPE
) == VT_LLONG
)
3167 /* XXX: truncate here because gen_opl can't handle ptr + long long */
3170 type1
= vtop
[-1].type
;
3171 type1
.t
&= ~VT_ARRAY
;
3172 if (vtop
[-1].type
.t
& VT_VLA
)
3173 vla_runtime_pointed_size(&vtop
[-1].type
);
3175 u
= pointed_size(&vtop
[-1].type
);
3177 tcc_error("unknown array element size");
3181 /* XXX: cast to int ? (long long case) */
3186 #ifdef CONFIG_TCC_BCHECK
3187 if (tcc_state
->do_bounds_check
&& !const_wanted
) {
3188 /* if bounded pointers, we generate a special code to
3195 gen_bounded_ptr_add();
3201 /* put again type if gen_opic() swaped operands */
3205 /* floats can only be used for a few operations */
3206 if (is_float(combtype
.t
)
3207 && op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/'
3208 && (op
< TOK_ULT
|| op
> TOK_LOR
))
3209 tcc_error("invalid operands for binary operation");
3210 else if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
) {
3211 t
= bt1
== VT_LLONG
? VT_LLONG
: VT_INT
;
3212 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (t
| VT_UNSIGNED
))
3214 t
|= (VT_LONG
& t1
);
3218 t
= t2
= combtype
.t
;
3219 /* XXX: currently, some unsigned operations are explicit, so
3220 we modify them here */
3221 if (t
& VT_UNSIGNED
) {
3228 else if (op
== TOK_LT
)
3230 else if (op
== TOK_GT
)
3232 else if (op
== TOK_LE
)
3234 else if (op
== TOK_GE
)
3240 /* special case for shifts and long long: we keep the shift as
3242 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3249 if (op
>= TOK_ULT
&& op
<= TOK_LOR
) {
3250 /* relational op: the result is an int */
3251 vtop
->type
.t
= VT_INT
;
3256 // Make sure that we have converted to an rvalue:
3257 if (vtop
->r
& VT_LVAL
)
3258 gv(is_float(vtop
->type
.t
& VT_BTYPE
) ? RC_FLOAT
: RC_INT
);
3261 #if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 || defined TCC_TARGET_ARM
3262 #define gen_cvt_itof1 gen_cvt_itof
3264 /* generic itof for unsigned long long case */
3265 static void gen_cvt_itof1(int t
)
3267 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3268 (VT_LLONG
| VT_UNSIGNED
)) {
3271 vpush_global_sym(&func_old_type
, TOK___floatundisf
);
3272 #if LDOUBLE_SIZE != 8
3273 else if (t
== VT_LDOUBLE
)
3274 vpush_global_sym(&func_old_type
, TOK___floatundixf
);
3277 vpush_global_sym(&func_old_type
, TOK___floatundidf
);
3288 #if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
3289 #define gen_cvt_ftoi1 gen_cvt_ftoi
3291 /* generic ftoi for unsigned long long case */
3292 static void gen_cvt_ftoi1(int t
)
3295 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3296 /* not handled natively */
3297 st
= vtop
->type
.t
& VT_BTYPE
;
3299 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
3300 #if LDOUBLE_SIZE != 8
3301 else if (st
== VT_LDOUBLE
)
3302 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
3305 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
3316 /* special delayed cast for char/short */
3317 static void force_charshort_cast(void)
3319 int sbt
= BFGET(vtop
->r
, VT_MUSTCAST
) == 2 ? VT_LLONG
: VT_INT
;
3320 int dbt
= vtop
->type
.t
;
3321 vtop
->r
&= ~VT_MUSTCAST
;
3323 gen_cast_s(dbt
== VT_BOOL
? VT_BYTE
|VT_UNSIGNED
: dbt
);
3327 static void gen_cast_s(int t
)
3335 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
3336 static void gen_cast(CType
*type
)
3338 int sbt
, dbt
, sf
, df
, c
;
3339 int dbt_bt
, sbt_bt
, ds
, ss
, bits
, trunc
;
3341 /* special delayed cast for char/short */
3342 if (vtop
->r
& VT_MUSTCAST
)
3343 force_charshort_cast();
3345 /* bitfields first get cast to ints */
3346 if (vtop
->type
.t
& VT_BITFIELD
)
3349 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3350 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
3358 dbt_bt
= dbt
& VT_BTYPE
;
3359 sbt_bt
= sbt
& VT_BTYPE
;
3361 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3362 #if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
3363 c
&= (dbt
!= VT_LDOUBLE
) | !!nocode_wanted
;
3366 /* constant case: we can do it now */
3367 /* XXX: in ISOC, cannot do it if error in convert */
3368 if (sbt
== VT_FLOAT
)
3369 vtop
->c
.ld
= vtop
->c
.f
;
3370 else if (sbt
== VT_DOUBLE
)
3371 vtop
->c
.ld
= vtop
->c
.d
;
3374 if (sbt_bt
== VT_LLONG
) {
3375 if ((sbt
& VT_UNSIGNED
) || !(vtop
->c
.i
>> 63))
3376 vtop
->c
.ld
= vtop
->c
.i
;
3378 vtop
->c
.ld
= -(long double)-vtop
->c
.i
;
3380 if ((sbt
& VT_UNSIGNED
) || !(vtop
->c
.i
>> 31))
3381 vtop
->c
.ld
= (uint32_t)vtop
->c
.i
;
3383 vtop
->c
.ld
= -(long double)-(uint32_t)vtop
->c
.i
;
3386 if (dbt
== VT_FLOAT
)
3387 vtop
->c
.f
= (float)vtop
->c
.ld
;
3388 else if (dbt
== VT_DOUBLE
)
3389 vtop
->c
.d
= (double)vtop
->c
.ld
;
3390 } else if (sf
&& dbt
== VT_BOOL
) {
3391 vtop
->c
.i
= (vtop
->c
.ld
!= 0);
3394 vtop
->c
.i
= vtop
->c
.ld
;
3395 else if (sbt_bt
== VT_LLONG
|| (PTR_SIZE
== 8 && sbt
== VT_PTR
))
3397 else if (sbt
& VT_UNSIGNED
)
3398 vtop
->c
.i
= (uint32_t)vtop
->c
.i
;
3400 vtop
->c
.i
= ((uint32_t)vtop
->c
.i
| -(vtop
->c
.i
& 0x80000000));
3402 if (dbt_bt
== VT_LLONG
|| (PTR_SIZE
== 8 && dbt
== VT_PTR
))
3404 else if (dbt
== VT_BOOL
)
3405 vtop
->c
.i
= (vtop
->c
.i
!= 0);
3407 uint32_t m
= dbt_bt
== VT_BYTE
? 0xff :
3408 dbt_bt
== VT_SHORT
? 0xffff :
3411 if (!(dbt
& VT_UNSIGNED
))
3412 vtop
->c
.i
|= -(vtop
->c
.i
& ((m
>> 1) + 1));
3417 } else if (dbt
== VT_BOOL
3418 && (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
))
3419 == (VT_CONST
| VT_SYM
)) {
3420 /* addresses are considered non-zero (see tcctest.c:sinit23) */
3426 /* cannot generate code for global or static initializers */
3427 if (STATIC_DATA_WANTED
)
3430 /* non constant case: generate code */
3431 if (dbt
== VT_BOOL
) {
3432 gen_test_zero(TOK_NE
);
3438 /* convert from fp to fp */
3441 /* convert int to fp */
3444 /* convert fp to int */
3446 if (dbt_bt
!= VT_LLONG
&& dbt_bt
!= VT_INT
)
3449 goto again
; /* may need char/short cast */
3454 ds
= btype_size(dbt_bt
);
3455 ss
= btype_size(sbt_bt
);
3456 if (ds
== 0 || ss
== 0) {
3457 if (dbt_bt
== VT_VOID
)
3459 cast_error(&vtop
->type
, type
);
3461 if (IS_ENUM(type
->t
) && type
->ref
->c
< 0)
3462 tcc_error("cast to incomplete type");
3464 /* same size and no sign conversion needed */
3465 if (ds
== ss
&& ds
>= 4)
3467 if (dbt_bt
== VT_PTR
|| sbt_bt
== VT_PTR
) {
3468 tcc_warning("cast between pointer and integer of different size");
3469 if (sbt_bt
== VT_PTR
) {
3470 /* put integer type to allow logical operations below */
3471 vtop
->type
.t
= (PTR_SIZE
== 8 ? VT_LLONG
: VT_INT
);
3475 /* processor allows { int a = 0, b = *(char*)&a; }
3476 That means that if we cast to less width, we can just
3477 change the type and read it still later. */
3478 #define ALLOW_SUBTYPE_ACCESS 1
3480 if (ALLOW_SUBTYPE_ACCESS
&& (vtop
->r
& VT_LVAL
)) {
3481 /* value still in memory */
3487 goto done
; /* no 64bit envolved */
3495 /* generate high word */
3496 if (sbt
& VT_UNSIGNED
) {
3505 } else if (ss
== 8) {
3506 /* from long long: just take low order word */
3514 /* need to convert from 32bit to 64bit */
3515 if (sbt
& VT_UNSIGNED
) {
3516 #if defined(TCC_TARGET_RISCV64)
3517 /* RISC-V keeps 32bit vals in registers sign-extended.
3518 So here we need a zero-extension. */
3527 ss
= ds
, ds
= 4, dbt
= sbt
;
3528 } else if (ss
== 8) {
3529 /* XXX some architectures (e.g. risc-v) would like it
3530 better for this merely being a 32-to-64 sign or zero-
3532 trunc
= 32; /* zero upper 32 bits */
3540 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM64
3546 bits
= (ss
- ds
) * 8;
3547 /* for unsigned, gen_op will convert SAR to SHR */
3548 vtop
->type
.t
= (ss
== 8 ? VT_LLONG
: VT_INT
) | (dbt
& VT_UNSIGNED
);
3551 vpushi(bits
- trunc
);
3558 vtop
->type
.t
&= ~ ( VT_CONSTANT
| VT_VOLATILE
| VT_ARRAY
);
3561 /* return type size as known at compile time. Put alignment at 'a' */
3562 ST_FUNC
int type_size(CType
*type
, int *a
)
3567 bt
= type
->t
& VT_BTYPE
;
3568 if (bt
== VT_STRUCT
) {
3573 } else if (bt
== VT_PTR
) {
3574 if (type
->t
& VT_ARRAY
) {
3578 ts
= type_size(&s
->type
, a
);
3580 if (ts
< 0 && s
->c
< 0)
3588 } else if (IS_ENUM(type
->t
) && type
->ref
->c
< 0) {
3589 return -1; /* incomplete enum */
3590 } else if (bt
== VT_LDOUBLE
) {
3592 return LDOUBLE_SIZE
;
3593 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3594 #ifdef TCC_TARGET_I386
3595 #ifdef TCC_TARGET_PE
3600 #elif defined(TCC_TARGET_ARM)
3610 } else if (bt
== VT_INT
|| bt
== VT_FLOAT
) {
3613 } else if (bt
== VT_SHORT
) {
3616 } else if (bt
== VT_QLONG
|| bt
== VT_QFLOAT
) {
3620 /* char, void, function, _Bool */
3626 /* push type size as known at runtime time on top of value stack. Put
3628 ST_FUNC
void vla_runtime_type_size(CType
*type
, int *a
)
3630 if (type
->t
& VT_VLA
) {
3631 type_size(&type
->ref
->type
, a
);
3632 vset(&int_type
, VT_LOCAL
|VT_LVAL
, type
->ref
->c
);
3634 vpushi(type_size(type
, a
));
3638 /* return the pointed type of t */
3639 static inline CType
*pointed_type(CType
*type
)
3641 return &type
->ref
->type
;
3644 /* modify type so that its it is a pointer to type. */
3645 ST_FUNC
void mk_pointer(CType
*type
)
3648 s
= sym_push(SYM_FIELD
, type
, 0, -1);
3649 type
->t
= VT_PTR
| (type
->t
& VT_STORAGE
);
3653 /* return true if type1 and type2 are exactly the same (including
3656 static int is_compatible_types(CType
*type1
, CType
*type2
)
3658 return compare_types(type1
,type2
,0);
3661 /* return true if type1 and type2 are the same (ignoring qualifiers).
3663 static int is_compatible_unqualified_types(CType
*type1
, CType
*type2
)
3665 return compare_types(type1
,type2
,1);
3668 static void cast_error(CType
*st
, CType
*dt
)
3670 type_incompatibility_error(st
, dt
, "cannot convert '%s' to '%s'");
3673 /* verify type compatibility to store vtop in 'dt' type */
3674 static void verify_assign_cast(CType
*dt
)
3676 CType
*st
, *type1
, *type2
;
3677 int dbt
, sbt
, qualwarn
, lvl
;
3679 st
= &vtop
->type
; /* source type */
3680 dbt
= dt
->t
& VT_BTYPE
;
3681 sbt
= st
->t
& VT_BTYPE
;
3682 if (dt
->t
& VT_CONSTANT
)
3683 tcc_warning("assignment of read-only location");
3687 tcc_error("assignment to void expression");
3690 /* special cases for pointers */
3691 /* '0' can also be a pointer */
3692 if (is_null_pointer(vtop
))
3694 /* accept implicit pointer to integer cast with warning */
3695 if (is_integer_btype(sbt
)) {
3696 tcc_warning("assignment makes pointer from integer without a cast");
3699 type1
= pointed_type(dt
);
3701 type2
= pointed_type(st
);
3702 else if (sbt
== VT_FUNC
)
3703 type2
= st
; /* a function is implicitly a function pointer */
3706 if (is_compatible_types(type1
, type2
))
3708 for (qualwarn
= lvl
= 0;; ++lvl
) {
3709 if (((type2
->t
& VT_CONSTANT
) && !(type1
->t
& VT_CONSTANT
)) ||
3710 ((type2
->t
& VT_VOLATILE
) && !(type1
->t
& VT_VOLATILE
)))
3712 dbt
= type1
->t
& (VT_BTYPE
|VT_LONG
);
3713 sbt
= type2
->t
& (VT_BTYPE
|VT_LONG
);
3714 if (dbt
!= VT_PTR
|| sbt
!= VT_PTR
)
3716 type1
= pointed_type(type1
);
3717 type2
= pointed_type(type2
);
3719 if (!is_compatible_unqualified_types(type1
, type2
)) {
3720 if ((dbt
== VT_VOID
|| sbt
== VT_VOID
) && lvl
== 0) {
3721 /* void * can match anything */
3722 } else if (dbt
== sbt
3723 && is_integer_btype(sbt
& VT_BTYPE
)
3724 && IS_ENUM(type1
->t
) + IS_ENUM(type2
->t
)
3725 + !!((type1
->t
^ type2
->t
) & VT_UNSIGNED
) < 2) {
3726 /* Like GCC don't warn by default for merely changes
3727 in pointer target signedness. Do warn for different
3728 base types, though, in particular for unsigned enums
3729 and signed int targets. */
3731 tcc_warning("assignment from incompatible pointer type");
3736 tcc_warning("assignment discards qualifiers from pointer target type");
3742 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
3743 tcc_warning("assignment makes integer from pointer without a cast");
3744 } else if (sbt
== VT_STRUCT
) {
3745 goto case_VT_STRUCT
;
3747 /* XXX: more tests */
3751 if (!is_compatible_unqualified_types(dt
, st
)) {
3759 static void gen_assign_cast(CType
*dt
)
3761 verify_assign_cast(dt
);
3765 /* store vtop in lvalue pushed on stack */
3766 ST_FUNC
void vstore(void)
3768 int sbt
, dbt
, ft
, r
, size
, align
, bit_size
, bit_pos
, delayed_cast
;
3770 ft
= vtop
[-1].type
.t
;
3771 sbt
= vtop
->type
.t
& VT_BTYPE
;
3772 dbt
= ft
& VT_BTYPE
;
3774 verify_assign_cast(&vtop
[-1].type
);
3776 if (sbt
== VT_STRUCT
) {
3777 /* if structure, only generate pointer */
3778 /* structure assignment : generate memcpy */
3779 /* XXX: optimize if small size */
3780 size
= type_size(&vtop
->type
, &align
);
3784 #ifdef CONFIG_TCC_BCHECK
3785 if (vtop
->r
& VT_MUSTBOUND
)
3786 gbound(); /* check would be wrong after gaddrof() */
3788 vtop
->type
.t
= VT_PTR
;
3791 /* address of memcpy() */
3794 vpush_global_sym(&func_old_type
, TOK_memcpy8
);
3795 else if(!(align
& 3))
3796 vpush_global_sym(&func_old_type
, TOK_memcpy4
);
3799 /* Use memmove, rather than memcpy, as dest and src may be same: */
3800 vpush_global_sym(&func_old_type
, TOK_memmove
);
3805 #ifdef CONFIG_TCC_BCHECK
3806 if (vtop
->r
& VT_MUSTBOUND
)
3809 vtop
->type
.t
= VT_PTR
;
3814 /* leave source on stack */
3816 } else if (ft
& VT_BITFIELD
) {
3817 /* bitfield store handling */
3819 /* save lvalue as expression result (example: s.b = s.a = n;) */
3820 vdup(), vtop
[-1] = vtop
[-2];
3822 bit_pos
= BIT_POS(ft
);
3823 bit_size
= BIT_SIZE(ft
);
3824 /* remove bit field info to avoid loops */
3825 vtop
[-1].type
.t
= ft
& ~VT_STRUCT_MASK
;
3827 if (dbt
== VT_BOOL
) {
3828 gen_cast(&vtop
[-1].type
);
3829 vtop
[-1].type
.t
= (vtop
[-1].type
.t
& ~VT_BTYPE
) | (VT_BYTE
| VT_UNSIGNED
);
3831 r
= adjust_bf(vtop
- 1, bit_pos
, bit_size
);
3832 if (dbt
!= VT_BOOL
) {
3833 gen_cast(&vtop
[-1].type
);
3834 dbt
= vtop
[-1].type
.t
& VT_BTYPE
;
3836 if (r
== VT_STRUCT
) {
3837 store_packed_bf(bit_pos
, bit_size
);
3839 unsigned long long mask
= (1ULL << bit_size
) - 1;
3840 if (dbt
!= VT_BOOL
) {
3842 if (dbt
== VT_LLONG
)
3845 vpushi((unsigned)mask
);
3852 /* duplicate destination */
3855 /* load destination, mask and or with source */
3856 if (dbt
== VT_LLONG
)
3857 vpushll(~(mask
<< bit_pos
));
3859 vpushi(~((unsigned)mask
<< bit_pos
));
3864 /* ... and discard */
3867 } else if (dbt
== VT_VOID
) {
3870 /* optimize char/short casts */
3872 if ((dbt
== VT_BYTE
|| dbt
== VT_SHORT
)
3873 && is_integer_btype(sbt
)
3875 if ((vtop
->r
& VT_MUSTCAST
)
3876 && btype_size(dbt
) > btype_size(sbt
)
3878 force_charshort_cast();
3881 gen_cast(&vtop
[-1].type
);
3884 #ifdef CONFIG_TCC_BCHECK
3885 /* bound check case */
3886 if (vtop
[-1].r
& VT_MUSTBOUND
) {
3892 gv(RC_TYPE(dbt
)); /* generate value */
3895 vtop
->r
|= BFVAL(VT_MUSTCAST
, (sbt
== VT_LLONG
) + 1);
3896 //tcc_warning("deley cast %x -> %x", sbt, dbt);
3897 vtop
->type
.t
= ft
& VT_TYPE
;
3900 /* if lvalue was saved on stack, must read it */
3901 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
3903 r
= get_reg(RC_INT
);
3904 sv
.type
.t
= VT_PTRDIFF_T
;
3905 sv
.r
= VT_LOCAL
| VT_LVAL
;
3906 sv
.c
.i
= vtop
[-1].c
.i
;
3908 vtop
[-1].r
= r
| VT_LVAL
;
3911 r
= vtop
->r
& VT_VALMASK
;
3912 /* two word case handling :
3913 store second register at word + 4 (or +8 for x86-64) */
3914 if (USING_TWO_WORDS(dbt
)) {
3915 int load_type
= (dbt
== VT_QFLOAT
) ? VT_DOUBLE
: VT_PTRDIFF_T
;
3916 vtop
[-1].type
.t
= load_type
;
3919 /* convert to int to increment easily */
3920 vtop
->type
.t
= VT_PTRDIFF_T
;
3926 vtop
[-1].type
.t
= load_type
;
3927 /* XXX: it works because r2 is spilled last ! */
3928 store(vtop
->r2
, vtop
- 1);
3934 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
3938 /* post defines POST/PRE add. c is the token ++ or -- */
3939 ST_FUNC
void inc(int post
, int c
)
3942 vdup(); /* save lvalue */
3944 gv_dup(); /* duplicate value */
3949 vpushi(c
- TOK_MID
);
3951 vstore(); /* store value */
3953 vpop(); /* if post op, return saved value */
3956 ST_FUNC
void parse_mult_str (CString
*astr
, const char *msg
)
3958 /* read the string */
3962 while (tok
== TOK_STR
) {
3963 /* XXX: add \0 handling too ? */
3964 cstr_cat(astr
, tokc
.str
.data
, -1);
3967 cstr_ccat(astr
, '\0');
3970 /* If I is >= 1 and a power of two, returns log2(i)+1.
3971 If I is 0 returns 0. */
3972 static int exact_log2p1(int i
)
3977 for (ret
= 1; i
>= 1 << 8; ret
+= 8)
3988 /* Parse __attribute__((...)) GNUC extension. */
3989 static void parse_attribute(AttributeDef
*ad
)
3995 if (tok
!= TOK_ATTRIBUTE1
&& tok
!= TOK_ATTRIBUTE2
)
4000 while (tok
!= ')') {
4001 if (tok
< TOK_IDENT
)
4002 expect("attribute name");
4014 tcc_warning("implicit declaration of function '%s'",
4015 get_tok_str(tok
, &tokc
));
4016 s
= external_global_sym(tok
, &func_old_type
);
4018 else if ((s
->type
.t
& VT_BTYPE
) == VT_FUNC
) {
4019 ad
->cleanup_func
= s
;
4022 tcc_error("'%s' is not declared as function", get_tok_str(tok
, &tokc
));
4024 ad
->cleanup_func
= s
;
4029 case TOK_CONSTRUCTOR1
:
4030 case TOK_CONSTRUCTOR2
:
4031 ad
->f
.func_ctor
= 1;
4033 case TOK_DESTRUCTOR1
:
4034 case TOK_DESTRUCTOR2
:
4035 ad
->f
.func_dtor
= 1;
4040 parse_mult_str(&astr
, "section name");
4041 ad
->section
= find_section(tcc_state
, (char *)astr
.data
);
4048 parse_mult_str(&astr
, "alias(\"target\")");
4049 ad
->alias_target
= /* save string as token, for later */
4050 tok_alloc((char*)astr
.data
, astr
.size
-1)->tok
;
4054 case TOK_VISIBILITY1
:
4055 case TOK_VISIBILITY2
:
4057 parse_mult_str(&astr
,
4058 "visibility(\"default|hidden|internal|protected\")");
4059 if (!strcmp (astr
.data
, "default"))
4060 ad
->a
.visibility
= STV_DEFAULT
;
4061 else if (!strcmp (astr
.data
, "hidden"))
4062 ad
->a
.visibility
= STV_HIDDEN
;
4063 else if (!strcmp (astr
.data
, "internal"))
4064 ad
->a
.visibility
= STV_INTERNAL
;
4065 else if (!strcmp (astr
.data
, "protected"))
4066 ad
->a
.visibility
= STV_PROTECTED
;
4068 expect("visibility(\"default|hidden|internal|protected\")");
4077 if (n
<= 0 || (n
& (n
- 1)) != 0)
4078 tcc_error("alignment must be a positive power of two");
4083 ad
->a
.aligned
= exact_log2p1(n
);
4084 if (n
!= 1 << (ad
->a
.aligned
- 1))
4085 tcc_error("alignment of %d is larger than implemented", n
);
4097 /* currently, no need to handle it because tcc does not
4098 track unused objects */
4102 ad
->f
.func_noreturn
= 1;
4107 ad
->f
.func_call
= FUNC_CDECL
;
4112 ad
->f
.func_call
= FUNC_STDCALL
;
4114 #ifdef TCC_TARGET_I386
4124 ad
->f
.func_call
= FUNC_FASTCALL1
+ n
- 1;
4130 ad
->f
.func_call
= FUNC_FASTCALLW
;
4137 ad
->attr_mode
= VT_LLONG
+ 1;
4140 ad
->attr_mode
= VT_BYTE
+ 1;
4143 ad
->attr_mode
= VT_SHORT
+ 1;
4147 ad
->attr_mode
= VT_INT
+ 1;
4150 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok
, NULL
));
4157 ad
->a
.dllexport
= 1;
4159 case TOK_NODECORATE
:
4160 ad
->a
.nodecorate
= 1;
4163 ad
->a
.dllimport
= 1;
4166 if (tcc_state
->warn_unsupported
)
4167 tcc_warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4168 /* skip parameters */
4170 int parenthesis
= 0;
4174 else if (tok
== ')')
4177 } while (parenthesis
&& tok
!= -1);
4190 static Sym
* find_field (CType
*type
, int v
, int *cumofs
)
4194 while ((s
= s
->next
) != NULL
) {
4195 if ((s
->v
& SYM_FIELD
) &&
4196 (s
->type
.t
& VT_BTYPE
) == VT_STRUCT
&&
4197 (s
->v
& ~SYM_FIELD
) >= SYM_FIRST_ANOM
) {
4198 Sym
*ret
= find_field (&s
->type
, v
, cumofs
);
4210 static void struct_layout(CType
*type
, AttributeDef
*ad
)
4212 int size
, align
, maxalign
, offset
, c
, bit_pos
, bit_size
;
4213 int packed
, a
, bt
, prevbt
, prev_bit_size
;
4214 int pcc
= !tcc_state
->ms_bitfields
;
4215 int pragma_pack
= *tcc_state
->pack_stack_ptr
;
4222 prevbt
= VT_STRUCT
; /* make it never match */
4227 for (f
= type
->ref
->next
; f
; f
= f
->next
) {
4228 if (f
->type
.t
& VT_BITFIELD
)
4229 bit_size
= BIT_SIZE(f
->type
.t
);
4232 size
= type_size(&f
->type
, &align
);
4233 a
= f
->a
.aligned
? 1 << (f
->a
.aligned
- 1) : 0;
4236 if (pcc
&& bit_size
== 0) {
4237 /* in pcc mode, packing does not affect zero-width bitfields */
4240 /* in pcc mode, attribute packed overrides if set. */
4241 if (pcc
&& (f
->a
.packed
|| ad
->a
.packed
))
4244 /* pragma pack overrides align if lesser and packs bitfields always */
4247 if (pragma_pack
< align
)
4248 align
= pragma_pack
;
4249 /* in pcc mode pragma pack also overrides individual align */
4250 if (pcc
&& pragma_pack
< a
)
4254 /* some individual align was specified */
4258 if (type
->ref
->type
.t
== VT_UNION
) {
4259 if (pcc
&& bit_size
>= 0)
4260 size
= (bit_size
+ 7) >> 3;
4265 } else if (bit_size
< 0) {
4267 c
+= (bit_pos
+ 7) >> 3;
4268 c
= (c
+ align
- 1) & -align
;
4277 /* A bit-field. Layout is more complicated. There are two
4278 options: PCC (GCC) compatible and MS compatible */
4280 /* In PCC layout a bit-field is placed adjacent to the
4281 preceding bit-fields, except if:
4283 - an individual alignment was given
4284 - it would overflow its base type container and
4285 there is no packing */
4286 if (bit_size
== 0) {
4288 c
= (c
+ ((bit_pos
+ 7) >> 3) + align
- 1) & -align
;
4290 } else if (f
->a
.aligned
) {
4292 } else if (!packed
) {
4294 int ofs
= ((c
* 8 + bit_pos
) % a8
+ bit_size
+ a8
- 1) / a8
;
4295 if (ofs
> size
/ align
)
4299 /* in pcc mode, long long bitfields have type int if they fit */
4300 if (size
== 8 && bit_size
<= 32)
4301 f
->type
.t
= (f
->type
.t
& ~VT_BTYPE
) | VT_INT
, size
= 4;
4303 while (bit_pos
>= align
* 8)
4304 c
+= align
, bit_pos
-= align
* 8;
4307 /* In PCC layout named bit-fields influence the alignment
4308 of the containing struct using the base types alignment,
4309 except for packed fields (which here have correct align). */
4310 if (f
->v
& SYM_FIRST_ANOM
4311 // && bit_size // ??? gcc on ARM/rpi does that
4316 bt
= f
->type
.t
& VT_BTYPE
;
4317 if ((bit_pos
+ bit_size
> size
* 8)
4318 || (bit_size
> 0) == (bt
!= prevbt
)
4320 c
= (c
+ align
- 1) & -align
;
4323 /* In MS bitfield mode a bit-field run always uses
4324 at least as many bits as the underlying type.
4325 To start a new run it's also required that this
4326 or the last bit-field had non-zero width. */
4327 if (bit_size
|| prev_bit_size
)
4330 /* In MS layout the records alignment is normally
4331 influenced by the field, except for a zero-width
4332 field at the start of a run (but by further zero-width
4333 fields it is again). */
4334 if (bit_size
== 0 && prevbt
!= bt
)
4337 prev_bit_size
= bit_size
;
4340 f
->type
.t
= (f
->type
.t
& ~(0x3f << VT_STRUCT_SHIFT
))
4341 | (bit_pos
<< VT_STRUCT_SHIFT
);
4342 bit_pos
+= bit_size
;
4344 if (align
> maxalign
)
4348 printf("set field %s offset %-2d size %-2d align %-2d",
4349 get_tok_str(f
->v
& ~SYM_FIELD
, NULL
), offset
, size
, align
);
4350 if (f
->type
.t
& VT_BITFIELD
) {
4351 printf(" pos %-2d bits %-2d",
4364 c
+= (bit_pos
+ 7) >> 3;
4366 /* store size and alignment */
4367 a
= bt
= ad
->a
.aligned
? 1 << (ad
->a
.aligned
- 1) : 1;
4371 if (pragma_pack
&& pragma_pack
< maxalign
&& 0 == pcc
) {
4372 /* can happen if individual align for some member was given. In
4373 this case MSVC ignores maxalign when aligning the size */
4378 c
= (c
+ a
- 1) & -a
;
4382 printf("struct size %-2d align %-2d\n\n", c
, a
), fflush(stdout
);
4385 /* check whether we can access bitfields by their type */
4386 for (f
= type
->ref
->next
; f
; f
= f
->next
) {
4390 if (0 == (f
->type
.t
& VT_BITFIELD
))
4394 bit_size
= BIT_SIZE(f
->type
.t
);
4397 bit_pos
= BIT_POS(f
->type
.t
);
4398 size
= type_size(&f
->type
, &align
);
4399 if (bit_pos
+ bit_size
<= size
* 8 && f
->c
+ size
<= c
)
4402 /* try to access the field using a different type */
4403 c0
= -1, s
= align
= 1;
4405 px
= f
->c
* 8 + bit_pos
;
4406 cx
= (px
>> 3) & -align
;
4407 px
= px
- (cx
<< 3);
4410 s
= (px
+ bit_size
+ 7) >> 3;
4420 s
= type_size(&t
, &align
);
4424 if (px
+ bit_size
<= s
* 8 && cx
+ s
<= c
) {
4425 /* update offset and bit position */
4428 f
->type
.t
= (f
->type
.t
& ~(0x3f << VT_STRUCT_SHIFT
))
4429 | (bit_pos
<< VT_STRUCT_SHIFT
);
4433 printf("FIX field %s offset %-2d size %-2d align %-2d "
4434 "pos %-2d bits %-2d\n",
4435 get_tok_str(f
->v
& ~SYM_FIELD
, NULL
),
4436 cx
, s
, align
, px
, bit_size
);
4439 /* fall back to load/store single-byte wise */
4440 f
->auxtype
= VT_STRUCT
;
4442 printf("FIX field %s : load byte-wise\n",
4443 get_tok_str(f
->v
& ~SYM_FIELD
, NULL
));
4449 /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
4450 static void struct_decl(CType
*type
, int u
)
4452 int v
, c
, size
, align
, flexible
;
4453 int bit_size
, bsize
, bt
;
4455 AttributeDef ad
, ad1
;
4458 memset(&ad
, 0, sizeof ad
);
4460 parse_attribute(&ad
);
4464 /* struct already defined ? return it */
4466 expect("struct/union/enum name");
4468 if (s
&& (s
->sym_scope
== local_scope
|| tok
!= '{')) {
4471 if (u
== VT_ENUM
&& IS_ENUM(s
->type
.t
))
4473 tcc_error("redefinition of '%s'", get_tok_str(v
, NULL
));
4478 /* Record the original enum/struct/union token. */
4479 type1
.t
= u
== VT_ENUM
? u
| VT_INT
| VT_UNSIGNED
: u
;
4481 /* we put an undefined size for struct/union */
4482 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
4483 s
->r
= 0; /* default alignment is zero as gcc */
4485 type
->t
= s
->type
.t
;
4491 tcc_error("struct/union/enum already defined");
4493 /* cannot be empty */
4494 /* non empty enums are not allowed */
4497 long long ll
= 0, pl
= 0, nl
= 0;
4500 /* enum symbols have static storage */
4501 t
.t
= VT_INT
|VT_STATIC
|VT_ENUM_VAL
;
4505 expect("identifier");
4507 if (ss
&& !local_stack
)
4508 tcc_error("redefinition of enumerator '%s'",
4509 get_tok_str(v
, NULL
));
4513 ll
= expr_const64();
4515 ss
= sym_push(v
, &t
, VT_CONST
, 0);
4517 *ps
= ss
, ps
= &ss
->next
;
4526 /* NOTE: we accept a trailing comma */
4531 /* set integral type of the enum */
4534 if (pl
!= (unsigned)pl
)
4535 t
.t
= (LONG_SIZE
==8 ? VT_LLONG
|VT_LONG
: VT_LLONG
);
4537 } else if (pl
!= (int)pl
|| nl
!= (int)nl
)
4538 t
.t
= (LONG_SIZE
==8 ? VT_LLONG
|VT_LONG
: VT_LLONG
);
4539 s
->type
.t
= type
->t
= t
.t
| VT_ENUM
;
4541 /* set type for enum members */
4542 for (ss
= s
->next
; ss
; ss
= ss
->next
) {
4544 if (ll
== (int)ll
) /* default is int if it fits */
4546 if (t
.t
& VT_UNSIGNED
) {
4547 ss
->type
.t
|= VT_UNSIGNED
;
4548 if (ll
== (unsigned)ll
)
4551 ss
->type
.t
= (ss
->type
.t
& ~VT_BTYPE
)
4552 | (LONG_SIZE
==8 ? VT_LLONG
|VT_LONG
: VT_LLONG
);
4557 while (tok
!= '}') {
4558 if (!parse_btype(&btype
, &ad1
)) {
4564 tcc_error("flexible array member '%s' not at the end of struct",
4565 get_tok_str(v
, NULL
));
4571 type_decl(&type1
, &ad1
, &v
, TYPE_DIRECT
);
4573 if ((type1
.t
& VT_BTYPE
) != VT_STRUCT
)
4574 expect("identifier");
4576 int v
= btype
.ref
->v
;
4577 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
4578 if (tcc_state
->ms_extensions
== 0)
4579 expect("identifier");
4583 if (type_size(&type1
, &align
) < 0) {
4584 if ((u
== VT_STRUCT
) && (type1
.t
& VT_ARRAY
) && c
)
4587 tcc_error("field '%s' has incomplete type",
4588 get_tok_str(v
, NULL
));
4590 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
4591 (type1
.t
& VT_BTYPE
) == VT_VOID
||
4592 (type1
.t
& VT_STORAGE
))
4593 tcc_error("invalid type for '%s'",
4594 get_tok_str(v
, NULL
));
4598 bit_size
= expr_const();
4599 /* XXX: handle v = 0 case for messages */
4601 tcc_error("negative width in bit-field '%s'",
4602 get_tok_str(v
, NULL
));
4603 if (v
&& bit_size
== 0)
4604 tcc_error("zero width for bit-field '%s'",
4605 get_tok_str(v
, NULL
));
4606 parse_attribute(&ad1
);
4608 size
= type_size(&type1
, &align
);
4609 if (bit_size
>= 0) {
4610 bt
= type1
.t
& VT_BTYPE
;
4616 tcc_error("bitfields must have scalar type");
4618 if (bit_size
> bsize
) {
4619 tcc_error("width of '%s' exceeds its type",
4620 get_tok_str(v
, NULL
));
4621 } else if (bit_size
== bsize
4622 && !ad
.a
.packed
&& !ad1
.a
.packed
) {
4623 /* no need for bit fields */
4625 } else if (bit_size
== 64) {
4626 tcc_error("field width 64 not implemented");
4628 type1
.t
= (type1
.t
& ~VT_STRUCT_MASK
)
4630 | (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4633 if (v
!= 0 || (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
4634 /* Remember we've seen a real field to check
4635 for placement of flexible array member. */
4638 /* If member is a struct or bit-field, enforce
4639 placing into the struct (as anonymous). */
4641 ((type1
.t
& VT_BTYPE
) == VT_STRUCT
||
4646 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, 0);
4651 if (tok
== ';' || tok
== TOK_EOF
)
4658 parse_attribute(&ad
);
4659 if (ad
.cleanup_func
) {
4660 tcc_warning("attribute '__cleanup__' ignored on type");
4662 struct_layout(type
, &ad
);
4667 static void sym_to_attr(AttributeDef
*ad
, Sym
*s
)
4669 merge_symattr(&ad
->a
, &s
->a
);
4670 merge_funcattr(&ad
->f
, &s
->f
);
4673 /* Add type qualifiers to a type. If the type is an array then the qualifiers
4674 are added to the element type, copied because it could be a typedef. */
4675 static void parse_btype_qualify(CType
*type
, int qualifiers
)
4677 while (type
->t
& VT_ARRAY
) {
4678 type
->ref
= sym_push(SYM_FIELD
, &type
->ref
->type
, 0, type
->ref
->c
);
4679 type
= &type
->ref
->type
;
4681 type
->t
|= qualifiers
;
4684 /* return 0 if no type declaration. otherwise, return the basic type
4687 static int parse_btype(CType
*type
, AttributeDef
*ad
)
4689 int t
, u
, bt
, st
, type_found
, typespec_found
, g
, n
;
4693 memset(ad
, 0, sizeof(AttributeDef
));
4703 /* currently, we really ignore extension */
4713 if (u
== VT_SHORT
|| u
== VT_LONG
) {
4714 if (st
!= -1 || (bt
!= -1 && bt
!= VT_INT
))
4715 tmbt
: tcc_error("too many basic types");
4718 if (bt
!= -1 || (st
!= -1 && u
!= VT_INT
))
4723 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | u
;
4740 memset(&ad1
, 0, sizeof(AttributeDef
));
4741 if (parse_btype(&type1
, &ad1
)) {
4742 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
4744 n
= 1 << (ad1
.a
.aligned
- 1);
4746 type_size(&type1
, &n
);
4749 if (n
<= 0 || (n
& (n
- 1)) != 0)
4750 tcc_error("alignment must be a positive power of two");
4753 ad
->a
.aligned
= exact_log2p1(n
);
4757 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4758 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | VT_LDOUBLE
;
4759 } else if ((t
& (VT_BTYPE
|VT_LONG
)) == VT_LONG
) {
4760 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | VT_LLONG
;
4767 #ifdef TCC_TARGET_ARM64
4769 /* GCC's __uint128_t appears in some Linux header files. Make it a
4770 synonym for long double to get the size and alignment right. */
4781 if ((t
& (VT_BTYPE
|VT_LONG
)) == VT_LONG
) {
4782 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | VT_LDOUBLE
;
4790 struct_decl(&type1
, VT_ENUM
);
4793 type
->ref
= type1
.ref
;
4796 struct_decl(&type1
, VT_STRUCT
);
4799 struct_decl(&type1
, VT_UNION
);
4802 /* type modifiers */
4807 parse_btype_qualify(type
, VT_CONSTANT
);
4815 parse_btype_qualify(type
, VT_VOLATILE
);
4822 if ((t
& (VT_DEFSIGN
|VT_UNSIGNED
)) == (VT_DEFSIGN
|VT_UNSIGNED
))
4823 tcc_error("signed and unsigned modifier");
4836 if ((t
& (VT_DEFSIGN
|VT_UNSIGNED
)) == VT_DEFSIGN
)
4837 tcc_error("signed and unsigned modifier");
4838 t
|= VT_DEFSIGN
| VT_UNSIGNED
;
4854 if (t
& (VT_EXTERN
|VT_STATIC
|VT_TYPEDEF
) & ~g
)
4855 tcc_error("multiple storage classes");
4867 ad
->f
.func_noreturn
= 1;
4869 /* GNUC attribute */
4870 case TOK_ATTRIBUTE1
:
4871 case TOK_ATTRIBUTE2
:
4872 parse_attribute(ad
);
4873 if (ad
->attr_mode
) {
4874 u
= ad
->attr_mode
-1;
4875 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | u
;
4883 parse_expr_type(&type1
);
4884 /* remove all storage modifiers except typedef */
4885 type1
.t
&= ~(VT_STORAGE
&~VT_TYPEDEF
);
4887 sym_to_attr(ad
, type1
.ref
);
4893 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
4897 if (tok
== ':' && !in_generic
) {
4898 /* ignore if it's a label */
4903 t
&= ~(VT_BTYPE
|VT_LONG
);
4904 u
= t
& ~(VT_CONSTANT
| VT_VOLATILE
), t
^= u
;
4905 type
->t
= (s
->type
.t
& ~VT_TYPEDEF
) | u
;
4906 type
->ref
= s
->type
.ref
;
4908 parse_btype_qualify(type
, t
);
4910 /* get attributes from typedef */
4919 if (tcc_state
->char_is_unsigned
) {
4920 if ((t
& (VT_DEFSIGN
|VT_BTYPE
)) == VT_BYTE
)
4923 /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
4924 bt
= t
& (VT_BTYPE
|VT_LONG
);
4926 t
|= LONG_SIZE
== 8 ? VT_LLONG
: VT_INT
;
4927 #ifdef TCC_TARGET_PE
4928 if (bt
== VT_LDOUBLE
)
4929 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | (VT_DOUBLE
|VT_LONG
);
4935 /* convert a function parameter type (array to pointer and function to
4936 function pointer) */
4937 static inline void convert_parameter_type(CType
*pt
)
4939 /* remove const and volatile qualifiers (XXX: const could be used
4940 to indicate a const function parameter */
4941 pt
->t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
4942 /* array must be transformed to pointer according to ANSI C */
4944 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
4949 ST_FUNC
void parse_asm_str(CString
*astr
)
4952 parse_mult_str(astr
, "string constant");
4955 /* Parse an asm label and return the token */
4956 static int asm_label_instr(void)
4962 parse_asm_str(&astr
);
4965 printf("asm_alias: \"%s\"\n", (char *)astr
.data
);
4967 v
= tok_alloc(astr
.data
, astr
.size
- 1)->tok
;
4972 static int post_type(CType
*type
, AttributeDef
*ad
, int storage
, int td
)
4974 int n
, l
, t1
, arg_size
, align
, unused_align
;
4975 Sym
**plast
, *s
, *first
;
4980 /* function type, or recursive declarator (return if so) */
4982 if (td
&& !(td
& TYPE_ABSTRACT
))
4986 else if (parse_btype(&pt
, &ad1
))
4989 merge_attr (ad
, &ad1
);
4998 /* read param name and compute offset */
4999 if (l
!= FUNC_OLD
) {
5000 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
5002 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
5003 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
5004 tcc_error("parameter declared as void");
5008 expect("identifier");
5009 pt
.t
= VT_VOID
; /* invalid type */
5013 convert_parameter_type(&pt
);
5014 arg_size
+= (type_size(&pt
, &align
) + PTR_SIZE
- 1) / PTR_SIZE
;
5015 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
5021 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
5026 if (l
== FUNC_NEW
&& !parse_btype(&pt
, &ad1
))
5027 tcc_error("invalid type");
5030 /* if no parameters, then old type prototype */
5033 /* NOTE: const is ignored in returned type as it has a special
5034 meaning in gcc / C++ */
5035 type
->t
&= ~VT_CONSTANT
;
5036 /* some ancient pre-K&R C allows a function to return an array
5037 and the array brackets to be put after the arguments, such
5038 that "int c()[]" means something like "int[] c()" */
5041 skip(']'); /* only handle simple "[]" */
5044 /* we push a anonymous symbol which will contain the function prototype */
5045 ad
->f
.func_args
= arg_size
;
5046 ad
->f
.func_type
= l
;
5047 s
= sym_push(SYM_FIELD
, type
, 0, 0);
5053 } else if (tok
== '[') {
5054 int saved_nocode_wanted
= nocode_wanted
;
5055 /* array definition */
5058 /* XXX The optional type-quals and static should only be accepted
5059 in parameter decls. The '*' as well, and then even only
5060 in prototypes (not function defs). */
5062 case TOK_RESTRICT1
: case TOK_RESTRICT2
: case TOK_RESTRICT3
:
5077 if (!local_stack
|| (storage
& VT_STATIC
))
5078 vpushi(expr_const());
5080 /* VLAs (which can only happen with local_stack && !VT_STATIC)
5081 length must always be evaluated, even under nocode_wanted,
5082 so that its size slot is initialized (e.g. under sizeof
5087 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
5090 tcc_error("invalid array size");
5092 if (!is_integer_btype(vtop
->type
.t
& VT_BTYPE
))
5093 tcc_error("size of variable length array should be an integer");
5099 /* parse next post type */
5100 post_type(type
, ad
, storage
, 0);
5102 if ((type
->t
& VT_BTYPE
) == VT_FUNC
)
5103 tcc_error("declaration of an array of functions");
5104 if ((type
->t
& VT_BTYPE
) == VT_VOID
5105 || type_size(type
, &unused_align
) < 0)
5106 tcc_error("declaration of an array of incomplete type elements");
5108 t1
|= type
->t
& VT_VLA
;
5112 tcc_error("need explicit inner array size in VLAs");
5113 loc
-= type_size(&int_type
, &align
);
5117 vla_runtime_type_size(type
, &align
);
5119 vset(&int_type
, VT_LOCAL
|VT_LVAL
, n
);
5125 nocode_wanted
= saved_nocode_wanted
;
5127 /* we push an anonymous symbol which will contain the array
5129 s
= sym_push(SYM_FIELD
, type
, 0, n
);
5130 type
->t
= (t1
? VT_VLA
: VT_ARRAY
) | VT_PTR
;
5136 /* Parse a type declarator (except basic type), and return the type
5137 in 'type'. 'td' is a bitmask indicating which kind of type decl is
5138 expected. 'type' should contain the basic type. 'ad' is the
5139 attribute definition of the basic type. It can be modified by
5140 type_decl(). If this (possibly abstract) declarator is a pointer chain
5141 it returns the innermost pointed to type (equals *type, but is a different
5142 pointer), otherwise returns type itself, that's used for recursive calls. */
5143 static CType
*type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
5146 int qualifiers
, storage
;
5148 /* recursive type, remove storage bits first, apply them later again */
5149 storage
= type
->t
& VT_STORAGE
;
5150 type
->t
&= ~VT_STORAGE
;
5153 while (tok
== '*') {
5161 qualifiers
|= VT_CONSTANT
;
5166 qualifiers
|= VT_VOLATILE
;
5172 /* XXX: clarify attribute handling */
5173 case TOK_ATTRIBUTE1
:
5174 case TOK_ATTRIBUTE2
:
5175 parse_attribute(ad
);
5179 type
->t
|= qualifiers
;
5181 /* innermost pointed to type is the one for the first derivation */
5182 ret
= pointed_type(type
);
5186 /* This is possibly a parameter type list for abstract declarators
5187 ('int ()'), use post_type for testing this. */
5188 if (!post_type(type
, ad
, 0, td
)) {
5189 /* It's not, so it's a nested declarator, and the post operations
5190 apply to the innermost pointed to type (if any). */
5191 /* XXX: this is not correct to modify 'ad' at this point, but
5192 the syntax is not clear */
5193 parse_attribute(ad
);
5194 post
= type_decl(type
, ad
, v
, td
);
5198 } else if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
5199 /* type identifier */
5204 if (!(td
& TYPE_ABSTRACT
))
5205 expect("identifier");
5208 post_type(post
, ad
, storage
, 0);
5209 parse_attribute(ad
);
5214 /* indirection with full error checking and bound check */
5215 ST_FUNC
void indir(void)
5217 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
) {
5218 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
5222 if (vtop
->r
& VT_LVAL
)
5224 vtop
->type
= *pointed_type(&vtop
->type
);
5225 /* Arrays and functions are never lvalues */
5226 if (!(vtop
->type
.t
& (VT_ARRAY
| VT_VLA
))
5227 && (vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
5229 /* if bound checking, the referenced pointer must be checked */
5230 #ifdef CONFIG_TCC_BCHECK
5231 if (tcc_state
->do_bounds_check
)
5232 vtop
->r
|= VT_MUSTBOUND
;
5237 /* pass a parameter to a function and do type checking and casting */
5238 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
5243 func_type
= func
->f
.func_type
;
5244 if (func_type
== FUNC_OLD
||
5245 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
5246 /* default casting : only need to convert float to double */
5247 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
5248 gen_cast_s(VT_DOUBLE
);
5249 } else if (vtop
->type
.t
& VT_BITFIELD
) {
5250 type
.t
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5251 type
.ref
= vtop
->type
.ref
;
5253 } else if (vtop
->r
& VT_MUSTCAST
) {
5254 force_charshort_cast();
5256 } else if (arg
== NULL
) {
5257 tcc_error("too many arguments to function");
5260 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
5261 gen_assign_cast(&type
);
5265 /* parse an expression and return its type without any side effect. */
5266 static void expr_type(CType
*type
, void (*expr_fn
)(void))
5275 /* parse an expression of the form '(type)' or '(expr)' and return its
5277 static void parse_expr_type(CType
*type
)
5283 if (parse_btype(type
, &ad
)) {
5284 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
5286 expr_type(type
, gexpr
);
5291 static void parse_type(CType
*type
)
5296 if (!parse_btype(type
, &ad
)) {
5299 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
5302 static void parse_builtin_params(int nc
, const char *args
)
5309 while ((c
= *args
++)) {
5313 case 'e': expr_eq(); continue;
5314 case 't': parse_type(&t
); vpush(&t
); continue;
5315 default: tcc_error("internal error"); break;
5323 ST_FUNC
void unary(void)
5325 int n
, t
, align
, size
, r
, sizeof_caller
;
5330 /* generate line number info */
5331 if (tcc_state
->do_debug
)
5332 tcc_debug_line(tcc_state
);
5334 sizeof_caller
= in_sizeof
;
5337 /* XXX: GCC 2.95.3 does not generate a table although it should be
5345 #ifdef TCC_TARGET_PE
5346 t
= VT_SHORT
|VT_UNSIGNED
;
5354 vsetc(&type
, VT_CONST
, &tokc
);
5358 t
= VT_INT
| VT_UNSIGNED
;
5364 t
= VT_LLONG
| VT_UNSIGNED
;
5376 t
= (LONG_SIZE
== 8 ? VT_LLONG
: VT_INT
) | VT_LONG
;
5379 t
= (LONG_SIZE
== 8 ? VT_LLONG
: VT_INT
) | VT_LONG
| VT_UNSIGNED
;
5381 case TOK___FUNCTION__
:
5383 goto tok_identifier
;
5389 /* special function name identifier */
5390 len
= strlen(funcname
) + 1;
5391 /* generate char[len] type */
5396 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
5397 if (!NODATA_WANTED
) {
5398 ptr
= section_ptr_add(data_section
, len
);
5399 memcpy(ptr
, funcname
, len
);
5405 #ifdef TCC_TARGET_PE
5406 t
= VT_SHORT
| VT_UNSIGNED
;
5412 /* string parsing */
5414 if (tcc_state
->char_is_unsigned
)
5415 t
= VT_BYTE
| VT_UNSIGNED
;
5417 if (tcc_state
->warn_write_strings
)
5422 memset(&ad
, 0, sizeof(AttributeDef
));
5423 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
5428 if (parse_btype(&type
, &ad
)) {
5429 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
5431 /* check ISOC99 compound literal */
5433 /* data is allocated locally by default */
5438 /* all except arrays are lvalues */
5439 if (!(type
.t
& VT_ARRAY
))
5441 memset(&ad
, 0, sizeof(AttributeDef
));
5442 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
5444 if (sizeof_caller
) {
5451 } else if (tok
== '{') {
5452 int saved_nocode_wanted
= nocode_wanted
;
5453 if (const_wanted
&& !(nocode_wanted
& unevalmask
))
5454 tcc_error("expected constant");
5455 /* save all registers */
5457 /* statement expression : we do not accept break/continue
5458 inside as GCC does. We do retain the nocode_wanted state,
5459 as statement expressions can't ever be entered from the
5460 outside, so any reactivation of code emission (from labels
5461 or loop heads) can be disabled again after the end of it. */
5463 nocode_wanted
= saved_nocode_wanted
;
5478 /* functions names must be treated as function pointers,
5479 except for unary '&' and sizeof. Since we consider that
5480 functions are not lvalues, we only have to handle it
5481 there and in function calls. */
5482 /* arrays can also be used although they are not lvalues */
5483 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
5484 !(vtop
->type
.t
& VT_ARRAY
))
5487 vtop
->sym
->a
.addrtaken
= 1;
5488 mk_pointer(&vtop
->type
);
5494 gen_test_zero(TOK_EQ
);
5505 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
5506 tcc_error("pointer not accepted for unary plus");
5507 /* In order to force cast, we add zero, except for floating point
5508 where we really need an noop (otherwise -0.0 will be transformed
5510 if (!is_float(vtop
->type
.t
)) {
5522 expr_type(&type
, unary
); /* Perform a in_sizeof = 0; */
5524 if (vtop
[1].r
& VT_SYM
)
5525 s
= vtop
[1].sym
; /* hack: accessing previous vtop */
5526 size
= type_size(&type
, &align
);
5527 if (s
&& s
->a
.aligned
)
5528 align
= 1 << (s
->a
.aligned
- 1);
5529 if (t
== TOK_SIZEOF
) {
5530 if (!(type
.t
& VT_VLA
)) {
5532 tcc_error("sizeof applied to an incomplete type");
5535 vla_runtime_type_size(&type
, &align
);
5540 vtop
->type
.t
|= VT_UNSIGNED
;
5543 case TOK_builtin_expect
:
5544 /* __builtin_expect is a no-op for now */
5545 parse_builtin_params(0, "ee");
5548 case TOK_builtin_types_compatible_p
:
5549 parse_builtin_params(0, "tt");
5550 vtop
[-1].type
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
5551 vtop
[0].type
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
5552 n
= is_compatible_types(&vtop
[-1].type
, &vtop
[0].type
);
5556 case TOK_builtin_choose_expr
:
5583 case TOK_builtin_constant_p
:
5584 parse_builtin_params(1, "e");
5585 n
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5589 case TOK_builtin_frame_address
:
5590 case TOK_builtin_return_address
:
5596 if (tok
!= TOK_CINT
) {
5597 tcc_error("%s only takes positive integers",
5598 tok1
== TOK_builtin_return_address
?
5599 "__builtin_return_address" :
5600 "__builtin_frame_address");
5602 level
= (uint32_t)tokc
.i
;
5607 vset(&type
, VT_LOCAL
, 0); /* local frame */
5609 mk_pointer(&vtop
->type
);
5610 indir(); /* -> parent frame */
5612 if (tok1
== TOK_builtin_return_address
) {
5613 // assume return address is just above frame pointer on stack
5616 mk_pointer(&vtop
->type
);
5621 #ifdef TCC_TARGET_RISCV64
5622 case TOK_builtin_va_start
:
5623 parse_builtin_params(0, "ee");
5624 r
= vtop
->r
& VT_VALMASK
;
5628 tcc_error("__builtin_va_start expects a local variable");
5633 #ifdef TCC_TARGET_X86_64
5634 #ifdef TCC_TARGET_PE
5635 case TOK_builtin_va_start
:
5636 parse_builtin_params(0, "ee");
5637 r
= vtop
->r
& VT_VALMASK
;
5641 tcc_error("__builtin_va_start expects a local variable");
5643 vtop
->type
= char_pointer_type
;
5648 case TOK_builtin_va_arg_types
:
5649 parse_builtin_params(0, "t");
5650 vpushi(classify_x86_64_va_arg(&vtop
->type
));
5657 #ifdef TCC_TARGET_ARM64
5658 case TOK_builtin_va_start
: {
5659 parse_builtin_params(0, "ee");
5663 vtop
->type
.t
= VT_VOID
;
5666 case TOK_builtin_va_arg
: {
5667 parse_builtin_params(0, "et");
5675 case TOK___arm64_clear_cache
: {
5676 parse_builtin_params(0, "ee");
5679 vtop
->type
.t
= VT_VOID
;
5683 /* pre operations */
5694 t
= vtop
->type
.t
& VT_BTYPE
;
5696 /* In IEEE negate(x) isn't subtract(0,x), but rather
5700 vtop
->c
.f
= -1.0 * 0.0;
5701 else if (t
== VT_DOUBLE
)
5702 vtop
->c
.d
= -1.0 * 0.0;
5704 vtop
->c
.ld
= -1.0 * 0.0;
5712 goto tok_identifier
;
5714 /* allow to take the address of a label */
5715 if (tok
< TOK_UIDENT
)
5716 expect("label identifier");
5717 s
= label_find(tok
);
5719 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
5721 if (s
->r
== LABEL_DECLARED
)
5722 s
->r
= LABEL_FORWARD
;
5725 s
->type
.t
= VT_VOID
;
5726 mk_pointer(&s
->type
);
5727 s
->type
.t
|= VT_STATIC
;
5729 vpushsym(&s
->type
, s
);
5735 CType controlling_type
;
5736 int has_default
= 0;
5739 TokenString
*str
= NULL
;
5740 int saved_const_wanted
= const_wanted
;
5745 expr_type(&controlling_type
, expr_eq
);
5746 controlling_type
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
| VT_ARRAY
);
5747 if ((controlling_type
.t
& VT_BTYPE
) == VT_FUNC
)
5748 mk_pointer(&controlling_type
);
5749 const_wanted
= saved_const_wanted
;
5753 if (tok
== TOK_DEFAULT
) {
5755 tcc_error("too many 'default'");
5761 AttributeDef ad_tmp
;
5766 parse_btype(&cur_type
, &ad_tmp
);
5769 type_decl(&cur_type
, &ad_tmp
, &itmp
, TYPE_ABSTRACT
);
5770 if (compare_types(&controlling_type
, &cur_type
, 0)) {
5772 tcc_error("type match twice");
5782 skip_or_save_block(&str
);
5784 skip_or_save_block(NULL
);
5791 type_to_str(buf
, sizeof buf
, &controlling_type
, NULL
);
5792 tcc_error("type '%s' does not match any association", buf
);
5794 begin_macro(str
, 1);
5803 // special qnan , snan and infinity values
5808 vtop
->type
.t
= VT_FLOAT
;
5813 goto special_math_val
;
5816 goto special_math_val
;
5823 expect("identifier");
5825 if (!s
|| IS_ASM_SYM(s
)) {
5826 const char *name
= get_tok_str(t
, NULL
);
5828 tcc_error("'%s' undeclared", name
);
5829 /* for simple function calls, we tolerate undeclared
5830 external reference to int() function */
5831 if (tcc_state
->warn_implicit_function_declaration
5832 #ifdef TCC_TARGET_PE
5833 /* people must be warned about using undeclared WINAPI functions
5834 (which usually start with uppercase letter) */
5835 || (name
[0] >= 'A' && name
[0] <= 'Z')
5838 tcc_warning("implicit declaration of function '%s'", name
);
5839 s
= external_global_sym(t
, &func_old_type
);
5843 /* A symbol that has a register is a local register variable,
5844 which starts out as VT_LOCAL value. */
5845 if ((r
& VT_VALMASK
) < VT_CONST
)
5846 r
= (r
& ~VT_VALMASK
) | VT_LOCAL
;
5848 vset(&s
->type
, r
, s
->c
);
5849 /* Point to s as backpointer (even without r&VT_SYM).
5850 Will be used by at least the x86 inline asm parser for
5856 } else if (r
== VT_CONST
&& IS_ENUM_VAL(s
->type
.t
)) {
5857 vtop
->c
.i
= s
->enum_val
;
5862 /* post operations */
5864 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
5867 } else if (tok
== '.' || tok
== TOK_ARROW
|| tok
== TOK_CDOUBLE
) {
5868 int qualifiers
, cumofs
= 0;
5870 if (tok
== TOK_ARROW
)
5872 qualifiers
= vtop
->type
.t
& (VT_CONSTANT
| VT_VOLATILE
);
5875 /* expect pointer on structure */
5876 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
) {
5878 type_to_str(got
, sizeof got
, &vtop
->type
, NULL
);
5879 tcc_error("expected struct or union but not '%s'", got
);
5881 if (tok
== TOK_CDOUBLE
)
5882 expect("field name");
5884 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
5885 expect("field name");
5886 s
= find_field(&vtop
->type
, tok
, &cumofs
);
5888 tcc_error("field not found: %s", get_tok_str(tok
& ~SYM_FIELD
, &tokc
));
5889 /* add field offset to pointer */
5890 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
5891 vpushi(cumofs
+ s
->c
);
5893 /* change type to field type, and set to lvalue */
5894 vtop
->type
= s
->type
;
5895 vtop
->type
.t
|= qualifiers
;
5896 /* an array is never an lvalue */
5897 if (!(vtop
->type
.t
& VT_ARRAY
)) {
5899 #ifdef CONFIG_TCC_BCHECK
5900 /* if bound checking, the referenced pointer must be checked */
5901 if (tcc_state
->do_bounds_check
)
5902 vtop
->r
|= VT_MUSTBOUND
;
5906 } else if (tok
== '[') {
5912 } else if (tok
== '(') {
5915 int nb_args
, ret_nregs
, ret_align
, regsize
, variadic
;
5917 #ifdef CONFIG_TCC_BCHECK
5918 tcc_state
->alloca_vla_used
|= tcc_state
->do_bounds_check
&&
5919 (vtop
->r
& VT_SYM
) &&
5920 vtop
->sym
->v
== TOK_alloca
;
5923 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
5924 /* pointer test (no array accepted) */
5925 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
5926 vtop
->type
= *pointed_type(&vtop
->type
);
5927 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
5931 expect("function pointer");
5934 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
5936 /* get return type */
5939 sa
= s
->next
; /* first parameter */
5940 nb_args
= regsize
= 0;
5942 /* compute first implicit argument if a structure is returned */
5943 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
5944 variadic
= (s
->f
.func_type
== FUNC_ELLIPSIS
);
5945 ret_nregs
= gfunc_sret(&s
->type
, variadic
, &ret
.type
,
5946 &ret_align
, ®size
);
5947 if (ret_nregs
<= 0) {
5948 /* get some space for the returned structure */
5949 size
= type_size(&s
->type
, &align
);
5950 #ifdef TCC_TARGET_ARM64
5951 /* On arm64, a small struct is return in registers.
5952 It is much easier to write it to memory if we know
5953 that we are allowed to write some extra bytes, so
5954 round the allocated space up to a power of 2: */
5956 while (size
& (size
- 1))
5957 size
= (size
| (size
- 1)) + 1;
5959 loc
= (loc
- size
) & -align
;
5961 ret
.r
= VT_LOCAL
| VT_LVAL
;
5962 /* pass it as 'int' to avoid structure arg passing
5964 vseti(VT_LOCAL
, loc
);
5976 if (ret_nregs
> 0) {
5977 /* return in register */
5979 PUT_R_RET(&ret
, ret
.type
.t
);
5984 gfunc_param_typed(s
, sa
);
5994 tcc_error("too few arguments to function");
5996 gfunc_call(nb_args
);
5998 if (ret_nregs
< 0) {
5999 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
6000 #ifdef TCC_TARGET_RISCV64
6001 arch_transfer_ret_regs(1);
6005 for (r
= ret
.r
+ ret_nregs
+ !ret_nregs
; r
-- > ret
.r
;) {
6006 vsetc(&ret
.type
, r
, &ret
.c
);
6007 vtop
->r2
= ret
.r2
; /* Loop only happens when r2 is VT_CONST */
6010 /* handle packed struct return */
6011 if (((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) && ret_nregs
) {
6014 size
= type_size(&s
->type
, &align
);
6015 /* We're writing whole regs often, make sure there's enough
6016 space. Assume register size is power of 2. */
6017 if (regsize
> align
)
6019 loc
= (loc
- size
) & -align
;
6023 vset(&ret
.type
, VT_LOCAL
| VT_LVAL
, addr
+ offset
);
6027 if (--ret_nregs
== 0)
6031 vset(&s
->type
, VT_LOCAL
| VT_LVAL
, addr
);
6034 /* Promote char/short return values. This is matters only
6035 for calling function that were not compiled by TCC and
6036 only on some architectures. For those where it doesn't
6037 matter we expect things to be already promoted to int,
6039 t
= s
->type
.t
& VT_BTYPE
;
6040 if (t
== VT_BYTE
|| t
== VT_SHORT
|| t
== VT_BOOL
) {
6042 vtop
->r
|= BFVAL(VT_MUSTCAST
, 1);
6044 vtop
->type
.t
= VT_INT
;
6048 if (s
->f
.func_noreturn
)
6056 #ifndef precedence_parser /* original top-down parser */
6058 static void expr_prod(void)
6063 while ((t
= tok
) == '*' || t
== '/' || t
== '%') {
6070 static void expr_sum(void)
6075 while ((t
= tok
) == '+' || t
== '-') {
6082 static void expr_shift(void)
6087 while ((t
= tok
) == TOK_SHL
|| t
== TOK_SAR
) {
6094 static void expr_cmp(void)
6099 while (((t
= tok
) >= TOK_ULE
&& t
<= TOK_GT
) ||
6100 t
== TOK_ULT
|| t
== TOK_UGE
) {
6107 static void expr_cmpeq(void)
6112 while ((t
= tok
) == TOK_EQ
|| t
== TOK_NE
) {
6119 static void expr_and(void)
6122 while (tok
== '&') {
6129 static void expr_xor(void)
6132 while (tok
== '^') {
6139 static void expr_or(void)
6142 while (tok
== '|') {
6149 static void expr_landor(int op
);
6151 static void expr_land(void)
6154 if (tok
== TOK_LAND
)
6158 static void expr_lor(void)
6165 # define expr_landor_next(op) op == TOK_LAND ? expr_or() : expr_land()
6166 #else /* defined precedence_parser */
6167 # define expr_landor_next(op) unary(), expr_infix(precedence(op) + 1)
6168 # define expr_lor() unary(), expr_infix(1)
6170 static int precedence(int tok
)
6173 case TOK_LOR
: return 1;
6174 case TOK_LAND
: return 2;
6178 case TOK_EQ
: case TOK_NE
: return 6;
6179 relat
: case TOK_ULT
: case TOK_UGE
: return 7;
6180 case TOK_SHL
: case TOK_SAR
: return 8;
6181 case '+': case '-': return 9;
6182 case '*': case '/': case '%': return 10;
6184 if (tok
>= TOK_ULE
&& tok
<= TOK_GT
)
6189 static unsigned char prec
[256];
6190 static void init_prec(void)
6193 for (i
= 0; i
< 256; i
++)
6194 prec
[i
] = precedence(i
);
6196 #define precedence(i) ((unsigned)i < 256 ? prec[i] : 0)
6198 static void expr_landor(int op
);
6200 static void expr_infix(int p
)
6203 while ((p2
= precedence(t
)) >= p
) {
6204 if (t
== TOK_LOR
|| t
== TOK_LAND
) {
6209 if (precedence(tok
) > p2
)
6218 /* Assuming vtop is a value used in a conditional context
6219 (i.e. compared with zero) return 0 if it's false, 1 if
6220 true and -1 if it can't be statically determined. */
6221 static int condition_3way(void)
6224 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
&&
6225 (!(vtop
->r
& VT_SYM
) || !vtop
->sym
->a
.weak
)) {
6227 gen_cast_s(VT_BOOL
);
6234 static void expr_landor(int op
)
6236 int t
= 0, cc
= 1, f
= 0, i
= op
== TOK_LAND
, c
;
6238 c
= f
? i
: condition_3way();
6240 save_regs(1), cc
= 0;
6242 nocode_wanted
++, f
= 1;
6250 expr_landor_next(op
);
6262 static int is_cond_bool(SValue
*sv
)
6264 if ((sv
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
6265 && (sv
->type
.t
& VT_BTYPE
) == VT_INT
)
6266 return (unsigned)sv
->c
.i
< 2;
6267 if (sv
->r
== VT_CMP
)
6272 static void expr_cond(void)
6274 int tt
, u
, r1
, r2
, rc
, t1
, t2
, islv
, c
, g
;
6282 c
= condition_3way();
6283 g
= (tok
== ':' && gnu_ext
);
6293 /* needed to avoid having different registers saved in
6300 ncw_prev
= nocode_wanted
;
6306 if (c
< 0 && vtop
->r
== VT_CMP
) {
6313 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
6314 mk_pointer(&vtop
->type
);
6315 sv
= *vtop
; /* save value to handle it later */
6316 vtop
--; /* no vpop so that FP stack is not flushed */
6326 nocode_wanted
= ncw_prev
;
6332 if (c
< 0 && is_cond_bool(vtop
) && is_cond_bool(&sv
)) {
6333 if (sv
.r
== VT_CMP
) {
6344 nocode_wanted
= ncw_prev
;
6345 // tcc_warning("two conditions expr_cond");
6349 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
6350 mk_pointer(&vtop
->type
);
6352 /* cast operands to correct type according to ISOC rules */
6353 if (!combine_types(&type
, &sv
, vtop
, '?'))
6354 type_incompatibility_error(&sv
.type
, &vtop
->type
,
6355 "type mismatch in conditional expression (have '%s' and '%s')");
6356 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
6357 that `(expr ? a : b).mem` does not error with "lvalue expected" */
6358 islv
= (vtop
->r
& VT_LVAL
) && (sv
.r
& VT_LVAL
) && VT_STRUCT
== (type
.t
& VT_BTYPE
);
6360 /* now we convert second operand */
6364 mk_pointer(&vtop
->type
);
6366 } else if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
6370 rc
= RC_TYPE(type
.t
);
6371 /* for long longs, we use fixed registers to avoid having
6372 to handle a complicated move */
6373 if (USING_TWO_WORDS(type
.t
))
6374 rc
= RC_RET(type
.t
);
6382 nocode_wanted
= ncw_prev
;
6384 /* this is horrible, but we must also convert first
6390 mk_pointer(&vtop
->type
);
6392 } else if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
6398 move_reg(r2
, r1
, islv
? VT_PTR
: type
.t
);
6408 static void expr_eq(void)
6413 if ((t
= tok
) == '='
6414 || (t
>= TOK_A_MOD
&& t
<= TOK_A_DIV
)
6415 || t
== TOK_A_XOR
|| t
== TOK_A_OR
6416 || t
== TOK_A_SHL
|| t
== TOK_A_SAR
) {
6430 ST_FUNC
void gexpr(void)
6441 /* parse a constant expression and return value in vtop. */
6442 static void expr_const1(void)
6445 nocode_wanted
+= unevalmask
+ 1;
6447 nocode_wanted
-= unevalmask
+ 1;
6451 /* parse an integer constant and return its value. */
6452 static inline int64_t expr_const64(void)
6456 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
6457 expect("constant expression");
6463 /* parse an integer constant and return its value.
6464 Complain if it doesn't fit 32bit (signed or unsigned). */
6465 ST_FUNC
int expr_const(void)
6468 int64_t wc
= expr_const64();
6470 if (c
!= wc
&& (unsigned)c
!= wc
)
6471 tcc_error("constant exceeds 32 bit");
6475 /* ------------------------------------------------------------------------- */
6476 /* return from function */
6478 #ifndef TCC_TARGET_ARM64
6479 static void gfunc_return(CType
*func_type
)
6481 if ((func_type
->t
& VT_BTYPE
) == VT_STRUCT
) {
6482 CType type
, ret_type
;
6483 int ret_align
, ret_nregs
, regsize
;
6484 ret_nregs
= gfunc_sret(func_type
, func_var
, &ret_type
,
6485 &ret_align
, ®size
);
6486 if (ret_nregs
< 0) {
6487 #ifdef TCC_TARGET_RISCV64
6488 arch_transfer_ret_regs(0);
6490 } else if (0 == ret_nregs
) {
6491 /* if returning structure, must copy it to implicit
6492 first pointer arg location */
6495 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
6498 /* copy structure value to pointer */
6501 /* returning structure packed into registers */
6502 int size
, addr
, align
, rc
;
6503 size
= type_size(func_type
,&align
);
6504 if ((vtop
->r
!= (VT_LOCAL
| VT_LVAL
) ||
6505 (vtop
->c
.i
& (ret_align
-1)))
6506 && (align
& (ret_align
-1))) {
6507 loc
= (loc
- size
) & -ret_align
;
6510 vset(&type
, VT_LOCAL
| VT_LVAL
, addr
);
6514 vset(&ret_type
, VT_LOCAL
| VT_LVAL
, addr
);
6516 vtop
->type
= ret_type
;
6517 rc
= RC_RET(ret_type
.t
);
6525 if (--ret_nregs
== 0)
6527 /* We assume that when a structure is returned in multiple
6528 registers, their classes are consecutive values of the
6531 vtop
->c
.i
+= regsize
;
6536 gv(RC_RET(func_type
->t
));
6538 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6542 static void check_func_return(void)
6544 if ((func_vt
.t
& VT_BTYPE
) == VT_VOID
)
6546 if (!strcmp (funcname
, "main")
6547 && (func_vt
.t
& VT_BTYPE
) == VT_INT
) {
6548 /* main returns 0 by default */
6550 gen_assign_cast(&func_vt
);
6551 gfunc_return(&func_vt
);
6553 tcc_warning("function might return no value: '%s'", funcname
);
6557 /* ------------------------------------------------------------------------- */
6560 static int case_cmp(const void *pa
, const void *pb
)
6562 int64_t a
= (*(struct case_t
**) pa
)->v1
;
6563 int64_t b
= (*(struct case_t
**) pb
)->v1
;
6564 return a
< b
? -1 : a
> b
;
6567 static void gtst_addr(int t
, int a
)
6569 gsym_addr(gvtst(0, t
), a
);
6572 static void gcase(struct case_t
**base
, int len
, int *bsym
)
6576 int ll
= (vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
;
6593 gtst_addr(0, p
->sym
); /* v1 <= x <= v2 */
6595 gcase(base
, len
/2, bsym
);
6599 base
+= e
; len
-= e
;
6609 if (p
->v1
== p
->v2
) {
6611 gtst_addr(0, p
->sym
);
6621 gtst_addr(0, p
->sym
);
6625 *bsym
= gjmp(*bsym
);
6628 /* ------------------------------------------------------------------------- */
6629 /* __attribute__((cleanup(fn))) */
6631 static void try_call_scope_cleanup(Sym
*stop
)
6633 Sym
*cls
= cur_scope
->cl
.s
;
6635 for (; cls
!= stop
; cls
= cls
->ncl
) {
6636 Sym
*fs
= cls
->next
;
6637 Sym
*vs
= cls
->prev_tok
;
6639 vpushsym(&fs
->type
, fs
);
6640 vset(&vs
->type
, vs
->r
, vs
->c
);
6642 mk_pointer(&vtop
->type
);
6648 static void try_call_cleanup_goto(Sym
*cleanupstate
)
6653 if (!cur_scope
->cl
.s
)
6656 /* search NCA of both cleanup chains given parents and initial depth */
6657 ocd
= cleanupstate
? cleanupstate
->v
& ~SYM_FIELD
: 0;
6658 for (ccd
= cur_scope
->cl
.n
, oc
= cleanupstate
; ocd
> ccd
; --ocd
, oc
= oc
->ncl
)
6660 for (cc
= cur_scope
->cl
.s
; ccd
> ocd
; --ccd
, cc
= cc
->ncl
)
6662 for (; cc
!= oc
; cc
= cc
->ncl
, oc
= oc
->ncl
, --ccd
)
6665 try_call_scope_cleanup(cc
);
6668 /* call 'func' for each __attribute__((cleanup(func))) */
6669 static void block_cleanup(struct scope
*o
)
6673 for (pg
= &pending_gotos
; (g
= *pg
) && g
->c
> o
->cl
.n
;) {
6674 if (g
->prev_tok
->r
& LABEL_FORWARD
) {
6679 try_call_scope_cleanup(o
->cl
.s
);
6680 pcl
->jnext
= gjmp(0);
6682 goto remove_pending
;
6692 try_call_scope_cleanup(o
->cl
.s
);
6695 /* ------------------------------------------------------------------------- */
6698 static void vla_restore(int loc
)
6701 gen_vla_sp_restore(loc
);
6704 static void vla_leave(struct scope
*o
)
6706 if (o
->vla
.num
< cur_scope
->vla
.num
)
6707 vla_restore(o
->vla
.loc
);
6710 /* ------------------------------------------------------------------------- */
6713 void new_scope(struct scope
*o
)
6715 /* copy and link previous scope */
6717 o
->prev
= cur_scope
;
6720 /* record local declaration stack position */
6721 o
->lstk
= local_stack
;
6722 o
->llstk
= local_label_stack
;
6725 tcc_debug_stabn(N_LBRAC
, ind
- func_ind
);
6728 void prev_scope(struct scope
*o
, int is_expr
)
6732 if (o
->cl
.s
!= o
->prev
->cl
.s
)
6733 block_cleanup(o
->prev
);
6735 /* pop locally defined labels */
6736 label_pop(&local_label_stack
, o
->llstk
, is_expr
);
6738 /* In the is_expr case (a statement expression is finished here),
6739 vtop might refer to symbols on the local_stack. Either via the
6740 type or via vtop->sym. We can't pop those nor any that in turn
6741 might be referred to. To make it easier we don't roll back
6742 any symbols in that case; some upper level call to block() will
6743 do that. We do have to remove such symbols from the lookup
6744 tables, though. sym_pop will do that. */
6746 /* pop locally defined symbols */
6747 pop_local_syms(0, &local_stack
, o
->lstk
, is_expr
, 0);
6749 tcc_debug_stabn(N_RBRAC
, ind
- func_ind
);
6751 cur_scope
= o
->prev
;
6755 /* leave a scope via break/continue(/goto) */
6756 void leave_scope(struct scope
*o
)
6760 try_call_scope_cleanup(o
->cl
.s
);
6764 /* ------------------------------------------------------------------------- */
6765 /* call block from 'for do while' loops */
6767 static void lblock(int *bsym
, int *csym
)
6769 struct scope
*lo
= loop_scope
, *co
= cur_scope
;
6770 int *b
= co
->bsym
, *c
= co
->csym
;
6784 static void block(int is_expr
)
6786 int a
, b
, c
, d
, e
, t
;
6791 /* default return value is (void) */
6793 vtop
->type
.t
= VT_VOID
;
6805 if (tok
== TOK_ELSE
) {
6810 gsym(d
); /* patch else jmp */
6815 } else if (t
== TOK_WHILE
) {
6827 } else if (t
== '{') {
6830 /* handle local labels declarations */
6831 while (tok
== TOK_LABEL
) {
6834 if (tok
< TOK_UIDENT
)
6835 expect("label identifier");
6836 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
6838 } while (tok
== ',');
6842 while (tok
!= '}') {
6851 prev_scope(&o
, is_expr
);
6854 else if (!nocode_wanted
)
6855 check_func_return();
6857 } else if (t
== TOK_RETURN
) {
6858 b
= (func_vt
.t
& VT_BTYPE
) != VT_VOID
;
6862 gen_assign_cast(&func_vt
);
6864 if (vtop
->type
.t
!= VT_VOID
)
6865 tcc_warning("void function returns a value");
6869 tcc_warning("'return' with no value");
6872 leave_scope(root_scope
);
6874 gfunc_return(&func_vt
);
6876 /* jump unless last stmt in top-level block */
6877 if (tok
!= '}' || local_scope
!= 1)
6881 } else if (t
== TOK_BREAK
) {
6883 if (!cur_scope
->bsym
)
6884 tcc_error("cannot break");
6885 if (cur_switch
&& cur_scope
->bsym
== cur_switch
->bsym
)
6886 leave_scope(cur_switch
->scope
);
6888 leave_scope(loop_scope
);
6889 *cur_scope
->bsym
= gjmp(*cur_scope
->bsym
);
6892 } else if (t
== TOK_CONTINUE
) {
6894 if (!cur_scope
->csym
)
6895 tcc_error("cannot continue");
6896 leave_scope(loop_scope
);
6897 *cur_scope
->csym
= gjmp(*cur_scope
->csym
);
6900 } else if (t
== TOK_FOR
) {
6905 /* c99 for-loop init decl? */
6906 if (!decl0(VT_LOCAL
, 1, NULL
)) {
6907 /* no, regular for-loop init expr */
6935 } else if (t
== TOK_DO
) {
6949 } else if (t
== TOK_SWITCH
) {
6950 struct switch_t
*sw
;
6952 sw
= tcc_mallocz(sizeof *sw
);
6954 sw
->scope
= cur_scope
;
6955 sw
->prev
= cur_switch
;
6961 sw
->sv
= *vtop
--; /* save switch value */
6964 b
= gjmp(0); /* jump to first case */
6966 a
= gjmp(a
); /* add implicit break */
6970 qsort(sw
->p
, sw
->n
, sizeof(void*), case_cmp
);
6971 for (b
= 1; b
< sw
->n
; b
++)
6972 if (sw
->p
[b
- 1]->v2
>= sw
->p
[b
]->v1
)
6973 tcc_error("duplicate case value");
6975 /* Our switch table sorting is signed, so the compared
6976 value needs to be as well when it's 64bit. */
6978 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
)
6979 vtop
->type
.t
&= ~VT_UNSIGNED
;
6981 d
= 0, gcase(sw
->p
, sw
->n
, &d
);
6984 gsym_addr(d
, sw
->def_sym
);
6990 dynarray_reset(&sw
->p
, &sw
->n
);
6991 cur_switch
= sw
->prev
;
6994 } else if (t
== TOK_CASE
) {
6995 struct case_t
*cr
= tcc_malloc(sizeof(struct case_t
));
6998 cr
->v1
= cr
->v2
= expr_const64();
6999 if (gnu_ext
&& tok
== TOK_DOTS
) {
7001 cr
->v2
= expr_const64();
7002 if (cr
->v2
< cr
->v1
)
7003 tcc_warning("empty case range");
7006 dynarray_add(&cur_switch
->p
, &cur_switch
->n
, cr
);
7009 goto block_after_label
;
7011 } else if (t
== TOK_DEFAULT
) {
7014 if (cur_switch
->def_sym
)
7015 tcc_error("too many 'default'");
7016 cur_switch
->def_sym
= gind();
7019 goto block_after_label
;
7021 } else if (t
== TOK_GOTO
) {
7022 vla_restore(root_scope
->vla
.loc
);
7023 if (tok
== '*' && gnu_ext
) {
7027 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
7031 } else if (tok
>= TOK_UIDENT
) {
7032 s
= label_find(tok
);
7033 /* put forward definition if needed */
7035 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7036 else if (s
->r
== LABEL_DECLARED
)
7037 s
->r
= LABEL_FORWARD
;
7039 if (s
->r
& LABEL_FORWARD
) {
7040 /* start new goto chain for cleanups, linked via label->next */
7041 if (cur_scope
->cl
.s
&& !nocode_wanted
) {
7042 sym_push2(&pending_gotos
, SYM_FIELD
, 0, cur_scope
->cl
.n
);
7043 pending_gotos
->prev_tok
= s
;
7044 s
= sym_push2(&s
->next
, SYM_FIELD
, 0, 0);
7045 pending_gotos
->next
= s
;
7047 s
->jnext
= gjmp(s
->jnext
);
7049 try_call_cleanup_goto(s
->cleanupstate
);
7050 gjmp_addr(s
->jnext
);
7055 expect("label identifier");
7059 } else if (t
== TOK_ASM1
|| t
== TOK_ASM2
|| t
== TOK_ASM3
) {
7063 if (tok
== ':' && t
>= TOK_UIDENT
) {
7068 if (s
->r
== LABEL_DEFINED
)
7069 tcc_error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
7070 s
->r
= LABEL_DEFINED
;
7072 Sym
*pcl
; /* pending cleanup goto */
7073 for (pcl
= s
->next
; pcl
; pcl
= pcl
->prev
)
7075 sym_pop(&s
->next
, NULL
, 0);
7079 s
= label_push(&global_label_stack
, t
, LABEL_DEFINED
);
7082 s
->cleanupstate
= cur_scope
->cl
.s
;
7085 vla_restore(cur_scope
->vla
.loc
);
7086 /* we accept this, but it is a mistake */
7088 tcc_warning("deprecated use of label at end of compound statement");
7094 /* expression case */
7110 /* This skips over a stream of tokens containing balanced {} and ()
7111 pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started
7112 with a '{'). If STR then allocates and stores the skipped tokens
7113 in *STR. This doesn't check if () and {} are nested correctly,
7114 i.e. "({)}" is accepted. */
7115 static void skip_or_save_block(TokenString
**str
)
7117 int braces
= tok
== '{';
7120 *str
= tok_str_alloc();
7122 while ((level
> 0 || (tok
!= '}' && tok
!= ',' && tok
!= ';' && tok
!= ')'))) {
7124 if (tok
== TOK_EOF
) {
7125 if (str
|| level
> 0)
7126 tcc_error("unexpected end of file");
7131 tok_str_add_tok(*str
);
7134 if (t
== '{' || t
== '(') {
7136 } else if (t
== '}' || t
== ')') {
7138 if (level
== 0 && braces
&& t
== '}')
7143 tok_str_add(*str
, -1);
7144 tok_str_add(*str
, 0);
7148 #define EXPR_CONST 1
7151 static void parse_init_elem(int expr_type
)
7153 int saved_global_expr
;
7156 /* compound literals must be allocated globally in this case */
7157 saved_global_expr
= global_expr
;
7160 global_expr
= saved_global_expr
;
7161 /* NOTE: symbols are accepted, as well as lvalue for anon symbols
7162 (compound literals). */
7163 if (((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
7164 && ((vtop
->r
& (VT_SYM
|VT_LVAL
)) != (VT_SYM
|VT_LVAL
)
7165 || vtop
->sym
->v
< SYM_FIRST_ANOM
))
7166 #ifdef TCC_TARGET_PE
7167 || ((vtop
->r
& VT_SYM
) && vtop
->sym
->a
.dllimport
)
7170 tcc_error("initializer element is not constant");
7178 /* put zeros for variable based init */
7179 static void init_putz(Section
*sec
, unsigned long c
, int size
)
7182 /* nothing to do because globals are already set to zero */
7184 vpush_global_sym(&func_old_type
, TOK_memset
);
7186 #ifdef TCC_TARGET_ARM
7198 #define DIF_SIZE_ONLY 2
7199 #define DIF_HAVE_ELEM 4
7201 /* t is the array or struct type. c is the array or struct
7202 address. cur_field is the pointer to the current
7203 field, for arrays the 'c' member contains the current start
7204 index. 'flags' is as in decl_initializer.
7205 'al' contains the already initialized length of the
7206 current container (starting at c). This returns the new length of that. */
7207 static int decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
7208 Sym
**cur_field
, int flags
, int al
)
7211 int index
, index_last
, align
, l
, nb_elems
, elem_size
;
7212 unsigned long corig
= c
;
7217 if (flags
& DIF_HAVE_ELEM
)
7220 if (gnu_ext
&& tok
>= TOK_UIDENT
) {
7227 /* NOTE: we only support ranges for last designator */
7228 while (nb_elems
== 1 && (tok
== '[' || tok
== '.')) {
7230 if (!(type
->t
& VT_ARRAY
))
7231 expect("array type");
7233 index
= index_last
= expr_const();
7234 if (tok
== TOK_DOTS
&& gnu_ext
) {
7236 index_last
= expr_const();
7240 if (index
< 0 || (s
->c
>= 0 && index_last
>= s
->c
) ||
7242 tcc_error("invalid index");
7244 (*cur_field
)->c
= index_last
;
7245 type
= pointed_type(type
);
7246 elem_size
= type_size(type
, &align
);
7247 c
+= index
* elem_size
;
7248 nb_elems
= index_last
- index
+ 1;
7255 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
7256 expect("struct/union type");
7258 f
= find_field(type
, l
, &cumofs
);
7271 } else if (!gnu_ext
) {
7276 if (type
->t
& VT_ARRAY
) {
7277 index
= (*cur_field
)->c
;
7278 if (type
->ref
->c
>= 0 && index
>= type
->ref
->c
)
7279 tcc_error("index too large");
7280 type
= pointed_type(type
);
7281 c
+= index
* type_size(type
, &align
);
7284 while (f
&& (f
->v
& SYM_FIRST_ANOM
) && (f
->type
.t
& VT_BITFIELD
))
7285 *cur_field
= f
= f
->next
;
7287 tcc_error("too many field init");
7292 /* must put zero in holes (note that doing it that way
7293 ensures that it even works with designators) */
7294 if (!(flags
& DIF_SIZE_ONLY
) && c
- corig
> al
)
7295 init_putz(sec
, corig
+ al
, c
- corig
- al
);
7296 decl_initializer(type
, sec
, c
, flags
& ~DIF_FIRST
);
7298 /* XXX: make it more general */
7299 if (!(flags
& DIF_SIZE_ONLY
) && nb_elems
> 1) {
7300 unsigned long c_end
;
7305 vset(type
, VT_LOCAL
|VT_LVAL
, c
);
7306 for (i
= 1; i
< nb_elems
; i
++) {
7307 vset(type
, VT_LOCAL
|VT_LVAL
, c
+ elem_size
* i
);
7312 } else if (!NODATA_WANTED
) {
7313 c_end
= c
+ nb_elems
* elem_size
;
7314 if (c_end
> sec
->data_allocated
)
7315 section_realloc(sec
, c_end
);
7316 src
= sec
->data
+ c
;
7318 for(i
= 1; i
< nb_elems
; i
++) {
7320 memcpy(dst
, src
, elem_size
);
7324 c
+= nb_elems
* type_size(type
, &align
);
7330 /* store a value or an expression directly in global data or in local array */
7331 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
)
7338 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
7342 /* XXX: not portable */
7343 /* XXX: generate error if incorrect relocation */
7344 gen_assign_cast(&dtype
);
7345 bt
= type
->t
& VT_BTYPE
;
7347 if ((vtop
->r
& VT_SYM
)
7350 && (bt
!= (PTR_SIZE
== 8 ? VT_LLONG
: VT_INT
)
7351 || (type
->t
& VT_BITFIELD
))
7352 && !((vtop
->r
& VT_CONST
) && vtop
->sym
->v
>= SYM_FIRST_ANOM
)
7354 tcc_error("initializer element is not computable at load time");
7356 if (NODATA_WANTED
) {
7361 size
= type_size(type
, &align
);
7362 section_reserve(sec
, c
+ size
);
7363 ptr
= sec
->data
+ c
;
7365 /* XXX: make code faster ? */
7366 if ((vtop
->r
& (VT_SYM
|VT_CONST
)) == (VT_SYM
|VT_CONST
) &&
7367 vtop
->sym
->v
>= SYM_FIRST_ANOM
&&
7368 /* XXX This rejects compound literals like
7369 '(void *){ptr}'. The problem is that '&sym' is
7370 represented the same way, which would be ruled out
7371 by the SYM_FIRST_ANOM check above, but also '"string"'
7372 in 'char *p = "string"' is represented the same
7373 with the type being VT_PTR and the symbol being an
7374 anonymous one. That is, there's no difference in vtop
7375 between '(void *){x}' and '&(void *){x}'. Ignore
7376 pointer typed entities here. Hopefully no real code
7377 will every use compound literals with scalar type. */
7378 (vtop
->type
.t
& VT_BTYPE
) != VT_PTR
) {
7379 /* These come from compound literals, memcpy stuff over. */
7383 esym
= elfsym(vtop
->sym
);
7384 ssec
= tcc_state
->sections
[esym
->st_shndx
];
7385 memmove (ptr
, ssec
->data
+ esym
->st_value
, size
);
7387 /* We need to copy over all memory contents, and that
7388 includes relocations. Use the fact that relocs are
7389 created it order, so look from the end of relocs
7390 until we hit one before the copied region. */
7391 int num_relocs
= ssec
->reloc
->data_offset
/ sizeof(*rel
);
7392 rel
= (ElfW_Rel
*)(ssec
->reloc
->data
+ ssec
->reloc
->data_offset
);
7393 while (num_relocs
--) {
7395 if (rel
->r_offset
>= esym
->st_value
+ size
)
7397 if (rel
->r_offset
< esym
->st_value
)
7399 /* Note: if the same fields are initialized multiple
7400 times (possible with designators) then we possibly
7401 add multiple relocations for the same offset here.
7402 That would lead to wrong code, the last reloc needs
7403 to win. We clean this up later after the whole
7404 initializer is parsed. */
7405 put_elf_reloca(symtab_section
, sec
,
7406 c
+ rel
->r_offset
- esym
->st_value
,
7407 ELFW(R_TYPE
)(rel
->r_info
),
7408 ELFW(R_SYM
)(rel
->r_info
),
7418 if (type
->t
& VT_BITFIELD
) {
7419 int bit_pos
, bit_size
, bits
, n
;
7420 unsigned char *p
, v
, m
;
7421 bit_pos
= BIT_POS(vtop
->type
.t
);
7422 bit_size
= BIT_SIZE(vtop
->type
.t
);
7423 p
= (unsigned char*)ptr
+ (bit_pos
>> 3);
7424 bit_pos
&= 7, bits
= 0;
7429 v
= vtop
->c
.i
>> bits
<< bit_pos
;
7430 m
= ((1 << n
) - 1) << bit_pos
;
7431 *p
= (*p
& ~m
) | (v
& m
);
7432 bits
+= n
, bit_size
-= n
, bit_pos
= 0, ++p
;
7436 /* XXX: when cross-compiling we assume that each type has the
7437 same representation on host and target, which is likely to
7438 be wrong in the case of long double */
7440 vtop
->c
.i
= vtop
->c
.i
!= 0;
7442 *(char *)ptr
|= vtop
->c
.i
;
7445 *(short *)ptr
|= vtop
->c
.i
;
7448 *(float*)ptr
= vtop
->c
.f
;
7451 *(double *)ptr
= vtop
->c
.d
;
7454 #if defined TCC_IS_NATIVE_387
7455 if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
7456 memcpy(ptr
, &vtop
->c
.ld
, 10);
7458 else if (sizeof (long double) == sizeof (double))
7459 __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr
) : "m" (vtop
->c
.ld
));
7461 else if (vtop
->c
.ld
== 0.0)
7465 if (sizeof(long double) == LDOUBLE_SIZE
)
7466 *(long double*)ptr
= vtop
->c
.ld
;
7467 else if (sizeof(double) == LDOUBLE_SIZE
)
7468 *(double *)ptr
= (double)vtop
->c
.ld
;
7470 tcc_error("can't cross compile long double constants");
7474 *(long long *)ptr
|= vtop
->c
.i
;
7481 addr_t val
= vtop
->c
.i
;
7483 if (vtop
->r
& VT_SYM
)
7484 greloca(sec
, vtop
->sym
, c
, R_DATA_PTR
, val
);
7486 *(addr_t
*)ptr
|= val
;
7488 if (vtop
->r
& VT_SYM
)
7489 greloc(sec
, vtop
->sym
, c
, R_DATA_PTR
);
7490 *(addr_t
*)ptr
|= val
;
7496 int val
= vtop
->c
.i
;
7498 if (vtop
->r
& VT_SYM
)
7499 greloca(sec
, vtop
->sym
, c
, R_DATA_PTR
, val
);
7503 if (vtop
->r
& VT_SYM
)
7504 greloc(sec
, vtop
->sym
, c
, R_DATA_PTR
);
7513 vset(&dtype
, VT_LOCAL
|VT_LVAL
, c
);
7520 /* 't' contains the type and storage info. 'c' is the offset of the
7521 object in section 'sec'. If 'sec' is NULL, it means stack based
7522 allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi
7523 dimension implicit array init handling). 'flags & DIF_SIZE_ONLY' is true if
7524 size only evaluation is wanted (only for arrays). */
7525 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
7528 int len
, n
, no_oblock
, nb
, i
;
7534 if (!(flags
& DIF_HAVE_ELEM
) && tok
!= '{' &&
7535 /* In case of strings we have special handling for arrays, so
7536 don't consume them as initializer value (which would commit them
7537 to some anonymous symbol). */
7538 tok
!= TOK_LSTR
&& tok
!= TOK_STR
&&
7539 !(flags
& DIF_SIZE_ONLY
)) {
7540 parse_init_elem(!sec
? EXPR_ANY
: EXPR_CONST
);
7541 flags
|= DIF_HAVE_ELEM
;
7544 if ((flags
& DIF_HAVE_ELEM
) &&
7545 !(type
->t
& VT_ARRAY
) &&
7546 /* Use i_c_parameter_t, to strip toplevel qualifiers.
7547 The source type might have VT_CONSTANT set, which is
7548 of course assignable to non-const elements. */
7549 is_compatible_unqualified_types(type
, &vtop
->type
)) {
7550 init_putv(type
, sec
, c
);
7551 } else if (type
->t
& VT_ARRAY
) {
7554 t1
= pointed_type(type
);
7555 size1
= type_size(t1
, &align1
);
7558 if (((flags
& DIF_FIRST
) && tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
7561 tcc_error("character array initializer must be a literal,"
7562 " optionally enclosed in braces");
7567 /* only parse strings here if correct type (otherwise: handle
7568 them as ((w)char *) expressions */
7569 if ((tok
== TOK_LSTR
&&
7570 #ifdef TCC_TARGET_PE
7571 (t1
->t
& VT_BTYPE
) == VT_SHORT
&& (t1
->t
& VT_UNSIGNED
)
7573 (t1
->t
& VT_BTYPE
) == VT_INT
7575 ) || (tok
== TOK_STR
&& (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
7577 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
7580 /* compute maximum number of chars wanted */
7582 cstr_len
= tokc
.str
.size
;
7584 cstr_len
= tokc
.str
.size
/ sizeof(nwchar_t
);
7587 if (n
>= 0 && nb
> (n
- len
))
7589 if (!(flags
& DIF_SIZE_ONLY
)) {
7591 tcc_warning("initializer-string for array is too long");
7592 /* in order to go faster for common case (char
7593 string in global variable, we handle it
7595 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
7597 memcpy(sec
->data
+ c
+ len
, tokc
.str
.data
, nb
);
7601 ch
= ((unsigned char *)tokc
.str
.data
)[i
];
7603 ch
= ((nwchar_t
*)tokc
.str
.data
)[i
];
7605 init_putv(t1
, sec
, c
+ (len
+ i
) * size1
);
7612 /* only add trailing zero if enough storage (no
7613 warning in this case since it is standard) */
7614 if (n
< 0 || len
< n
) {
7615 if (!(flags
& DIF_SIZE_ONLY
)) {
7617 init_putv(t1
, sec
, c
+ (len
* size1
));
7628 while (tok
!= '}' || (flags
& DIF_HAVE_ELEM
)) {
7629 len
= decl_designator(type
, sec
, c
, &f
, flags
, len
);
7630 flags
&= ~DIF_HAVE_ELEM
;
7631 if (type
->t
& VT_ARRAY
) {
7633 /* special test for multi dimensional arrays (may not
7634 be strictly correct if designators are used at the
7636 if (no_oblock
&& len
>= n
*size1
)
7639 if (s
->type
.t
== VT_UNION
)
7643 if (no_oblock
&& f
== NULL
)
7652 /* put zeros at the end */
7653 if (!(flags
& DIF_SIZE_ONLY
) && len
< n
*size1
)
7654 init_putz(sec
, c
+ len
, n
*size1
- len
);
7657 /* patch type size if needed, which happens only for array types */
7659 s
->c
= size1
== 1 ? len
: ((len
+ size1
- 1)/size1
);
7660 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
) {
7663 if ((flags
& DIF_FIRST
) || tok
== '{') {
7671 } else if (tok
== '{') {
7672 if (flags
& DIF_HAVE_ELEM
)
7675 decl_initializer(type
, sec
, c
, flags
& ~DIF_HAVE_ELEM
);
7677 } else if ((flags
& DIF_SIZE_ONLY
)) {
7678 /* If we supported only ISO C we wouldn't have to accept calling
7679 this on anything than an array if DIF_SIZE_ONLY (and even then
7680 only on the outermost level, so no recursion would be needed),
7681 because initializing a flex array member isn't supported.
7682 But GNU C supports it, so we need to recurse even into
7683 subfields of structs and arrays when DIF_SIZE_ONLY is set. */
7684 /* just skip expression */
7685 skip_or_save_block(NULL
);
7687 if (!(flags
& DIF_HAVE_ELEM
)) {
7688 /* This should happen only when we haven't parsed
7689 the init element above for fear of committing a
7690 string constant to memory too early. */
7691 if (tok
!= TOK_STR
&& tok
!= TOK_LSTR
)
7692 expect("string constant");
7693 parse_init_elem(!sec
? EXPR_ANY
: EXPR_CONST
);
7695 init_putv(type
, sec
, c
);
7699 /* parse an initializer for type 't' if 'has_init' is non zero, and
7700 allocate space in local or global data space ('r' is either
7701 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7702 variable 'v' of scope 'scope' is declared before initializers
7703 are parsed. If 'v' is zero, then a reference to the new object
7704 is put in the value stack. If 'has_init' is 2, a special parsing
7705 is done to handle string constants. */
7706 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
7707 int has_init
, int v
, int scope
)
7709 int size
, align
, addr
;
7710 TokenString
*init_str
= NULL
;
7713 Sym
*flexible_array
;
7715 int saved_nocode_wanted
= nocode_wanted
;
7716 #ifdef CONFIG_TCC_BCHECK
7717 int bcheck
= tcc_state
->do_bounds_check
&& !NODATA_WANTED
;
7720 /* Always allocate static or global variables */
7721 if (v
&& (r
& VT_VALMASK
) == VT_CONST
)
7722 nocode_wanted
|= 0x80000000;
7724 flexible_array
= NULL
;
7725 if ((type
->t
& VT_BTYPE
) == VT_STRUCT
) {
7726 Sym
*field
= type
->ref
->next
;
7729 field
= field
->next
;
7730 if (field
->type
.t
& VT_ARRAY
&& field
->type
.ref
->c
< 0)
7731 flexible_array
= field
;
7735 size
= type_size(type
, &align
);
7736 /* If unknown size, we must evaluate it before
7737 evaluating initializers because
7738 initializers can generate global data too
7739 (e.g. string pointers or ISOC99 compound
7740 literals). It also simplifies local
7741 initializers handling */
7742 if (size
< 0 || (flexible_array
&& has_init
)) {
7744 tcc_error("unknown type size");
7745 /* get all init string */
7746 if (has_init
== 2) {
7747 init_str
= tok_str_alloc();
7748 /* only get strings */
7749 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
7750 tok_str_add_tok(init_str
);
7753 tok_str_add(init_str
, -1);
7754 tok_str_add(init_str
, 0);
7756 skip_or_save_block(&init_str
);
7761 begin_macro(init_str
, 1);
7763 decl_initializer(type
, NULL
, 0, DIF_FIRST
| DIF_SIZE_ONLY
);
7764 /* prepare second initializer parsing */
7765 macro_ptr
= init_str
->str
;
7768 /* if still unknown size, error */
7769 size
= type_size(type
, &align
);
7771 tcc_error("unknown type size");
7773 /* If there's a flex member and it was used in the initializer
7775 if (flexible_array
&&
7776 flexible_array
->type
.ref
->c
> 0)
7777 size
+= flexible_array
->type
.ref
->c
7778 * pointed_size(&flexible_array
->type
);
7779 /* take into account specified alignment if bigger */
7780 if (ad
->a
.aligned
) {
7781 int speca
= 1 << (ad
->a
.aligned
- 1);
7784 } else if (ad
->a
.packed
) {
7788 if (!v
&& NODATA_WANTED
)
7789 size
= 0, align
= 1;
7791 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
7793 #ifdef CONFIG_TCC_BCHECK
7795 /* add padding between stack variables for bound checking */
7799 loc
= (loc
- size
) & -align
;
7801 #ifdef CONFIG_TCC_BCHECK
7803 /* add padding between stack variables for bound checking */
7808 /* local variable */
7809 #ifdef CONFIG_TCC_ASM
7810 if (ad
->asm_label
) {
7811 int reg
= asm_parse_regvar(ad
->asm_label
);
7813 r
= (r
& ~VT_VALMASK
) | reg
;
7816 sym
= sym_push(v
, type
, r
, addr
);
7817 if (ad
->cleanup_func
) {
7818 Sym
*cls
= sym_push2(&all_cleanups
,
7819 SYM_FIELD
| ++cur_scope
->cl
.n
, 0, 0);
7820 cls
->prev_tok
= sym
;
7821 cls
->next
= ad
->cleanup_func
;
7822 cls
->ncl
= cur_scope
->cl
.s
;
7823 cur_scope
->cl
.s
= cls
;
7828 /* push local reference */
7829 vset(type
, r
, addr
);
7832 if (v
&& scope
== VT_CONST
) {
7833 /* see if the symbol was already defined */
7836 patch_storage(sym
, ad
, type
);
7837 /* we accept several definitions of the same global variable. */
7838 if (!has_init
&& sym
->c
&& elfsym(sym
)->st_shndx
!= SHN_UNDEF
)
7843 /* allocate symbol in corresponding section */
7848 else if (tcc_state
->nocommon
)
7853 addr
= section_add(sec
, size
, align
);
7854 #ifdef CONFIG_TCC_BCHECK
7855 /* add padding if bound check */
7857 section_add(sec
, 1, 1);
7860 addr
= align
; /* SHN_COMMON is special, symbol value is align */
7861 sec
= common_section
;
7866 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
7867 patch_storage(sym
, ad
, NULL
);
7869 /* update symbol definition */
7870 put_extern_sym(sym
, sec
, addr
, size
);
7872 /* push global reference */
7873 vpush_ref(type
, sec
, addr
, size
);
7878 #ifdef CONFIG_TCC_BCHECK
7879 /* handles bounds now because the symbol must be defined
7880 before for the relocation */
7884 greloca(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_PTR
, 0);
7885 /* then add global bound info */
7886 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(addr_t
));
7887 bounds_ptr
[0] = 0; /* relocated */
7888 bounds_ptr
[1] = size
;
7893 if (type
->t
& VT_VLA
) {
7899 /* save current stack pointer */
7900 if (root_scope
->vla
.loc
== 0) {
7901 struct scope
*v
= cur_scope
;
7902 gen_vla_sp_save(loc
-= PTR_SIZE
);
7903 do v
->vla
.loc
= loc
; while ((v
= v
->prev
));
7906 vla_runtime_type_size(type
, &a
);
7907 gen_vla_alloc(type
, a
);
7908 #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
7909 /* on _WIN64, because of the function args scratch area, the
7910 result of alloca differs from RSP and is returned in RAX. */
7911 gen_vla_result(addr
), addr
= (loc
-= PTR_SIZE
);
7913 gen_vla_sp_save(addr
);
7914 cur_scope
->vla
.loc
= addr
;
7915 cur_scope
->vla
.num
++;
7916 #ifdef CONFIG_TCC_BCHECK
7917 tcc_state
->alloca_vla_used
|= bcheck
;
7919 } else if (has_init
) {
7920 size_t oldreloc_offset
= 0;
7921 if (sec
&& sec
->reloc
)
7922 oldreloc_offset
= sec
->reloc
->data_offset
;
7923 decl_initializer(type
, sec
, addr
, DIF_FIRST
);
7924 if (sec
&& sec
->reloc
)
7925 squeeze_multi_relocs(sec
, oldreloc_offset
);
7926 /* patch flexible array member size back to -1, */
7927 /* for possible subsequent similar declarations */
7929 flexible_array
->type
.ref
->c
= -1;
7933 /* restore parse state if needed */
7939 nocode_wanted
= saved_nocode_wanted
;
7942 /* parse a function defined by symbol 'sym' and generate its code in
7943 'cur_text_section' */
7944 static void gen_function(Sym
*sym
)
7946 /* Initialize VLA state */
7947 struct scope f
= { 0 };
7948 cur_scope
= root_scope
= &f
;
7951 #ifdef CONFIG_TCC_BCHECK
7952 tcc_state
->alloca_vla_used
= 0;
7954 ind
= cur_text_section
->data_offset
;
7955 if (sym
->a
.aligned
) {
7956 size_t newoff
= section_add(cur_text_section
, 0,
7957 1 << (sym
->a
.aligned
- 1));
7958 gen_fill_nops(newoff
- ind
);
7960 /* NOTE: we patch the symbol size later */
7961 put_extern_sym(sym
, cur_text_section
, ind
, 0);
7962 if (sym
->type
.ref
->f
.func_ctor
)
7963 add_array (tcc_state
, ".init_array", sym
->c
);
7964 if (sym
->type
.ref
->f
.func_dtor
)
7965 add_array (tcc_state
, ".fini_array", sym
->c
);
7966 funcname
= get_tok_str(sym
->v
, NULL
);
7968 /* put debug symbol */
7969 tcc_debug_funcstart(tcc_state
, sym
);
7970 /* push a dummy symbol to enable local sym storage */
7971 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
7972 local_scope
= 1; /* for function parameters */
7976 clear_temp_local_var_list();
7980 /* reset local stack */
7981 pop_local_syms(1, &local_stack
, NULL
, 0,
7982 sym
->type
.ref
->f
.func_type
== FUNC_ELLIPSIS
);
7984 cur_text_section
->data_offset
= ind
;
7986 label_pop(&global_label_stack
, NULL
, 0);
7987 sym_pop(&all_cleanups
, NULL
, 0);
7988 /* patch symbol size */
7989 elfsym(sym
)->st_size
= ind
- func_ind
;
7990 /* end of function */
7991 tcc_debug_funcend(tcc_state
, ind
- func_ind
);
7992 /* It's better to crash than to generate wrong code */
7993 cur_text_section
= NULL
;
7994 funcname
= ""; /* for safety */
7995 func_vt
.t
= VT_VOID
; /* for safety */
7996 func_var
= 0; /* for safety */
7997 ind
= 0; /* for safety */
7998 nocode_wanted
= 0x80000000;
8000 /* do this after funcend debug info */
8004 static void gen_inline_functions(TCCState
*s
)
8007 int inline_generated
, i
;
8008 struct InlineFunc
*fn
;
8010 tcc_open_bf(s
, ":inline:", 0);
8011 /* iterate while inline function are referenced */
8013 inline_generated
= 0;
8014 for (i
= 0; i
< s
->nb_inline_fns
; ++i
) {
8015 fn
= s
->inline_fns
[i
];
8017 if (sym
&& (sym
->c
|| !(sym
->type
.t
& VT_INLINE
))) {
8018 /* the function was used or forced (and then not internal):
8019 generate its code and convert it to a normal function */
8021 tcc_debug_putfile(s
, fn
->filename
);
8022 begin_macro(fn
->func_str
, 1);
8024 cur_text_section
= text_section
;
8028 inline_generated
= 1;
8031 } while (inline_generated
);
8035 static void free_inline_functions(TCCState
*s
)
8038 /* free tokens of unused inline functions */
8039 for (i
= 0; i
< s
->nb_inline_fns
; ++i
) {
8040 struct InlineFunc
*fn
= s
->inline_fns
[i
];
8042 tok_str_free(fn
->func_str
);
8044 dynarray_reset(&s
->inline_fns
, &s
->nb_inline_fns
);
8047 /* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
8048 if parsing old style parameter decl list (and FUNC_SYM is set then) */
8049 static int decl0(int l
, int is_for_loop_init
, Sym
*func_sym
)
8054 AttributeDef ad
, adbase
;
8057 if (tok
== TOK_STATIC_ASSERT
) {
8067 tcc_error("_Static_assert fail");
8069 goto static_assert_out
;
8073 parse_mult_str(&error_str
, "string constant");
8075 tcc_error("%s", (char *)error_str
.data
);
8076 cstr_free(&error_str
);
8082 if (!parse_btype(&btype
, &adbase
)) {
8083 if (is_for_loop_init
)
8085 /* skip redundant ';' if not in old parameter decl scope */
8086 if (tok
== ';' && l
!= VT_CMP
) {
8092 if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
8093 /* global asm block */
8097 if (tok
>= TOK_UIDENT
) {
8098 /* special test for old K&R protos without explicit int
8099 type. Only accepted when defining global data */
8103 expect("declaration");
8108 if ((btype
.t
& VT_BTYPE
) == VT_STRUCT
) {
8109 int v
= btype
.ref
->v
;
8110 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
)
8111 tcc_warning("unnamed struct/union that defines no instances");
8115 if (IS_ENUM(btype
.t
)) {
8120 while (1) { /* iterate thru each declaration */
8122 /* If the base type itself was an array type of unspecified
8123 size (like in 'typedef int arr[]; arr x = {1};') then
8124 we will overwrite the unknown size by the real one for
8125 this decl. We need to unshare the ref symbol holding
8127 if ((type
.t
& VT_ARRAY
) && type
.ref
->c
< 0) {
8128 type
.ref
= sym_push(SYM_FIELD
, &type
.ref
->type
, 0, type
.ref
->c
);
8131 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8135 type_to_str(buf
, sizeof(buf
), &type
, get_tok_str(v
, NULL
));
8136 printf("type = '%s'\n", buf
);
8139 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8140 if ((type
.t
& VT_STATIC
) && (l
== VT_LOCAL
))
8141 tcc_error("function without file scope cannot be static");
8142 /* if old style function prototype, we accept a
8145 if (sym
->f
.func_type
== FUNC_OLD
&& l
== VT_CONST
)
8146 decl0(VT_CMP
, 0, sym
);
8147 /* always compile 'extern inline' */
8148 if (type
.t
& VT_EXTERN
)
8149 type
.t
&= ~VT_INLINE
;
8152 if (gnu_ext
&& (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
8153 ad
.asm_label
= asm_label_instr();
8154 /* parse one last attribute list, after asm label */
8155 parse_attribute(&ad
);
8157 /* gcc does not allow __asm__("label") with function definition,
8164 #ifdef TCC_TARGET_PE
8165 if (ad
.a
.dllimport
|| ad
.a
.dllexport
) {
8166 if (type
.t
& VT_STATIC
)
8167 tcc_error("cannot have dll linkage with static");
8168 if (type
.t
& VT_TYPEDEF
) {
8169 tcc_warning("'%s' attribute ignored for typedef",
8170 ad
.a
.dllimport
? (ad
.a
.dllimport
= 0, "dllimport") :
8171 (ad
.a
.dllexport
= 0, "dllexport"));
8172 } else if (ad
.a
.dllimport
) {
8173 if ((type
.t
& VT_BTYPE
) == VT_FUNC
)
8176 type
.t
|= VT_EXTERN
;
8182 tcc_error("cannot use local functions");
8183 if ((type
.t
& VT_BTYPE
) != VT_FUNC
)
8184 expect("function definition");
8186 /* reject abstract declarators in function definition
8187 make old style params without decl have int type */
8189 while ((sym
= sym
->next
) != NULL
) {
8190 if (!(sym
->v
& ~SYM_FIELD
))
8191 expect("identifier");
8192 if (sym
->type
.t
== VT_VOID
)
8193 sym
->type
= int_type
;
8196 /* put function symbol */
8197 type
.t
&= ~VT_EXTERN
;
8198 sym
= external_sym(v
, &type
, 0, &ad
);
8199 /* static inline functions are just recorded as a kind
8200 of macro. Their code will be emitted at the end of
8201 the compilation unit only if they are used */
8202 if (sym
->type
.t
& VT_INLINE
) {
8203 struct InlineFunc
*fn
;
8204 fn
= tcc_malloc(sizeof *fn
+ strlen(file
->filename
));
8205 strcpy(fn
->filename
, file
->filename
);
8207 skip_or_save_block(&fn
->func_str
);
8208 dynarray_add(&tcc_state
->inline_fns
,
8209 &tcc_state
->nb_inline_fns
, fn
);
8211 /* compute text section */
8212 cur_text_section
= ad
.section
;
8213 if (!cur_text_section
)
8214 cur_text_section
= text_section
;
8220 /* find parameter in function parameter list */
8221 for (sym
= func_sym
->next
; sym
; sym
= sym
->next
)
8222 if ((sym
->v
& ~SYM_FIELD
) == v
)
8224 tcc_error("declaration for parameter '%s' but no such parameter",
8225 get_tok_str(v
, NULL
));
8227 if (type
.t
& VT_STORAGE
) /* 'register' is okay */
8228 tcc_error("storage class specified for '%s'",
8229 get_tok_str(v
, NULL
));
8230 if (sym
->type
.t
!= VT_VOID
)
8231 tcc_error("redefinition of parameter '%s'",
8232 get_tok_str(v
, NULL
));
8233 convert_parameter_type(&type
);
8235 } else if (type
.t
& VT_TYPEDEF
) {
8236 /* save typedefed type */
8237 /* XXX: test storage specifiers ? */
8239 if (sym
&& sym
->sym_scope
== local_scope
) {
8240 if (!is_compatible_types(&sym
->type
, &type
)
8241 || !(sym
->type
.t
& VT_TYPEDEF
))
8242 tcc_error("incompatible redefinition of '%s'",
8243 get_tok_str(v
, NULL
));
8246 sym
= sym_push(v
, &type
, 0, 0);
8250 } else if ((type
.t
& VT_BTYPE
) == VT_VOID
8251 && !(type
.t
& VT_EXTERN
)) {
8252 tcc_error("declaration of void object");
8255 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8256 /* external function definition */
8257 /* specific case for func_call attribute */
8259 } else if (!(type
.t
& VT_ARRAY
)) {
8260 /* not lvalue if array */
8263 has_init
= (tok
== '=');
8264 if (has_init
&& (type
.t
& VT_VLA
))
8265 tcc_error("variable length array cannot be initialized");
8266 if (((type
.t
& VT_EXTERN
) && (!has_init
|| l
!= VT_CONST
))
8267 || (type
.t
& VT_BTYPE
) == VT_FUNC
8268 /* as with GCC, uninitialized global arrays with no size
8269 are considered extern: */
8270 || ((type
.t
& VT_ARRAY
) && !has_init
8271 && l
== VT_CONST
&& type
.ref
->c
< 0)
8273 /* external variable or function */
8274 type
.t
|= VT_EXTERN
;
8275 sym
= external_sym(v
, &type
, r
, &ad
);
8276 if (ad
.alias_target
) {
8279 alias_target
= sym_find(ad
.alias_target
);
8280 esym
= elfsym(alias_target
);
8282 tcc_error("unsupported forward __alias__ attribute");
8283 put_extern_sym2(sym
, esym
->st_shndx
, esym
->st_value
, esym
->st_size
, 0);
8286 if (type
.t
& VT_STATIC
)
8292 else if (l
== VT_CONST
)
8293 /* uninitialized global variables may be overridden */
8294 type
.t
|= VT_EXTERN
;
8295 decl_initializer_alloc(&type
, &ad
, r
, has_init
, v
, l
);
8299 if (is_for_loop_init
)
8311 static void decl(int l
)
8316 /* ------------------------------------------------------------------------- */
8319 /* ------------------------------------------------------------------------- */