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
;
49 ST_DATA
char debug_modes
;
52 static SValue _vstack
[1 + VSTACK_SIZE
];
53 #define vstack (_vstack + 1)
55 ST_DATA
int const_wanted
; /* true if constant wanted */
56 ST_DATA
int nocode_wanted
; /* no code generation wanted */
57 #define unevalmask 0xffff /* unevaluated subexpression */
58 #define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
59 #define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */
61 /* Automagical code suppression ----> */
62 #define CODE_OFF() (nocode_wanted |= 0x20000000)
63 #define CODE_ON() (nocode_wanted &= ~0x20000000)
65 static void tcc_tcov_block_begin(void);
67 /* Clear 'nocode_wanted' at label if it was used */
68 ST_FUNC
void gsym(int t
) { if (t
) { gsym_addr(t
, ind
); CODE_ON(); }}
69 static int gind(void) { int t
= ind
; CODE_ON(); if (debug_modes
) tcc_tcov_block_begin(); return t
; }
71 /* Set 'nocode_wanted' after unconditional jumps */
72 static void gjmp_addr_acs(int t
) { gjmp_addr(t
); CODE_OFF(); }
73 static int gjmp_acs(int t
) { t
= gjmp(t
); CODE_OFF(); return t
; }
75 /* These are #undef'd at the end of this file */
76 #define gjmp_addr gjmp_addr_acs
80 ST_DATA
int global_expr
; /* true if compound literals must be allocated globally (used during initializers parsing */
81 ST_DATA CType func_vt
; /* current function return type (used by return instruction) */
82 ST_DATA
int func_var
; /* true if current function is variadic (used by return instruction) */
84 static int last_line_num
, new_file
, func_ind
; /* debug info control */
85 ST_DATA
const char *funcname
;
86 ST_DATA CType int_type
, func_old_type
, char_type
, char_pointer_type
;
87 static CString initstr
;
90 #define VT_SIZE_T (VT_INT | VT_UNSIGNED)
91 #define VT_PTRDIFF_T VT_INT
93 #define VT_SIZE_T (VT_LLONG | VT_UNSIGNED)
94 #define VT_PTRDIFF_T VT_LLONG
96 #define VT_SIZE_T (VT_LONG | VT_LLONG | VT_UNSIGNED)
97 #define VT_PTRDIFF_T (VT_LONG | VT_LLONG)
100 static struct switch_t
{
104 } **p
; int n
; /* list of case ranges */
105 int def_sym
; /* default symbol */
108 struct switch_t
*prev
;
110 } *cur_switch
; /* current switch */
112 #define MAX_TEMP_LOCAL_VARIABLE_NUMBER 8
113 /*list of temporary local variables on the stack in current function. */
114 static struct temp_local_variable
{
115 int location
; //offset on stack. Svalue.c.i
118 } arr_temp_local_vars
[MAX_TEMP_LOCAL_VARIABLE_NUMBER
];
119 static int nb_temp_local_vars
;
121 static struct scope
{
123 struct { int loc
, locorig
, num
; } vla
;
124 struct { Sym
*s
; int n
; } cl
;
127 } *cur_scope
, *loop_scope
, *root_scope
;
136 #define precedence_parser
137 static void init_prec(void);
140 /********************************************************/
141 /* stab debug support */
143 static const struct {
146 } default_debug
[] = {
147 { VT_INT
, "int:t1=r1;-2147483648;2147483647;" },
148 { VT_BYTE
, "char:t2=r2;0;127;" },
150 { VT_LONG
| VT_INT
, "long int:t3=r3;-2147483648;2147483647;" },
152 { VT_LLONG
| VT_LONG
, "long int:t3=r3;-9223372036854775808;9223372036854775807;" },
154 { VT_INT
| VT_UNSIGNED
, "unsigned int:t4=r4;0;037777777777;" },
156 { VT_LONG
| VT_INT
| VT_UNSIGNED
, "long unsigned int:t5=r5;0;037777777777;" },
158 /* use octal instead of -1 so size_t works (-gstabs+ in gcc) */
159 { VT_LLONG
| VT_LONG
| VT_UNSIGNED
, "long unsigned int:t5=r5;0;01777777777777777777777;" },
161 { VT_QLONG
, "__int128:t6=r6;0;-1;" },
162 { VT_QLONG
| VT_UNSIGNED
, "__int128 unsigned:t7=r7;0;-1;" },
163 { VT_LLONG
, "long long int:t8=r8;-9223372036854775808;9223372036854775807;" },
164 { VT_LLONG
| VT_UNSIGNED
, "long long unsigned int:t9=r9;0;01777777777777777777777;" },
165 { VT_SHORT
, "short int:t10=r10;-32768;32767;" },
166 { VT_SHORT
| VT_UNSIGNED
, "short unsigned int:t11=r11;0;65535;" },
167 { VT_BYTE
| VT_DEFSIGN
, "signed char:t12=r12;-128;127;" },
168 { VT_BYTE
| VT_DEFSIGN
| VT_UNSIGNED
, "unsigned char:t13=r13;0;255;" },
169 { VT_FLOAT
, "float:t14=r1;4;0;" },
170 { VT_DOUBLE
, "double:t15=r1;8;0;" },
171 #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
172 { VT_DOUBLE
| VT_LONG
, "long double:t16=r1;8;0;" },
174 { VT_LDOUBLE
, "long double:t16=r1;16;0;" },
176 { -1, "_Float32:t17=r1;4;0;" },
177 { -1, "_Float64:t18=r1;8;0;" },
178 { -1, "_Float128:t19=r1;16;0;" },
179 { -1, "_Float32x:t20=r1;8;0;" },
180 { -1, "_Float64x:t21=r1;16;0;" },
181 { -1, "_Decimal32:t22=r1;4;0;" },
182 { -1, "_Decimal64:t23=r1;8;0;" },
183 { -1, "_Decimal128:t24=r1;16;0;" },
184 /* if default char is unsigned */
185 { VT_BYTE
| VT_UNSIGNED
, "unsigned char:t25=r25;0;255;" },
187 { VT_BOOL
, "bool:t26=r26;0;255;" },
188 { VT_VOID
, "void:t27=27" },
191 static int debug_next_type
;
193 static struct debug_hash
{
198 static int n_debug_hash
;
200 static struct debug_info
{
211 struct debug_info
*child
, *next
, *last
, *parent
;
212 } *debug_info
, *debug_info_root
;
215 unsigned long offset
;
216 unsigned long last_file_name
;
217 unsigned long last_func_name
;
222 /********************************************************/
223 static void gen_cast(CType
*type
);
224 static void gen_cast_s(int t
);
225 static inline CType
*pointed_type(CType
*type
);
226 static int is_compatible_types(CType
*type1
, CType
*type2
);
227 static int parse_btype(CType
*type
, AttributeDef
*ad
);
228 static CType
*type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
229 static void parse_expr_type(CType
*type
);
230 static void init_putv(init_params
*p
, CType
*type
, unsigned long c
);
231 static void decl_initializer(init_params
*p
, CType
*type
, unsigned long c
, int flags
);
232 static void block(int is_expr
);
233 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
, int has_init
, int v
, int scope
);
234 static void decl(int l
);
235 static int decl0(int l
, int is_for_loop_init
, Sym
*);
236 static void expr_eq(void);
237 static void vpush_type_size(CType
*type
, int *a
);
238 static int is_compatible_unqualified_types(CType
*type1
, CType
*type2
);
239 static inline int64_t expr_const64(void);
240 static void vpush64(int ty
, unsigned long long v
);
241 static void vpush(CType
*type
);
242 static int gvtst(int inv
, int t
);
243 static void gen_inline_functions(TCCState
*s
);
244 static void free_inline_functions(TCCState
*s
);
245 static void skip_or_save_block(TokenString
**str
);
246 static void gv_dup(void);
247 static int get_temp_local_var(int size
,int align
);
248 static void clear_temp_local_var_list();
249 static void cast_error(CType
*st
, CType
*dt
);
251 ST_INLN
int is_float(int t
)
253 int bt
= t
& VT_BTYPE
;
254 return bt
== VT_LDOUBLE
260 static inline int is_integer_btype(int bt
)
269 static int btype_size(int bt
)
271 return bt
== VT_BYTE
|| bt
== VT_BOOL
? 1 :
275 bt
== VT_PTR
? PTR_SIZE
: 0;
278 /* returns function return register from type */
279 static int R_RET(int t
)
283 #ifdef TCC_TARGET_X86_64
284 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
286 #elif defined TCC_TARGET_RISCV64
287 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
293 /* returns 2nd function return register, if any */
294 static int R2_RET(int t
)
300 #elif defined TCC_TARGET_X86_64
305 #elif defined TCC_TARGET_RISCV64
312 /* returns true for two-word types */
313 #define USING_TWO_WORDS(t) (R2_RET(t) != VT_CONST)
315 /* put function return registers to stack value */
316 static void PUT_R_RET(SValue
*sv
, int t
)
318 sv
->r
= R_RET(t
), sv
->r2
= R2_RET(t
);
321 /* returns function return register class for type t */
322 static int RC_RET(int t
)
324 return reg_classes
[R_RET(t
)] & ~(RC_FLOAT
| RC_INT
);
327 /* returns generic register class for type t */
328 static int RC_TYPE(int t
)
332 #ifdef TCC_TARGET_X86_64
333 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
335 if ((t
& VT_BTYPE
) == VT_QFLOAT
)
337 #elif defined TCC_TARGET_RISCV64
338 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
344 /* returns 2nd register class corresponding to t and rc */
345 static int RC2_TYPE(int t
, int rc
)
347 if (!USING_TWO_WORDS(t
))
362 /* we use our own 'finite' function to avoid potential problems with
363 non standard math libs */
364 /* XXX: endianness dependent */
365 ST_FUNC
int ieee_finite(double d
)
368 memcpy(p
, &d
, sizeof(double));
369 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
372 /* compiling intel long double natively */
373 #if (defined __i386__ || defined __x86_64__) \
374 && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
375 # define TCC_IS_NATIVE_387
378 ST_FUNC
void test_lvalue(void)
380 if (!(vtop
->r
& VT_LVAL
))
384 ST_FUNC
void check_vstack(void)
386 if (vtop
!= vstack
- 1)
387 tcc_error("internal compiler error: vstack leak (%d)",
388 (int)(vtop
- vstack
+ 1));
391 /* ------------------------------------------------------------------------- */
392 /* vstack debugging aid */
395 void pv (const char *lbl
, int a
, int b
)
398 for (i
= a
; i
< a
+ b
; ++i
) {
399 SValue
*p
= &vtop
[-i
];
400 printf("%s vtop[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n",
401 lbl
, i
, p
->type
.t
, p
->r
, p
->r2
, (int)p
->c
.i
);
406 /* ------------------------------------------------------------------------- */
407 /* start of translation unit info */
408 ST_FUNC
void tcc_debug_start(TCCState
*s1
)
414 /* file info: full path + filename */
415 section_sym
= put_elf_sym(symtab_section
, 0, 0,
416 ELFW(ST_INFO
)(STB_LOCAL
, STT_SECTION
), 0,
417 text_section
->sh_num
, NULL
);
418 getcwd(buf
, sizeof(buf
));
420 normalize_slashes(buf
);
422 pstrcat(buf
, sizeof(buf
), "/");
423 put_stabs_r(s1
, buf
, N_SO
, 0, 0,
424 text_section
->data_offset
, text_section
, section_sym
);
425 put_stabs_r(s1
, file
->prev
? file
->prev
->filename
: file
->filename
,
427 text_section
->data_offset
, text_section
, section_sym
);
428 for (i
= 0; i
< sizeof (default_debug
) / sizeof (default_debug
[0]); i
++)
429 put_stabs(s1
, default_debug
[i
].name
, N_LSYM
, 0, 0, 0);
431 new_file
= last_line_num
= 0;
433 debug_next_type
= sizeof(default_debug
) / sizeof(default_debug
[0]);
437 /* we're currently 'including' the <command line> */
441 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
442 symbols can be safely used */
443 put_elf_sym(symtab_section
, 0, 0,
444 ELFW(ST_INFO
)(STB_LOCAL
, STT_FILE
), 0,
445 SHN_ABS
, file
->filename
);
448 /* put end of translation unit info */
449 ST_FUNC
void tcc_debug_end(TCCState
*s1
)
453 put_stabs_r(s1
, NULL
, N_SO
, 0, 0,
454 text_section
->data_offset
, text_section
, section_sym
);
455 tcc_free(debug_hash
);
458 static BufferedFile
* put_new_file(TCCState
*s1
)
460 BufferedFile
*f
= file
;
461 /* use upper file if from inline ":asm:" */
462 if (f
->filename
[0] == ':')
465 put_stabs_r(s1
, f
->filename
, N_SOL
, 0, 0, ind
, text_section
, section_sym
);
466 new_file
= last_line_num
= 0;
471 /* put alternative filename */
472 ST_FUNC
void tcc_debug_putfile(TCCState
*s1
, const char *filename
)
474 if (0 == strcmp(file
->filename
, filename
))
476 pstrcpy(file
->filename
, sizeof(file
->filename
), filename
);
480 /* begin of #include */
481 ST_FUNC
void tcc_debug_bincl(TCCState
*s1
)
485 put_stabs(s1
, file
->filename
, N_BINCL
, 0, 0, 0);
489 /* end of #include */
490 ST_FUNC
void tcc_debug_eincl(TCCState
*s1
)
494 put_stabn(s1
, N_EINCL
, 0, 0, 0);
498 /* generate line number info */
499 static void tcc_debug_line(TCCState
*s1
)
503 || cur_text_section
!= text_section
504 || !(f
= put_new_file(s1
))
505 || last_line_num
== f
->line_num
)
507 if (func_ind
!= -1) {
508 put_stabn(s1
, N_SLINE
, 0, f
->line_num
, ind
- func_ind
);
510 /* from tcc_assemble */
511 put_stabs_r(s1
, NULL
, N_SLINE
, 0, f
->line_num
, ind
, text_section
, section_sym
);
513 last_line_num
= f
->line_num
;
516 static void tcc_debug_stabs (TCCState
*s1
, const char *str
, int type
, unsigned long value
,
517 Section
*sec
, int sym_index
)
523 (struct debug_sym
*)tcc_realloc (debug_info
->sym
,
524 sizeof(struct debug_sym
) *
525 (debug_info
->n_sym
+ 1));
526 s
= debug_info
->sym
+ debug_info
->n_sym
++;
529 s
->str
= tcc_strdup(str
);
531 s
->sym_index
= sym_index
;
534 put_stabs_r (s1
, str
, type
, 0, 0, value
, sec
, sym_index
);
536 put_stabs (s1
, str
, type
, 0, 0, value
);
539 static void tcc_debug_stabn(TCCState
*s1
, int type
, int value
)
543 if (type
== N_LBRAC
) {
544 struct debug_info
*info
=
545 (struct debug_info
*) tcc_mallocz(sizeof (*info
));
548 info
->parent
= debug_info
;
550 if (debug_info
->child
) {
551 if (debug_info
->child
->last
)
552 debug_info
->child
->last
->next
= info
;
554 debug_info
->child
->next
= info
;
555 debug_info
->child
->last
= info
;
558 debug_info
->child
= info
;
561 debug_info_root
= info
;
565 debug_info
->end
= value
;
566 debug_info
= debug_info
->parent
;
570 static void tcc_get_debug_info(TCCState
*s1
, Sym
*s
, CString
*result
)
579 type
= t
->type
.t
& ~(VT_STORAGE
| VT_CONSTANT
| VT_VOLATILE
);
580 if ((type
& VT_BTYPE
) != VT_BYTE
)
582 if (type
== VT_PTR
|| type
== (VT_PTR
| VT_ARRAY
))
583 n
++, t
= t
->type
.ref
;
587 if ((type
& VT_BTYPE
) == VT_STRUCT
) {
591 for (i
= 0; i
< n_debug_hash
; i
++) {
592 if (t
== debug_hash
[i
].type
) {
593 debug_type
= debug_hash
[i
].debug_type
;
597 if (debug_type
== -1) {
598 debug_type
= ++debug_next_type
;
599 debug_hash
= (struct debug_hash
*)
600 tcc_realloc (debug_hash
,
601 (n_debug_hash
+ 1) * sizeof(*debug_hash
));
602 debug_hash
[n_debug_hash
].debug_type
= debug_type
;
603 debug_hash
[n_debug_hash
++].type
= t
;
605 cstr_printf (&str
, "%s:T%d=%c%d",
606 (t
->v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
607 ? "" : get_tok_str(t
->v
& ~SYM_STRUCT
, NULL
),
609 IS_UNION (t
->type
.t
) ? 'u' : 's',
612 int pos
, size
, align
;
615 cstr_printf (&str
, "%s:",
616 (t
->v
& ~SYM_FIELD
) >= SYM_FIRST_ANOM
617 ? "" : get_tok_str(t
->v
& ~SYM_FIELD
, NULL
));
618 tcc_get_debug_info (s1
, t
, &str
);
619 if (t
->type
.t
& VT_BITFIELD
) {
620 pos
= t
->c
* 8 + BIT_POS(t
->type
.t
);
621 size
= BIT_SIZE(t
->type
.t
);
625 size
= type_size(&t
->type
, &align
) * 8;
627 cstr_printf (&str
, ",%d,%d;", pos
, size
);
629 cstr_printf (&str
, ";");
630 tcc_debug_stabs(s1
, str
.data
, N_LSYM
, 0, NULL
, 0);
634 else if (IS_ENUM(type
)) {
635 Sym
*e
= t
= t
->type
.ref
;
637 debug_type
= ++debug_next_type
;
639 cstr_printf (&str
, "%s:T%d=e",
640 (t
->v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
641 ? "" : get_tok_str(t
->v
& ~SYM_STRUCT
, NULL
),
645 cstr_printf (&str
, "%s:",
646 (t
->v
& ~SYM_FIELD
) >= SYM_FIRST_ANOM
647 ? "" : get_tok_str(t
->v
& ~SYM_FIELD
, NULL
));
648 cstr_printf (&str
, e
->type
.t
& VT_UNSIGNED
? "%u," : "%d,",
651 cstr_printf (&str
, ";");
652 tcc_debug_stabs(s1
, str
.data
, N_LSYM
, 0, NULL
, 0);
655 else if ((type
& VT_BTYPE
) != VT_FUNC
) {
656 type
&= ~VT_STRUCT_MASK
;
658 debug_type
<= sizeof(default_debug
) / sizeof(default_debug
[0]);
660 if (default_debug
[debug_type
- 1].type
== type
)
662 if (debug_type
> sizeof(default_debug
) / sizeof(default_debug
[0]))
666 cstr_printf (result
, "%d=", ++debug_next_type
);
669 type
= t
->type
.t
& ~(VT_STORAGE
| VT_CONSTANT
| VT_VOLATILE
);
670 if ((type
& VT_BTYPE
) != VT_BYTE
)
673 cstr_printf (result
, "%d=*", ++debug_next_type
);
674 else if (type
== (VT_PTR
| VT_ARRAY
))
675 cstr_printf (result
, "%d=ar1;0;%d;",
676 ++debug_next_type
, t
->type
.ref
->c
- 1);
677 else if (type
== VT_FUNC
) {
678 cstr_printf (result
, "%d=f", ++debug_next_type
);
679 tcc_get_debug_info (s1
, t
->type
.ref
, result
);
686 cstr_printf (result
, "%d", debug_type
);
689 static void tcc_debug_finish (TCCState
*s1
, struct debug_info
*cur
)
693 struct debug_info
*next
= cur
->next
;
695 for (i
= 0; i
< cur
->n_sym
; i
++) {
696 struct debug_sym
*s
= &cur
->sym
[i
];
699 put_stabs_r(s1
, s
->str
, s
->type
, 0, 0, s
->value
,
700 s
->sec
, s
->sym_index
);
702 put_stabs(s1
, s
->str
, s
->type
, 0, 0, s
->value
);
706 put_stabn(s1
, N_LBRAC
, 0, 0, cur
->start
);
707 tcc_debug_finish (s1
, cur
->child
);
708 put_stabn(s1
, N_RBRAC
, 0, 0, cur
->end
);
714 static void tcc_add_debug_info(TCCState
*s1
, int param
, Sym
*s
, Sym
*e
)
719 cstr_new (&debug_str
);
720 for (; s
!= e
; s
= s
->prev
) {
721 if (!s
->v
|| (s
->r
& VT_VALMASK
) != VT_LOCAL
)
723 cstr_reset (&debug_str
);
724 cstr_printf (&debug_str
, "%s:%s", get_tok_str(s
->v
, NULL
), param
? "p" : "");
725 tcc_get_debug_info(s1
, s
, &debug_str
);
726 tcc_debug_stabs(s1
, debug_str
.data
, param
? N_PSYM
: N_LSYM
, s
->c
, NULL
, 0);
728 cstr_free (&debug_str
);
731 /* put function symbol */
732 static void tcc_debug_funcstart(TCCState
*s1
, Sym
*sym
)
738 debug_info_root
= NULL
;
740 tcc_debug_stabn(s1
, N_LBRAC
, ind
- func_ind
);
741 if (!(f
= put_new_file(s1
)))
743 cstr_new (&debug_str
);
744 cstr_printf(&debug_str
, "%s:%c", funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
745 tcc_get_debug_info(s1
, sym
->type
.ref
, &debug_str
);
746 put_stabs_r(s1
, debug_str
.data
, N_FUN
, 0, f
->line_num
, 0, cur_text_section
, sym
->c
);
747 cstr_free (&debug_str
);
752 /* put function size */
753 static void tcc_debug_funcend(TCCState
*s1
, int size
)
757 tcc_debug_stabn(s1
, N_RBRAC
, size
);
758 tcc_debug_finish (s1
, debug_info_root
);
762 static void tcc_debug_extern_sym(TCCState
*s1
, Sym
*sym
, int sh_num
, int sym_bind
, int sym_type
)
769 if (sym_type
== STT_FUNC
|| sym
->v
>= SYM_FIRST_ANOM
)
771 s
= s1
->sections
[sh_num
];
774 cstr_printf (&str
, "%s:%c",
775 get_tok_str(sym
->v
, NULL
),
776 sym_bind
== STB_GLOBAL
? 'G' : local_scope
? 'V' : 'S'
778 tcc_get_debug_info(s1
, sym
, &str
);
779 if (sym_bind
== STB_GLOBAL
)
780 tcc_debug_stabs(s1
, str
.data
, N_GSYM
, 0, NULL
, 0);
782 tcc_debug_stabs(s1
, str
.data
,
783 (sym
->type
.t
& VT_STATIC
) && data_section
== s
784 ? N_STSYM
: N_LCSYM
, 0, s
, sym
->c
);
788 static void tcc_debug_typedef(TCCState
*s1
, Sym
*sym
)
795 cstr_printf (&str
, "%s:t",
796 (sym
->v
& ~SYM_FIELD
) >= SYM_FIRST_ANOM
797 ? "" : get_tok_str(sym
->v
& ~SYM_FIELD
, NULL
));
798 tcc_get_debug_info(s1
, sym
, &str
);
799 tcc_debug_stabs(s1
, str
.data
, N_LSYM
, 0, NULL
, 0);
803 /* ------------------------------------------------------------------------- */
804 /* for section layout see lib/tcov.c */
806 static void tcc_tcov_block_end(int line
);
808 static void tcc_tcov_block_begin(void)
812 unsigned long last_offset
= tcov_data
.offset
;
814 tcc_tcov_block_end (0);
815 if (tcc_state
->test_coverage
== 0 || nocode_wanted
)
818 if (tcov_data
.last_file_name
== 0 ||
819 strcmp ((const char *)(tcov_section
->data
+ tcov_data
.last_file_name
),
820 file
->true_filename
) != 0) {
824 if (tcov_data
.last_func_name
)
825 section_ptr_add(tcov_section
, 1);
826 if (tcov_data
.last_file_name
)
827 section_ptr_add(tcov_section
, 1);
828 tcov_data
.last_func_name
= 0;
830 if (file
->true_filename
[0] == '/') {
831 tcov_data
.last_file_name
= tcov_section
->data_offset
;
832 cstr_printf (&cstr
, "%s", file
->true_filename
);
835 getcwd (wd
, sizeof(wd
));
836 tcov_data
.last_file_name
= tcov_section
->data_offset
+ strlen(wd
) + 1;
837 cstr_printf (&cstr
, "%s/%s", wd
, file
->true_filename
);
839 ptr
= section_ptr_add(tcov_section
, cstr
.size
+ 1);
840 strcpy((char *)ptr
, cstr
.data
);
842 normalize_slashes((char *)ptr
);
846 if (tcov_data
.last_func_name
== 0 ||
847 strcmp ((const char *)(tcov_section
->data
+ tcov_data
.last_func_name
),
851 if (tcov_data
.last_func_name
)
852 section_ptr_add(tcov_section
, 1);
853 tcov_data
.last_func_name
= tcov_section
->data_offset
;
854 len
= strlen (funcname
);
855 ptr
= section_ptr_add(tcov_section
, len
+ 1);
856 strcpy((char *)ptr
, funcname
);
857 section_ptr_add(tcov_section
, -tcov_section
->data_offset
& 7);
858 ptr
= section_ptr_add(tcov_section
, 8);
859 write64le (ptr
, file
->line_num
);
861 if (ind
== tcov_data
.ind
&& tcov_data
.line
== file
->line_num
)
862 tcov_data
.offset
= last_offset
;
865 label
.type
.t
= VT_LLONG
| VT_STATIC
;
867 ptr
= section_ptr_add(tcov_section
, 16);
868 tcov_data
.line
= file
->line_num
;
869 write64le (ptr
, (tcov_data
.line
<< 8) | 0xff);
870 put_extern_sym(&label
, tcov_section
,
871 ((unsigned char *)ptr
- tcov_section
->data
) + 8, 0);
872 sv
.type
= label
.type
;
873 sv
.r
= VT_SYM
| VT_LVAL
| VT_CONST
;
877 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || \
878 defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 || \
879 defined TCC_TARGET_RISCV64
880 gen_increment_tcov (&sv
);
886 tcov_data
.offset
= (unsigned char *)ptr
- tcov_section
->data
;
891 static void tcc_tcov_block_end(int line
)
893 if (tcc_state
->test_coverage
== 0)
895 if (tcov_data
.offset
) {
896 void *ptr
= tcov_section
->data
+ tcov_data
.offset
;
897 unsigned long long nline
= line
? line
: file
->line_num
;
899 write64le (ptr
, (read64le (ptr
) & 0xfffffffffull
) | (nline
<< 36));
900 tcov_data
.offset
= 0;
904 static void tcc_tcov_check_line(int start
)
906 if (tcc_state
->test_coverage
== 0)
908 if (tcov_data
.line
!= file
->line_num
) {
909 if ((tcov_data
.line
+ 1) != file
->line_num
) {
910 tcc_tcov_block_end (tcov_data
.line
);
912 tcc_tcov_block_begin ();
915 tcov_data
.line
= file
->line_num
;
919 static void tcc_tcov_start(void)
921 if (tcc_state
->test_coverage
== 0)
923 memset (&tcov_data
, 0, sizeof (tcov_data
));
924 if (tcov_section
== NULL
) {
925 tcov_section
= new_section(tcc_state
, ".tcov", SHT_PROGBITS
,
926 SHF_ALLOC
| SHF_WRITE
);
927 section_ptr_add(tcov_section
, 4); // pointer to executable name
931 static void tcc_tcov_end(void)
933 if (tcc_state
->test_coverage
== 0)
935 if (tcov_data
.last_func_name
)
936 section_ptr_add(tcov_section
, 1);
937 if (tcov_data
.last_file_name
)
938 section_ptr_add(tcov_section
, 1);
941 /* ------------------------------------------------------------------------- */
942 /* initialize vstack and types. This must be done also for tcc -E */
943 ST_FUNC
void tccgen_init(TCCState
*s1
)
946 memset(vtop
, 0, sizeof *vtop
);
948 /* define some often used types */
951 char_type
.t
= VT_BYTE
;
952 if (s1
->char_is_unsigned
)
953 char_type
.t
|= VT_UNSIGNED
;
954 char_pointer_type
= char_type
;
955 mk_pointer(&char_pointer_type
);
957 func_old_type
.t
= VT_FUNC
;
958 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, 0, 0);
959 func_old_type
.ref
->f
.func_call
= FUNC_CDECL
;
960 func_old_type
.ref
->f
.func_type
= FUNC_OLD
;
961 #ifdef precedence_parser
967 ST_FUNC
int tccgen_compile(TCCState
*s1
)
969 cur_text_section
= NULL
;
971 anon_sym
= SYM_FIRST_ANOM
;
974 nocode_wanted
= 0x80000000;
976 debug_modes
= s1
->do_debug
| s1
->test_coverage
<< 1;
980 #ifdef TCC_TARGET_ARM
984 printf("%s: **** new file\n", file
->filename
);
986 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
| PARSE_FLAG_TOK_STR
;
989 gen_inline_functions(s1
);
991 /* end of translation unit info */
997 ST_FUNC
void tccgen_finish(TCCState
*s1
)
1000 free_inline_functions(s1
);
1001 sym_pop(&global_stack
, NULL
, 0);
1002 sym_pop(&local_stack
, NULL
, 0);
1003 /* free preprocessor macros */
1005 /* free sym_pools */
1006 dynarray_reset(&sym_pools
, &nb_sym_pools
);
1007 sym_free_first
= NULL
;
1010 /* ------------------------------------------------------------------------- */
1011 ST_FUNC ElfSym
*elfsym(Sym
*s
)
1015 return &((ElfSym
*)symtab_section
->data
)[s
->c
];
1018 /* apply storage attributes to Elf symbol */
1019 ST_FUNC
void update_storage(Sym
*sym
)
1022 int sym_bind
, old_sym_bind
;
1028 if (sym
->a
.visibility
)
1029 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
1030 | sym
->a
.visibility
;
1032 if (sym
->type
.t
& (VT_STATIC
| VT_INLINE
))
1033 sym_bind
= STB_LOCAL
;
1034 else if (sym
->a
.weak
)
1035 sym_bind
= STB_WEAK
;
1037 sym_bind
= STB_GLOBAL
;
1038 old_sym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
1039 if (sym_bind
!= old_sym_bind
) {
1040 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, ELFW(ST_TYPE
)(esym
->st_info
));
1043 #ifdef TCC_TARGET_PE
1044 if (sym
->a
.dllimport
)
1045 esym
->st_other
|= ST_PE_IMPORT
;
1046 if (sym
->a
.dllexport
)
1047 esym
->st_other
|= ST_PE_EXPORT
;
1051 printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n",
1052 get_tok_str(sym
->v
, NULL
),
1053 sym_bind
== STB_WEAK
? 'w' : sym_bind
== STB_LOCAL
? 'l' : 'g',
1061 /* ------------------------------------------------------------------------- */
1062 /* update sym->c so that it points to an external symbol in section
1063 'section' with value 'value' */
1065 ST_FUNC
void put_extern_sym2(Sym
*sym
, int sh_num
,
1066 addr_t value
, unsigned long size
,
1067 int can_add_underscore
)
1069 int sym_type
, sym_bind
, info
, other
, t
;
1075 name
= get_tok_str(sym
->v
, NULL
);
1077 if ((t
& VT_BTYPE
) == VT_FUNC
) {
1078 sym_type
= STT_FUNC
;
1079 } else if ((t
& VT_BTYPE
) == VT_VOID
) {
1080 sym_type
= STT_NOTYPE
;
1081 if ((t
& (VT_BTYPE
|VT_ASM_FUNC
)) == VT_ASM_FUNC
)
1082 sym_type
= STT_FUNC
;
1084 sym_type
= STT_OBJECT
;
1086 if (t
& (VT_STATIC
| VT_INLINE
))
1087 sym_bind
= STB_LOCAL
;
1089 sym_bind
= STB_GLOBAL
;
1092 #ifdef TCC_TARGET_PE
1093 if (sym_type
== STT_FUNC
&& sym
->type
.ref
) {
1094 Sym
*ref
= sym
->type
.ref
;
1095 if (ref
->a
.nodecorate
) {
1096 can_add_underscore
= 0;
1098 if (ref
->f
.func_call
== FUNC_STDCALL
&& can_add_underscore
) {
1099 sprintf(buf1
, "_%s@%d", name
, ref
->f
.func_args
* PTR_SIZE
);
1101 other
|= ST_PE_STDCALL
;
1102 can_add_underscore
= 0;
1107 if (sym
->asm_label
) {
1108 name
= get_tok_str(sym
->asm_label
, NULL
);
1109 can_add_underscore
= 0;
1112 if (tcc_state
->leading_underscore
&& can_add_underscore
) {
1114 pstrcpy(buf1
+ 1, sizeof(buf1
) - 1, name
);
1118 info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
1119 sym
->c
= put_elf_sym(symtab_section
, value
, size
, info
, other
, sh_num
, name
);
1122 tcc_debug_extern_sym(tcc_state
, sym
, sh_num
, sym_bind
, sym_type
);
1126 esym
->st_value
= value
;
1127 esym
->st_size
= size
;
1128 esym
->st_shndx
= sh_num
;
1130 update_storage(sym
);
1133 ST_FUNC
void put_extern_sym(Sym
*sym
, Section
*section
,
1134 addr_t value
, unsigned long size
)
1136 int sh_num
= section
? section
->sh_num
: SHN_UNDEF
;
1137 put_extern_sym2(sym
, sh_num
, value
, size
, 1);
1140 /* add a new relocation entry to symbol 'sym' in section 's' */
1141 ST_FUNC
void greloca(Section
*s
, Sym
*sym
, unsigned long offset
, int type
,
1146 if (nocode_wanted
&& s
== cur_text_section
)
1151 put_extern_sym(sym
, NULL
, 0, 0);
1155 /* now we can add ELF relocation info */
1156 put_elf_reloca(symtab_section
, s
, offset
, type
, c
, addend
);
1160 ST_FUNC
void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
1162 greloca(s
, sym
, offset
, type
, 0);
1166 /* ------------------------------------------------------------------------- */
1167 /* symbol allocator */
1168 static Sym
*__sym_malloc(void)
1170 Sym
*sym_pool
, *sym
, *last_sym
;
1173 sym_pool
= tcc_malloc(SYM_POOL_NB
* sizeof(Sym
));
1174 dynarray_add(&sym_pools
, &nb_sym_pools
, sym_pool
);
1176 last_sym
= sym_free_first
;
1178 for(i
= 0; i
< SYM_POOL_NB
; i
++) {
1179 sym
->next
= last_sym
;
1183 sym_free_first
= last_sym
;
1187 static inline Sym
*sym_malloc(void)
1191 sym
= sym_free_first
;
1193 sym
= __sym_malloc();
1194 sym_free_first
= sym
->next
;
1197 sym
= tcc_malloc(sizeof(Sym
));
1202 ST_INLN
void sym_free(Sym
*sym
)
1205 sym
->next
= sym_free_first
;
1206 sym_free_first
= sym
;
1212 /* push, without hashing */
1213 ST_FUNC Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1218 memset(s
, 0, sizeof *s
);
1228 /* find a symbol and return its associated structure. 's' is the top
1229 of the symbol stack */
1230 ST_FUNC Sym
*sym_find2(Sym
*s
, int v
)
1235 else if (s
->v
== -1)
1242 /* structure lookup */
1243 ST_INLN Sym
*struct_find(int v
)
1246 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1248 return table_ident
[v
]->sym_struct
;
1251 /* find an identifier */
1252 ST_INLN Sym
*sym_find(int v
)
1255 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1257 return table_ident
[v
]->sym_identifier
;
1260 static int sym_scope(Sym
*s
)
1262 if (IS_ENUM_VAL (s
->type
.t
))
1263 return s
->type
.ref
->sym_scope
;
1265 return s
->sym_scope
;
1268 /* push a given symbol on the symbol stack */
1269 ST_FUNC Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1278 s
= sym_push2(ps
, v
, type
->t
, c
);
1279 s
->type
.ref
= type
->ref
;
1281 /* don't record fields or anonymous symbols */
1283 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1284 /* record symbol in token array */
1285 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1287 ps
= &ts
->sym_struct
;
1289 ps
= &ts
->sym_identifier
;
1292 s
->sym_scope
= local_scope
;
1293 if (s
->prev_tok
&& sym_scope(s
->prev_tok
) == s
->sym_scope
)
1294 tcc_error("redeclaration of '%s'",
1295 get_tok_str(v
& ~SYM_STRUCT
, NULL
));
1300 /* push a global identifier */
1301 ST_FUNC Sym
*global_identifier_push(int v
, int t
, int c
)
1304 s
= sym_push2(&global_stack
, v
, t
, c
);
1305 s
->r
= VT_CONST
| VT_SYM
;
1306 /* don't record anonymous symbol */
1307 if (v
< SYM_FIRST_ANOM
) {
1308 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1309 /* modify the top most local identifier, so that sym_identifier will
1310 point to 's' when popped; happens when called from inline asm */
1311 while (*ps
!= NULL
&& (*ps
)->sym_scope
)
1312 ps
= &(*ps
)->prev_tok
;
1319 /* pop symbols until top reaches 'b'. If KEEP is non-zero don't really
1320 pop them yet from the list, but do remove them from the token array. */
1321 ST_FUNC
void sym_pop(Sym
**ptop
, Sym
*b
, int keep
)
1331 /* remove symbol in token array */
1333 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1334 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1336 ps
= &ts
->sym_struct
;
1338 ps
= &ts
->sym_identifier
;
1349 /* ------------------------------------------------------------------------- */
1350 static void vcheck_cmp(void)
1352 /* cannot let cpu flags if other instruction are generated. Also
1353 avoid leaving VT_JMP anywhere except on the top of the stack
1354 because it would complicate the code generator.
1356 Don't do this when nocode_wanted. vtop might come from
1357 !nocode_wanted regions (see 88_codeopt.c) and transforming
1358 it to a register without actually generating code is wrong
1359 as their value might still be used for real. All values
1360 we push under nocode_wanted will eventually be popped
1361 again, so that the VT_CMP/VT_JMP value will be in vtop
1362 when code is unsuppressed again. */
1364 if (vtop
->r
== VT_CMP
&& !nocode_wanted
)
1368 static void vsetc(CType
*type
, int r
, CValue
*vc
)
1370 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
1371 tcc_error("memory full (vstack)");
1376 vtop
->r2
= VT_CONST
;
1381 ST_FUNC
void vswap(void)
1391 /* pop stack value */
1392 ST_FUNC
void vpop(void)
1395 v
= vtop
->r
& VT_VALMASK
;
1396 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1397 /* for x86, we need to pop the FP stack */
1398 if (v
== TREG_ST0
) {
1399 o(0xd8dd); /* fstp %st(0) */
1403 /* need to put correct jump if && or || without test */
1410 /* push constant of type "type" with useless value */
1411 static void vpush(CType
*type
)
1413 vset(type
, VT_CONST
, 0);
1416 /* push arbitrary 64bit constant */
1417 static void vpush64(int ty
, unsigned long long v
)
1424 vsetc(&ctype
, VT_CONST
, &cval
);
1427 /* push integer constant */
1428 ST_FUNC
void vpushi(int v
)
1433 /* push a pointer sized constant */
1434 static void vpushs(addr_t v
)
1436 vpush64(VT_SIZE_T
, v
);
1439 /* push long long constant */
1440 static inline void vpushll(long long v
)
1442 vpush64(VT_LLONG
, v
);
1445 ST_FUNC
void vset(CType
*type
, int r
, int v
)
1449 vsetc(type
, r
, &cval
);
1452 static void vseti(int r
, int v
)
1460 ST_FUNC
void vpushv(SValue
*v
)
1462 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
1463 tcc_error("memory full (vstack)");
1468 static void vdup(void)
1473 /* rotate n first stack elements to the bottom
1474 I1 ... In -> I2 ... In I1 [top is right]
1476 ST_FUNC
void vrotb(int n
)
1483 for(i
=-n
+1;i
!=0;i
++)
1484 vtop
[i
] = vtop
[i
+1];
1488 /* rotate the n elements before entry e towards the top
1489 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1491 ST_FUNC
void vrote(SValue
*e
, int n
)
1498 for(i
= 0;i
< n
- 1; i
++)
1503 /* rotate n first stack elements to the top
1504 I1 ... In -> In I1 ... I(n-1) [top is right]
1506 ST_FUNC
void vrott(int n
)
1511 /* ------------------------------------------------------------------------- */
1512 /* vtop->r = VT_CMP means CPU-flags have been set from comparison or test. */
1514 /* called from generators to set the result from relational ops */
1515 ST_FUNC
void vset_VT_CMP(int op
)
1523 /* called once before asking generators to load VT_CMP to a register */
1524 static void vset_VT_JMP(void)
1526 int op
= vtop
->cmp_op
;
1528 if (vtop
->jtrue
|| vtop
->jfalse
) {
1529 /* we need to jump to 'mov $0,%R' or 'mov $1,%R' */
1530 int inv
= op
& (op
< 2); /* small optimization */
1531 vseti(VT_JMP
+inv
, gvtst(inv
, 0));
1533 /* otherwise convert flags (rsp. 0/1) to register */
1535 if (op
< 2) /* doesn't seem to happen */
1540 /* Set CPU Flags, doesn't yet jump */
1541 static void gvtst_set(int inv
, int t
)
1545 if (vtop
->r
!= VT_CMP
) {
1548 if (vtop
->r
!= VT_CMP
) /* must be VT_CONST then */
1549 vset_VT_CMP(vtop
->c
.i
!= 0);
1552 p
= inv
? &vtop
->jfalse
: &vtop
->jtrue
;
1553 *p
= gjmp_append(*p
, t
);
1556 /* Generate value test
1558 * Generate a test for any value (jump, comparison and integers) */
1559 static int gvtst(int inv
, int t
)
1564 t
= vtop
->jtrue
, u
= vtop
->jfalse
;
1566 x
= u
, u
= t
, t
= x
;
1569 /* jump to the wanted target */
1571 t
= gjmp_cond(op
^ inv
, t
);
1574 /* resolve complementary jumps to here */
1581 /* generate a zero or nozero test */
1582 static void gen_test_zero(int op
)
1584 if (vtop
->r
== VT_CMP
) {
1588 vtop
->jfalse
= vtop
->jtrue
;
1598 /* ------------------------------------------------------------------------- */
1599 /* push a symbol value of TYPE */
1600 ST_FUNC
void vpushsym(CType
*type
, Sym
*sym
)
1604 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
1608 /* Return a static symbol pointing to a section */
1609 ST_FUNC Sym
*get_sym_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
1615 sym
= sym_push(v
, type
, VT_CONST
| VT_SYM
, 0);
1616 sym
->type
.t
|= VT_STATIC
;
1617 put_extern_sym(sym
, sec
, offset
, size
);
1621 /* push a reference to a section offset by adding a dummy symbol */
1622 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
1624 vpushsym(type
, get_sym_ref(type
, sec
, offset
, size
));
1627 /* define a new external reference to a symbol 'v' of type 'u' */
1628 ST_FUNC Sym
*external_global_sym(int v
, CType
*type
)
1634 /* push forward reference */
1635 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
1636 s
->type
.ref
= type
->ref
;
1637 } else if (IS_ASM_SYM(s
)) {
1638 s
->type
.t
= type
->t
| (s
->type
.t
& VT_EXTERN
);
1639 s
->type
.ref
= type
->ref
;
1645 /* create an external reference with no specific type similar to asm labels.
1646 This avoids type conflicts if the symbol is used from C too */
1647 ST_FUNC Sym
*external_helper_sym(int v
)
1649 CType ct
= { VT_ASM_FUNC
, NULL
};
1650 return external_global_sym(v
, &ct
);
1653 /* push a reference to an helper function (such as memmove) */
1654 ST_FUNC
void vpush_helper_func(int v
)
1656 vpushsym(&func_old_type
, external_helper_sym(v
));
1659 /* Merge symbol attributes. */
1660 static void merge_symattr(struct SymAttr
*sa
, struct SymAttr
*sa1
)
1662 if (sa1
->aligned
&& !sa
->aligned
)
1663 sa
->aligned
= sa1
->aligned
;
1664 sa
->packed
|= sa1
->packed
;
1665 sa
->weak
|= sa1
->weak
;
1666 if (sa1
->visibility
!= STV_DEFAULT
) {
1667 int vis
= sa
->visibility
;
1668 if (vis
== STV_DEFAULT
1669 || vis
> sa1
->visibility
)
1670 vis
= sa1
->visibility
;
1671 sa
->visibility
= vis
;
1673 sa
->dllexport
|= sa1
->dllexport
;
1674 sa
->nodecorate
|= sa1
->nodecorate
;
1675 sa
->dllimport
|= sa1
->dllimport
;
1678 /* Merge function attributes. */
1679 static void merge_funcattr(struct FuncAttr
*fa
, struct FuncAttr
*fa1
)
1681 if (fa1
->func_call
&& !fa
->func_call
)
1682 fa
->func_call
= fa1
->func_call
;
1683 if (fa1
->func_type
&& !fa
->func_type
)
1684 fa
->func_type
= fa1
->func_type
;
1685 if (fa1
->func_args
&& !fa
->func_args
)
1686 fa
->func_args
= fa1
->func_args
;
1687 if (fa1
->func_noreturn
)
1688 fa
->func_noreturn
= 1;
1695 /* Merge attributes. */
1696 static void merge_attr(AttributeDef
*ad
, AttributeDef
*ad1
)
1698 merge_symattr(&ad
->a
, &ad1
->a
);
1699 merge_funcattr(&ad
->f
, &ad1
->f
);
1702 ad
->section
= ad1
->section
;
1703 if (ad1
->alias_target
)
1704 ad
->alias_target
= ad1
->alias_target
;
1706 ad
->asm_label
= ad1
->asm_label
;
1708 ad
->attr_mode
= ad1
->attr_mode
;
1711 /* Merge some type attributes. */
1712 static void patch_type(Sym
*sym
, CType
*type
)
1714 if (!(type
->t
& VT_EXTERN
) || IS_ENUM_VAL(sym
->type
.t
)) {
1715 if (!(sym
->type
.t
& VT_EXTERN
))
1716 tcc_error("redefinition of '%s'", get_tok_str(sym
->v
, NULL
));
1717 sym
->type
.t
&= ~VT_EXTERN
;
1720 if (IS_ASM_SYM(sym
)) {
1721 /* stay static if both are static */
1722 sym
->type
.t
= type
->t
& (sym
->type
.t
| ~VT_STATIC
);
1723 sym
->type
.ref
= type
->ref
;
1726 if (!is_compatible_types(&sym
->type
, type
)) {
1727 tcc_error("incompatible types for redefinition of '%s'",
1728 get_tok_str(sym
->v
, NULL
));
1730 } else if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
) {
1731 int static_proto
= sym
->type
.t
& VT_STATIC
;
1732 /* warn if static follows non-static function declaration */
1733 if ((type
->t
& VT_STATIC
) && !static_proto
1734 /* XXX this test for inline shouldn't be here. Until we
1735 implement gnu-inline mode again it silences a warning for
1736 mingw caused by our workarounds. */
1737 && !((type
->t
| sym
->type
.t
) & VT_INLINE
))
1738 tcc_warning("static storage ignored for redefinition of '%s'",
1739 get_tok_str(sym
->v
, NULL
));
1741 /* set 'inline' if both agree or if one has static */
1742 if ((type
->t
| sym
->type
.t
) & VT_INLINE
) {
1743 if (!((type
->t
^ sym
->type
.t
) & VT_INLINE
)
1744 || ((type
->t
| sym
->type
.t
) & VT_STATIC
))
1745 static_proto
|= VT_INLINE
;
1748 if (0 == (type
->t
& VT_EXTERN
)) {
1749 struct FuncAttr f
= sym
->type
.ref
->f
;
1750 /* put complete type, use static from prototype */
1751 sym
->type
.t
= (type
->t
& ~(VT_STATIC
|VT_INLINE
)) | static_proto
;
1752 sym
->type
.ref
= type
->ref
;
1753 merge_funcattr(&sym
->type
.ref
->f
, &f
);
1755 sym
->type
.t
&= ~VT_INLINE
| static_proto
;
1758 if (sym
->type
.ref
->f
.func_type
== FUNC_OLD
1759 && type
->ref
->f
.func_type
!= FUNC_OLD
) {
1760 sym
->type
.ref
= type
->ref
;
1764 if ((sym
->type
.t
& VT_ARRAY
) && type
->ref
->c
>= 0) {
1765 /* set array size if it was omitted in extern declaration */
1766 sym
->type
.ref
->c
= type
->ref
->c
;
1768 if ((type
->t
^ sym
->type
.t
) & VT_STATIC
)
1769 tcc_warning("storage mismatch for redefinition of '%s'",
1770 get_tok_str(sym
->v
, NULL
));
1774 /* Merge some storage attributes. */
1775 static void patch_storage(Sym
*sym
, AttributeDef
*ad
, CType
*type
)
1778 patch_type(sym
, type
);
1780 #ifdef TCC_TARGET_PE
1781 if (sym
->a
.dllimport
!= ad
->a
.dllimport
)
1782 tcc_error("incompatible dll linkage for redefinition of '%s'",
1783 get_tok_str(sym
->v
, NULL
));
1785 merge_symattr(&sym
->a
, &ad
->a
);
1787 sym
->asm_label
= ad
->asm_label
;
1788 update_storage(sym
);
1791 /* copy sym to other stack */
1792 static Sym
*sym_copy(Sym
*s0
, Sym
**ps
)
1795 s
= sym_malloc(), *s
= *s0
;
1796 s
->prev
= *ps
, *ps
= s
;
1797 if (s
->v
< SYM_FIRST_ANOM
) {
1798 ps
= &table_ident
[s
->v
- TOK_IDENT
]->sym_identifier
;
1799 s
->prev_tok
= *ps
, *ps
= s
;
1804 /* copy s->type.ref to stack 'ps' for VT_FUNC and VT_PTR */
1805 static void sym_copy_ref(Sym
*s
, Sym
**ps
)
1807 int bt
= s
->type
.t
& VT_BTYPE
;
1808 if (bt
== VT_FUNC
|| bt
== VT_PTR
|| (bt
== VT_STRUCT
&& s
->sym_scope
)) {
1809 Sym
**sp
= &s
->type
.ref
;
1810 for (s
= *sp
, *sp
= NULL
; s
; s
= s
->next
) {
1811 Sym
*s2
= sym_copy(s
, ps
);
1812 sp
= &(*sp
= s2
)->next
;
1813 sym_copy_ref(s2
, ps
);
1818 /* define a new external reference to a symbol 'v' */
1819 static Sym
*external_sym(int v
, CType
*type
, int r
, AttributeDef
*ad
)
1823 /* look for global symbol */
1825 while (s
&& s
->sym_scope
)
1829 /* push forward reference */
1830 s
= global_identifier_push(v
, type
->t
, 0);
1833 s
->asm_label
= ad
->asm_label
;
1834 s
->type
.ref
= type
->ref
;
1835 /* copy type to the global stack */
1837 sym_copy_ref(s
, &global_stack
);
1839 patch_storage(s
, ad
, type
);
1841 /* push variables on local_stack if any */
1842 if (local_stack
&& (s
->type
.t
& VT_BTYPE
) != VT_FUNC
)
1843 s
= sym_copy(s
, &local_stack
);
1847 /* save registers up to (vtop - n) stack entry */
1848 ST_FUNC
void save_regs(int n
)
1851 for(p
= vstack
, p1
= vtop
- n
; p
<= p1
; p
++)
1855 /* save r to the memory stack, and mark it as being free */
1856 ST_FUNC
void save_reg(int r
)
1858 save_reg_upstack(r
, 0);
1861 /* save r to the memory stack, and mark it as being free,
1862 if seen up to (vtop - n) stack entry */
1863 ST_FUNC
void save_reg_upstack(int r
, int n
)
1865 int l
, size
, align
, bt
;
1868 if ((r
&= VT_VALMASK
) >= VT_CONST
)
1873 for(p
= vstack
, p1
= vtop
- n
; p
<= p1
; p
++) {
1874 if ((p
->r
& VT_VALMASK
) == r
|| p
->r2
== r
) {
1875 /* must save value on stack if not already done */
1877 bt
= p
->type
.t
& VT_BTYPE
;
1880 if ((p
->r
& VT_LVAL
) || bt
== VT_FUNC
)
1883 size
= type_size(&sv
.type
, &align
);
1884 l
= get_temp_local_var(size
,align
);
1885 sv
.r
= VT_LOCAL
| VT_LVAL
;
1887 store(p
->r
& VT_VALMASK
, &sv
);
1888 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1889 /* x86 specific: need to pop fp register ST0 if saved */
1890 if (r
== TREG_ST0
) {
1891 o(0xd8dd); /* fstp %st(0) */
1894 /* special long long case */
1895 if (p
->r2
< VT_CONST
&& USING_TWO_WORDS(bt
)) {
1900 /* mark that stack entry as being saved on the stack */
1901 if (p
->r
& VT_LVAL
) {
1902 /* also clear the bounded flag because the
1903 relocation address of the function was stored in
1905 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
1907 p
->r
= VT_LVAL
| VT_LOCAL
;
1916 #ifdef TCC_TARGET_ARM
1917 /* find a register of class 'rc2' with at most one reference on stack.
1918 * If none, call get_reg(rc) */
1919 ST_FUNC
int get_reg_ex(int rc
, int rc2
)
1924 for(r
=0;r
<NB_REGS
;r
++) {
1925 if (reg_classes
[r
] & rc2
) {
1928 for(p
= vstack
; p
<= vtop
; p
++) {
1929 if ((p
->r
& VT_VALMASK
) == r
||
1941 /* find a free register of class 'rc'. If none, save one register */
1942 ST_FUNC
int get_reg(int rc
)
1947 /* find a free register */
1948 for(r
=0;r
<NB_REGS
;r
++) {
1949 if (reg_classes
[r
] & rc
) {
1952 for(p
=vstack
;p
<=vtop
;p
++) {
1953 if ((p
->r
& VT_VALMASK
) == r
||
1962 /* no register left : free the first one on the stack (VERY
1963 IMPORTANT to start from the bottom to ensure that we don't
1964 spill registers used in gen_opi()) */
1965 for(p
=vstack
;p
<=vtop
;p
++) {
1966 /* look at second register (if long long) */
1968 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
1970 r
= p
->r
& VT_VALMASK
;
1971 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
1977 /* Should never comes here */
1981 /* find a free temporary local variable (return the offset on stack) match the size and align. If none, add new temporary stack variable*/
1982 static int get_temp_local_var(int size
,int align
){
1984 struct temp_local_variable
*temp_var
;
1991 for(i
=0;i
<nb_temp_local_vars
;i
++){
1992 temp_var
=&arr_temp_local_vars
[i
];
1993 if(temp_var
->size
<size
||align
!=temp_var
->align
){
1996 /*check if temp_var is free*/
1998 for(p
=vstack
;p
<=vtop
;p
++) {
2000 if(r
==VT_LOCAL
||r
==VT_LLOCAL
){
2001 if(p
->c
.i
==temp_var
->location
){
2008 found_var
=temp_var
->location
;
2014 loc
= (loc
- size
) & -align
;
2015 if(nb_temp_local_vars
<MAX_TEMP_LOCAL_VARIABLE_NUMBER
){
2016 temp_var
=&arr_temp_local_vars
[i
];
2017 temp_var
->location
=loc
;
2018 temp_var
->size
=size
;
2019 temp_var
->align
=align
;
2020 nb_temp_local_vars
++;
2027 static void clear_temp_local_var_list(){
2028 nb_temp_local_vars
=0;
2031 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
2033 static void move_reg(int r
, int s
, int t
)
2047 /* get address of vtop (vtop MUST BE an lvalue) */
2048 ST_FUNC
void gaddrof(void)
2050 vtop
->r
&= ~VT_LVAL
;
2051 /* tricky: if saved lvalue, then we can go back to lvalue */
2052 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
2053 vtop
->r
= (vtop
->r
& ~VT_VALMASK
) | VT_LOCAL
| VT_LVAL
;
2056 #ifdef CONFIG_TCC_BCHECK
2057 /* generate a bounded pointer addition */
2058 static void gen_bounded_ptr_add(void)
2060 int save
= (vtop
[-1].r
& VT_VALMASK
) == VT_LOCAL
;
2065 vpush_helper_func(TOK___bound_ptr_add
);
2070 /* returned pointer is in REG_IRET */
2071 vtop
->r
= REG_IRET
| VT_BOUNDED
;
2074 /* relocation offset of the bounding function call point */
2075 vtop
->c
.i
= (cur_text_section
->reloc
->data_offset
- sizeof(ElfW_Rel
));
2078 /* patch pointer addition in vtop so that pointer dereferencing is
2080 static void gen_bounded_ptr_deref(void)
2090 size
= type_size(&vtop
->type
, &align
);
2092 case 1: func
= TOK___bound_ptr_indir1
; break;
2093 case 2: func
= TOK___bound_ptr_indir2
; break;
2094 case 4: func
= TOK___bound_ptr_indir4
; break;
2095 case 8: func
= TOK___bound_ptr_indir8
; break;
2096 case 12: func
= TOK___bound_ptr_indir12
; break;
2097 case 16: func
= TOK___bound_ptr_indir16
; break;
2099 /* may happen with struct member access */
2102 sym
= external_helper_sym(func
);
2104 put_extern_sym(sym
, NULL
, 0, 0);
2105 /* patch relocation */
2106 /* XXX: find a better solution ? */
2107 rel
= (ElfW_Rel
*)(cur_text_section
->reloc
->data
+ vtop
->c
.i
);
2108 rel
->r_info
= ELFW(R_INFO
)(sym
->c
, ELFW(R_TYPE
)(rel
->r_info
));
2111 /* generate lvalue bound code */
2112 static void gbound(void)
2116 vtop
->r
&= ~VT_MUSTBOUND
;
2117 /* if lvalue, then use checking code before dereferencing */
2118 if (vtop
->r
& VT_LVAL
) {
2119 /* if not VT_BOUNDED value, then make one */
2120 if (!(vtop
->r
& VT_BOUNDED
)) {
2121 /* must save type because we must set it to int to get pointer */
2123 vtop
->type
.t
= VT_PTR
;
2126 gen_bounded_ptr_add();
2130 /* then check for dereferencing */
2131 gen_bounded_ptr_deref();
2135 /* we need to call __bound_ptr_add before we start to load function
2136 args into registers */
2137 ST_FUNC
void gbound_args(int nb_args
)
2142 for (i
= 1; i
<= nb_args
; ++i
)
2143 if (vtop
[1 - i
].r
& VT_MUSTBOUND
) {
2149 sv
= vtop
- nb_args
;
2150 if (sv
->r
& VT_SYM
) {
2154 #ifndef TCC_TARGET_PE
2155 || v
== TOK_sigsetjmp
2156 || v
== TOK___sigsetjmp
2159 vpush_helper_func(TOK___bound_setjmp
);
2162 func_bound_add_epilog
= 1;
2164 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
2165 if (v
== TOK_alloca
)
2166 func_bound_add_epilog
= 1;
2169 if (v
== TOK_longjmp
) /* undo rename to __longjmp14 */
2170 sv
->sym
->asm_label
= TOK___bound_longjmp
;
2175 /* Add bounds for local symbols from S to E (via ->prev) */
2176 static void add_local_bounds(Sym
*s
, Sym
*e
)
2178 for (; s
!= e
; s
= s
->prev
) {
2179 if (!s
->v
|| (s
->r
& VT_VALMASK
) != VT_LOCAL
)
2181 /* Add arrays/structs/unions because we always take address */
2182 if ((s
->type
.t
& VT_ARRAY
)
2183 || (s
->type
.t
& VT_BTYPE
) == VT_STRUCT
2184 || s
->a
.addrtaken
) {
2185 /* add local bound info */
2186 int align
, size
= type_size(&s
->type
, &align
);
2187 addr_t
*bounds_ptr
= section_ptr_add(lbounds_section
,
2188 2 * sizeof(addr_t
));
2189 bounds_ptr
[0] = s
->c
;
2190 bounds_ptr
[1] = size
;
2196 /* Wrapper around sym_pop, that potentially also registers local bounds. */
2197 static void pop_local_syms(Sym
*b
, int keep
)
2199 #ifdef CONFIG_TCC_BCHECK
2200 if (tcc_state
->do_bounds_check
&& !keep
&& (local_scope
|| !func_var
))
2201 add_local_bounds(local_stack
, b
);
2204 tcc_add_debug_info (tcc_state
, !local_scope
, local_stack
, b
);
2205 sym_pop(&local_stack
, b
, keep
);
2208 static void incr_bf_adr(int o
)
2210 vtop
->type
= char_pointer_type
;
2214 vtop
->type
.t
= VT_BYTE
| VT_UNSIGNED
;
2218 /* single-byte load mode for packed or otherwise unaligned bitfields */
2219 static void load_packed_bf(CType
*type
, int bit_pos
, int bit_size
)
2222 save_reg_upstack(vtop
->r
, 1);
2223 vpush64(type
->t
& VT_BTYPE
, 0); // B X
2224 bits
= 0, o
= bit_pos
>> 3, bit_pos
&= 7;
2233 vpushi(bit_pos
), gen_op(TOK_SHR
), bit_pos
= 0; // X B Y
2235 vpushi((1 << n
) - 1), gen_op('&');
2238 vpushi(bits
), gen_op(TOK_SHL
);
2241 bits
+= n
, bit_size
-= n
, o
= 1;
2244 if (!(type
->t
& VT_UNSIGNED
)) {
2245 n
= ((type
->t
& VT_BTYPE
) == VT_LLONG
? 64 : 32) - bits
;
2246 vpushi(n
), gen_op(TOK_SHL
);
2247 vpushi(n
), gen_op(TOK_SAR
);
2251 /* single-byte store mode for packed or otherwise unaligned bitfields */
2252 static void store_packed_bf(int bit_pos
, int bit_size
)
2254 int bits
, n
, o
, m
, c
;
2255 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2257 save_reg_upstack(vtop
->r
, 1);
2258 bits
= 0, o
= bit_pos
>> 3, bit_pos
&= 7;
2260 incr_bf_adr(o
); // X B
2262 c
? vdup() : gv_dup(); // B V X
2265 vpushi(bits
), gen_op(TOK_SHR
);
2267 vpushi(bit_pos
), gen_op(TOK_SHL
);
2272 m
= ((1 << n
) - 1) << bit_pos
;
2273 vpushi(m
), gen_op('&'); // X B V1
2274 vpushv(vtop
-1); // X B V1 B
2275 vpushi(m
& 0x80 ? ~m
& 0x7f : ~m
);
2276 gen_op('&'); // X B V1 B1
2277 gen_op('|'); // X B V2
2279 vdup(), vtop
[-1] = vtop
[-2]; // X B B V2
2280 vstore(), vpop(); // X B
2281 bits
+= n
, bit_size
-= n
, bit_pos
= 0, o
= 1;
2286 static int adjust_bf(SValue
*sv
, int bit_pos
, int bit_size
)
2289 if (0 == sv
->type
.ref
)
2291 t
= sv
->type
.ref
->auxtype
;
2292 if (t
!= -1 && t
!= VT_STRUCT
) {
2293 sv
->type
.t
= (sv
->type
.t
& ~(VT_BTYPE
| VT_LONG
)) | t
;
2299 /* store vtop a register belonging to class 'rc'. lvalues are
2300 converted to values. Cannot be used if cannot be converted to
2301 register value (such as structures). */
2302 ST_FUNC
int gv(int rc
)
2304 int r
, r2
, r_ok
, r2_ok
, rc2
, bt
;
2305 int bit_pos
, bit_size
, size
, align
;
2307 /* NOTE: get_reg can modify vstack[] */
2308 if (vtop
->type
.t
& VT_BITFIELD
) {
2311 bit_pos
= BIT_POS(vtop
->type
.t
);
2312 bit_size
= BIT_SIZE(vtop
->type
.t
);
2313 /* remove bit field info to avoid loops */
2314 vtop
->type
.t
&= ~VT_STRUCT_MASK
;
2317 type
.t
= vtop
->type
.t
& VT_UNSIGNED
;
2318 if ((vtop
->type
.t
& VT_BTYPE
) == VT_BOOL
)
2319 type
.t
|= VT_UNSIGNED
;
2321 r
= adjust_bf(vtop
, bit_pos
, bit_size
);
2323 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
)
2328 if (r
== VT_STRUCT
) {
2329 load_packed_bf(&type
, bit_pos
, bit_size
);
2331 int bits
= (type
.t
& VT_BTYPE
) == VT_LLONG
? 64 : 32;
2332 /* cast to int to propagate signedness in following ops */
2334 /* generate shifts */
2335 vpushi(bits
- (bit_pos
+ bit_size
));
2337 vpushi(bits
- bit_size
);
2338 /* NOTE: transformed to SHR if unsigned */
2343 if (is_float(vtop
->type
.t
) &&
2344 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2345 /* CPUs usually cannot use float constants, so we store them
2346 generically in data segment */
2347 init_params p
= { rodata_section
};
2348 unsigned long offset
;
2349 size
= type_size(&vtop
->type
, &align
);
2351 size
= 0, align
= 1;
2352 offset
= section_add(p
.sec
, size
, align
);
2353 vpush_ref(&vtop
->type
, p
.sec
, offset
, size
);
2355 init_putv(&p
, &vtop
->type
, offset
);
2358 #ifdef CONFIG_TCC_BCHECK
2359 if (vtop
->r
& VT_MUSTBOUND
)
2363 bt
= vtop
->type
.t
& VT_BTYPE
;
2365 #ifdef TCC_TARGET_RISCV64
2367 if (bt
== VT_LDOUBLE
&& rc
== RC_FLOAT
)
2370 rc2
= RC2_TYPE(bt
, rc
);
2372 /* need to reload if:
2374 - lvalue (need to dereference pointer)
2375 - already a register, but not in the right class */
2376 r
= vtop
->r
& VT_VALMASK
;
2377 r_ok
= !(vtop
->r
& VT_LVAL
) && (r
< VT_CONST
) && (reg_classes
[r
] & rc
);
2378 r2_ok
= !rc2
|| ((vtop
->r2
< VT_CONST
) && (reg_classes
[vtop
->r2
] & rc2
));
2380 if (!r_ok
|| !r2_ok
) {
2384 int load_type
= (bt
== VT_QFLOAT
) ? VT_DOUBLE
: VT_PTRDIFF_T
;
2385 int original_type
= vtop
->type
.t
;
2387 /* two register type load :
2388 expand to two words temporarily */
2389 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2391 unsigned long long ll
= vtop
->c
.i
;
2392 vtop
->c
.i
= ll
; /* first word */
2394 vtop
->r
= r
; /* save register value */
2395 vpushi(ll
>> 32); /* second word */
2396 } else if (vtop
->r
& VT_LVAL
) {
2397 /* We do not want to modifier the long long pointer here.
2398 So we save any other instances down the stack */
2399 save_reg_upstack(vtop
->r
, 1);
2400 /* load from memory */
2401 vtop
->type
.t
= load_type
;
2404 vtop
[-1].r
= r
; /* save register value */
2405 /* increment pointer to get second word */
2406 vtop
->type
.t
= VT_PTRDIFF_T
;
2411 vtop
->type
.t
= load_type
;
2413 /* move registers */
2416 if (r2_ok
&& vtop
->r2
< VT_CONST
)
2419 vtop
[-1].r
= r
; /* save register value */
2420 vtop
->r
= vtop
[-1].r2
;
2422 /* Allocate second register. Here we rely on the fact that
2423 get_reg() tries first to free r2 of an SValue. */
2427 /* write second register */
2430 vtop
->type
.t
= original_type
;
2432 if (vtop
->r
== VT_CMP
)
2434 /* one register type load */
2439 #ifdef TCC_TARGET_C67
2440 /* uses register pairs for doubles */
2441 if (bt
== VT_DOUBLE
)
2448 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2449 ST_FUNC
void gv2(int rc1
, int rc2
)
2451 /* generate more generic register first. But VT_JMP or VT_CMP
2452 values must be generated first in all cases to avoid possible
2454 if (vtop
->r
!= VT_CMP
&& rc1
<= rc2
) {
2459 /* test if reload is needed for first register */
2460 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
2470 /* test if reload is needed for first register */
2471 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
2478 /* expand 64bit on stack in two ints */
2479 ST_FUNC
void lexpand(void)
2482 u
= vtop
->type
.t
& (VT_DEFSIGN
| VT_UNSIGNED
);
2483 v
= vtop
->r
& (VT_VALMASK
| VT_LVAL
);
2484 if (v
== VT_CONST
) {
2487 } else if (v
== (VT_LVAL
|VT_CONST
) || v
== (VT_LVAL
|VT_LOCAL
)) {
2493 vtop
[0].r
= vtop
[-1].r2
;
2494 vtop
[0].r2
= vtop
[-1].r2
= VT_CONST
;
2496 vtop
[0].type
.t
= vtop
[-1].type
.t
= VT_INT
| u
;
2501 /* build a long long from two ints */
2502 static void lbuild(int t
)
2504 gv2(RC_INT
, RC_INT
);
2505 vtop
[-1].r2
= vtop
[0].r
;
2506 vtop
[-1].type
.t
= t
;
2511 /* convert stack entry to register and duplicate its value in another
2513 static void gv_dup(void)
2519 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2520 if (t
& VT_BITFIELD
) {
2530 /* stack: H L L1 H1 */
2540 /* duplicate value */
2550 /* generate CPU independent (unsigned) long long operations */
2551 static void gen_opl(int op
)
2553 int t
, a
, b
, op1
, c
, i
;
2555 unsigned short reg_iret
= REG_IRET
;
2556 unsigned short reg_lret
= REG_IRE2
;
2562 func
= TOK___divdi3
;
2565 func
= TOK___udivdi3
;
2568 func
= TOK___moddi3
;
2571 func
= TOK___umoddi3
;
2578 /* call generic long long function */
2579 vpush_helper_func(func
);
2584 vtop
->r2
= reg_lret
;
2592 //pv("gen_opl A",0,2);
2598 /* stack: L1 H1 L2 H2 */
2603 vtop
[-2] = vtop
[-3];
2606 /* stack: H1 H2 L1 L2 */
2607 //pv("gen_opl B",0,4);
2613 /* stack: H1 H2 L1 L2 ML MH */
2616 /* stack: ML MH H1 H2 L1 L2 */
2620 /* stack: ML MH H1 L2 H2 L1 */
2625 /* stack: ML MH M1 M2 */
2628 } else if (op
== '+' || op
== '-') {
2629 /* XXX: add non carry method too (for MIPS or alpha) */
2635 /* stack: H1 H2 (L1 op L2) */
2638 gen_op(op1
+ 1); /* TOK_xxxC2 */
2641 /* stack: H1 H2 (L1 op L2) */
2644 /* stack: (L1 op L2) H1 H2 */
2646 /* stack: (L1 op L2) (H1 op H2) */
2654 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
2655 t
= vtop
[-1].type
.t
;
2659 /* stack: L H shift */
2661 /* constant: simpler */
2662 /* NOTE: all comments are for SHL. the other cases are
2663 done by swapping words */
2674 if (op
!= TOK_SAR
) {
2707 /* XXX: should provide a faster fallback on x86 ? */
2710 func
= TOK___ashrdi3
;
2713 func
= TOK___lshrdi3
;
2716 func
= TOK___ashldi3
;
2722 /* compare operations */
2728 /* stack: L1 H1 L2 H2 */
2730 vtop
[-1] = vtop
[-2];
2732 /* stack: L1 L2 H1 H2 */
2736 /* when values are equal, we need to compare low words. since
2737 the jump is inverted, we invert the test too. */
2740 else if (op1
== TOK_GT
)
2742 else if (op1
== TOK_ULT
)
2744 else if (op1
== TOK_UGT
)
2754 /* generate non equal test */
2756 vset_VT_CMP(TOK_NE
);
2760 /* compare low. Always unsigned */
2764 else if (op1
== TOK_LE
)
2766 else if (op1
== TOK_GT
)
2768 else if (op1
== TOK_GE
)
2771 #if 0//def TCC_TARGET_I386
2772 if (op
== TOK_NE
) { gsym(b
); break; }
2773 if (op
== TOK_EQ
) { gsym(a
); break; }
2782 static uint64_t gen_opic_sdiv(uint64_t a
, uint64_t b
)
2784 uint64_t x
= (a
>> 63 ? -a
: a
) / (b
>> 63 ? -b
: b
);
2785 return (a
^ b
) >> 63 ? -x
: x
;
2788 static int gen_opic_lt(uint64_t a
, uint64_t b
)
2790 return (a
^ (uint64_t)1 << 63) < (b
^ (uint64_t)1 << 63);
2793 /* handle integer constant optimizations and various machine
2795 static void gen_opic(int op
)
2797 SValue
*v1
= vtop
- 1;
2799 int t1
= v1
->type
.t
& VT_BTYPE
;
2800 int t2
= v2
->type
.t
& VT_BTYPE
;
2801 int c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2802 int c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2803 uint64_t l1
= c1
? v1
->c
.i
: 0;
2804 uint64_t l2
= c2
? v2
->c
.i
: 0;
2805 int shm
= (t1
== VT_LLONG
) ? 63 : 31;
2807 if (t1
!= VT_LLONG
&& (PTR_SIZE
!= 8 || t1
!= VT_PTR
))
2808 l1
= ((uint32_t)l1
|
2809 (v1
->type
.t
& VT_UNSIGNED
? 0 : -(l1
& 0x80000000)));
2810 if (t2
!= VT_LLONG
&& (PTR_SIZE
!= 8 || t2
!= VT_PTR
))
2811 l2
= ((uint32_t)l2
|
2812 (v2
->type
.t
& VT_UNSIGNED
? 0 : -(l2
& 0x80000000)));
2816 case '+': l1
+= l2
; break;
2817 case '-': l1
-= l2
; break;
2818 case '&': l1
&= l2
; break;
2819 case '^': l1
^= l2
; break;
2820 case '|': l1
|= l2
; break;
2821 case '*': l1
*= l2
; break;
2828 /* if division by zero, generate explicit division */
2830 if (const_wanted
&& !(nocode_wanted
& unevalmask
))
2831 tcc_error("division by zero in constant");
2835 default: l1
= gen_opic_sdiv(l1
, l2
); break;
2836 case '%': l1
= l1
- l2
* gen_opic_sdiv(l1
, l2
); break;
2837 case TOK_UDIV
: l1
= l1
/ l2
; break;
2838 case TOK_UMOD
: l1
= l1
% l2
; break;
2841 case TOK_SHL
: l1
<<= (l2
& shm
); break;
2842 case TOK_SHR
: l1
>>= (l2
& shm
); break;
2844 l1
= (l1
>> 63) ? ~(~l1
>> (l2
& shm
)) : l1
>> (l2
& shm
);
2847 case TOK_ULT
: l1
= l1
< l2
; break;
2848 case TOK_UGE
: l1
= l1
>= l2
; break;
2849 case TOK_EQ
: l1
= l1
== l2
; break;
2850 case TOK_NE
: l1
= l1
!= l2
; break;
2851 case TOK_ULE
: l1
= l1
<= l2
; break;
2852 case TOK_UGT
: l1
= l1
> l2
; break;
2853 case TOK_LT
: l1
= gen_opic_lt(l1
, l2
); break;
2854 case TOK_GE
: l1
= !gen_opic_lt(l1
, l2
); break;
2855 case TOK_LE
: l1
= !gen_opic_lt(l2
, l1
); break;
2856 case TOK_GT
: l1
= gen_opic_lt(l2
, l1
); break;
2858 case TOK_LAND
: l1
= l1
&& l2
; break;
2859 case TOK_LOR
: l1
= l1
|| l2
; break;
2863 if (t1
!= VT_LLONG
&& (PTR_SIZE
!= 8 || t1
!= VT_PTR
))
2864 l1
= ((uint32_t)l1
|
2865 (v1
->type
.t
& VT_UNSIGNED
? 0 : -(l1
& 0x80000000)));
2869 /* if commutative ops, put c2 as constant */
2870 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
2871 op
== '|' || op
== '*' || op
== TOK_EQ
|| op
== TOK_NE
)) {
2873 c2
= c1
; //c = c1, c1 = c2, c2 = c;
2874 l2
= l1
; //l = l1, l1 = l2, l2 = l;
2876 if (!const_wanted
&&
2878 (op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
)) ||
2879 (l1
== -1 && op
== TOK_SAR
))) {
2880 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
2882 } else if (!const_wanted
&&
2883 c2
&& ((l2
== 0 && (op
== '&' || op
== '*')) ||
2885 (l2
== -1 || (l2
== 0xFFFFFFFF && t2
!= VT_LLONG
))) ||
2886 (l2
== 1 && (op
== '%' || op
== TOK_UMOD
)))) {
2887 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
2892 } else if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
2895 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
2896 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
2899 (l2
== -1 || (l2
== 0xFFFFFFFF && t2
!= VT_LLONG
))))) {
2900 /* filter out NOP operations like x*1, x-0, x&-1... */
2902 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
2903 /* try to use shifts instead of muls or divs */
2904 if (l2
> 0 && (l2
& (l2
- 1)) == 0) {
2913 else if (op
== TOK_PDIV
)
2919 } else if (c2
&& (op
== '+' || op
== '-') &&
2920 (((vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == (VT_CONST
| VT_SYM
))
2921 || (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
)) == VT_LOCAL
)) {
2922 /* symbol + constant case */
2926 /* The backends can't always deal with addends to symbols
2927 larger than +-1<<31. Don't construct such. */
2934 /* call low level op generator */
2935 if (t1
== VT_LLONG
|| t2
== VT_LLONG
||
2936 (PTR_SIZE
== 8 && (t1
== VT_PTR
|| t2
== VT_PTR
)))
2944 #if defined TCC_TARGET_X86_64 || defined TCC_TARGET_I386
2945 # define gen_negf gen_opf
2946 #elif defined TCC_TARGET_ARM
2947 void gen_negf(int op
)
2949 /* arm will detect 0-x and replace by vneg */
2950 vpushi(0), vswap(), gen_op('-');
2953 /* XXX: implement in gen_opf() for other backends too */
2954 void gen_negf(int op
)
2956 /* In IEEE negate(x) isn't subtract(0,x). Without NaNs it's
2957 subtract(-0, x), but with them it's really a sign flip
2958 operation. We implement this with bit manipulation and have
2959 to do some type reinterpretation for this, which TCC can do
2962 int align
, size
, bt
;
2964 size
= type_size(&vtop
->type
, &align
);
2965 bt
= vtop
->type
.t
& VT_BTYPE
;
2966 save_reg(gv(RC_TYPE(bt
)));
2968 incr_bf_adr(size
- 1);
2970 vpushi(0x80); /* flip sign */
2977 /* generate a floating point operation with constant propagation */
2978 static void gen_opif(int op
)
2982 #if defined _MSC_VER && defined __x86_64__
2983 /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
2993 /* currently, we cannot do computations with forward symbols */
2994 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2995 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2997 if (v1
->type
.t
== VT_FLOAT
) {
3000 } else if (v1
->type
.t
== VT_DOUBLE
) {
3007 /* NOTE: we only do constant propagation if finite number (not
3008 NaN or infinity) (ANSI spec) */
3009 if (!(ieee_finite(f1
) || !ieee_finite(f2
)) && !const_wanted
)
3012 case '+': f1
+= f2
; break;
3013 case '-': f1
-= f2
; break;
3014 case '*': f1
*= f2
; break;
3017 union { float f
; unsigned u
; } x1
, x2
, y
;
3018 /* If not in initializer we need to potentially generate
3019 FP exceptions at runtime, otherwise we want to fold. */
3022 /* the run-time result of 0.0/0.0 on x87, also of other compilers
3023 when used to compile the f1 /= f2 below, would be -nan */
3024 x1
.f
= f1
, x2
.f
= f2
;
3026 y
.u
= 0x7fc00000; /* nan */
3028 y
.u
= 0x7f800000; /* infinity */
3029 y
.u
|= (x1
.u
^ x2
.u
) & 0x80000000; /* set sign */
3038 /* XXX: also handles tests ? */
3044 /* XXX: overflow test ? */
3045 if (v1
->type
.t
== VT_FLOAT
) {
3047 } else if (v1
->type
.t
== VT_DOUBLE
) {
3054 if (op
== TOK_NEG
) {
3062 /* print a type. If 'varstr' is not NULL, then the variable is also
3063 printed in the type */
3065 /* XXX: add array and function pointers */
3066 static void type_to_str(char *buf
, int buf_size
,
3067 CType
*type
, const char *varstr
)
3079 pstrcat(buf
, buf_size
, "extern ");
3081 pstrcat(buf
, buf_size
, "static ");
3083 pstrcat(buf
, buf_size
, "typedef ");
3085 pstrcat(buf
, buf_size
, "inline ");
3087 if (t
& VT_VOLATILE
)
3088 pstrcat(buf
, buf_size
, "volatile ");
3089 if (t
& VT_CONSTANT
)
3090 pstrcat(buf
, buf_size
, "const ");
3092 if (((t
& VT_DEFSIGN
) && bt
== VT_BYTE
)
3093 || ((t
& VT_UNSIGNED
)
3094 && (bt
== VT_SHORT
|| bt
== VT_INT
|| bt
== VT_LLONG
)
3097 pstrcat(buf
, buf_size
, (t
& VT_UNSIGNED
) ? "unsigned " : "signed ");
3099 buf_size
-= strlen(buf
);
3135 tstr
= "long double";
3137 pstrcat(buf
, buf_size
, tstr
);
3144 pstrcat(buf
, buf_size
, tstr
);
3145 v
= type
->ref
->v
& ~SYM_STRUCT
;
3146 if (v
>= SYM_FIRST_ANOM
)
3147 pstrcat(buf
, buf_size
, "<anonymous>");
3149 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
3154 if (varstr
&& '*' == *varstr
) {
3155 pstrcat(buf1
, sizeof(buf1
), "(");
3156 pstrcat(buf1
, sizeof(buf1
), varstr
);
3157 pstrcat(buf1
, sizeof(buf1
), ")");
3159 pstrcat(buf1
, buf_size
, "(");
3161 while (sa
!= NULL
) {
3163 type_to_str(buf2
, sizeof(buf2
), &sa
->type
, NULL
);
3164 pstrcat(buf1
, sizeof(buf1
), buf2
);
3167 pstrcat(buf1
, sizeof(buf1
), ", ");
3169 if (s
->f
.func_type
== FUNC_ELLIPSIS
)
3170 pstrcat(buf1
, sizeof(buf1
), ", ...");
3171 pstrcat(buf1
, sizeof(buf1
), ")");
3172 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
3176 if (t
& (VT_ARRAY
|VT_VLA
)) {
3177 if (varstr
&& '*' == *varstr
)
3178 snprintf(buf1
, sizeof(buf1
), "(%s)[%d]", varstr
, s
->c
);
3180 snprintf(buf1
, sizeof(buf1
), "%s[%d]", varstr
? varstr
: "", s
->c
);
3181 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
3184 pstrcpy(buf1
, sizeof(buf1
), "*");
3185 if (t
& VT_CONSTANT
)
3186 pstrcat(buf1
, buf_size
, "const ");
3187 if (t
& VT_VOLATILE
)
3188 pstrcat(buf1
, buf_size
, "volatile ");
3190 pstrcat(buf1
, sizeof(buf1
), varstr
);
3191 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
3195 pstrcat(buf
, buf_size
, " ");
3196 pstrcat(buf
, buf_size
, varstr
);
3201 static void type_incompatibility_error(CType
* st
, CType
* dt
, const char* fmt
)
3203 char buf1
[256], buf2
[256];
3204 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3205 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3206 tcc_error(fmt
, buf1
, buf2
);
3209 static void type_incompatibility_warning(CType
* st
, CType
* dt
, const char* fmt
)
3211 char buf1
[256], buf2
[256];
3212 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3213 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3214 tcc_warning(fmt
, buf1
, buf2
);
3217 static int pointed_size(CType
*type
)
3220 return type_size(pointed_type(type
), &align
);
3223 static inline int is_null_pointer(SValue
*p
)
3225 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
3227 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& (uint32_t)p
->c
.i
== 0) ||
3228 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.i
== 0) ||
3229 ((p
->type
.t
& VT_BTYPE
) == VT_PTR
&&
3230 (PTR_SIZE
== 4 ? (uint32_t)p
->c
.i
== 0 : p
->c
.i
== 0) &&
3231 ((pointed_type(&p
->type
)->t
& VT_BTYPE
) == VT_VOID
) &&
3232 0 == (pointed_type(&p
->type
)->t
& (VT_CONSTANT
| VT_VOLATILE
))
3236 /* compare function types. OLD functions match any new functions */
3237 static int is_compatible_func(CType
*type1
, CType
*type2
)
3243 if (s1
->f
.func_call
!= s2
->f
.func_call
)
3245 if (s1
->f
.func_type
!= s2
->f
.func_type
3246 && s1
->f
.func_type
!= FUNC_OLD
3247 && s2
->f
.func_type
!= FUNC_OLD
)
3250 if (!is_compatible_unqualified_types(&s1
->type
, &s2
->type
))
3252 if (s1
->f
.func_type
== FUNC_OLD
|| s2
->f
.func_type
== FUNC_OLD
)
3263 /* return true if type1 and type2 are the same. If unqualified is
3264 true, qualifiers on the types are ignored.
3266 static int compare_types(CType
*type1
, CType
*type2
, int unqualified
)
3270 t1
= type1
->t
& VT_TYPE
;
3271 t2
= type2
->t
& VT_TYPE
;
3273 /* strip qualifiers before comparing */
3274 t1
&= ~(VT_CONSTANT
| VT_VOLATILE
);
3275 t2
&= ~(VT_CONSTANT
| VT_VOLATILE
);
3278 /* Default Vs explicit signedness only matters for char */
3279 if ((t1
& VT_BTYPE
) != VT_BYTE
) {
3283 /* XXX: bitfields ? */
3288 && !(type1
->ref
->c
< 0
3289 || type2
->ref
->c
< 0
3290 || type1
->ref
->c
== type2
->ref
->c
))
3293 /* test more complicated cases */
3294 bt1
= t1
& VT_BTYPE
;
3295 if (bt1
== VT_PTR
) {
3296 type1
= pointed_type(type1
);
3297 type2
= pointed_type(type2
);
3298 return is_compatible_types(type1
, type2
);
3299 } else if (bt1
== VT_STRUCT
) {
3300 return (type1
->ref
== type2
->ref
);
3301 } else if (bt1
== VT_FUNC
) {
3302 return is_compatible_func(type1
, type2
);
3303 } else if (IS_ENUM(type1
->t
) && IS_ENUM(type2
->t
)) {
3304 /* If both are enums then they must be the same, if only one is then
3305 t1 and t2 must be equal, which was checked above already. */
3306 return type1
->ref
== type2
->ref
;
3312 /* Check if OP1 and OP2 can be "combined" with operation OP, the combined
3313 type is stored in DEST if non-null (except for pointer plus/minus) . */
3314 static int combine_types(CType
*dest
, SValue
*op1
, SValue
*op2
, int op
)
3316 CType
*type1
= &op1
->type
, *type2
= &op2
->type
, type
;
3317 int t1
= type1
->t
, t2
= type2
->t
, bt1
= t1
& VT_BTYPE
, bt2
= t2
& VT_BTYPE
;
3323 if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
3324 ret
= op
== '?' ? 1 : 0;
3325 /* NOTE: as an extension, we accept void on only one side */
3327 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3328 if (op
== '+') ; /* Handled in caller */
3329 /* http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6 */
3330 /* If one is a null ptr constant the result type is the other. */
3331 else if (is_null_pointer (op2
)) type
= *type1
;
3332 else if (is_null_pointer (op1
)) type
= *type2
;
3333 else if (bt1
!= bt2
) {
3334 /* accept comparison or cond-expr between pointer and integer
3336 if ((op
== '?' || TOK_ISCOND(op
))
3337 && (is_integer_btype(bt1
) || is_integer_btype(bt2
)))
3338 tcc_warning("pointer/integer mismatch in %s",
3339 op
== '?' ? "conditional expression" : "comparison");
3340 else if (op
!= '-' || !is_integer_btype(bt2
))
3342 type
= *(bt1
== VT_PTR
? type1
: type2
);
3344 CType
*pt1
= pointed_type(type1
);
3345 CType
*pt2
= pointed_type(type2
);
3346 int pbt1
= pt1
->t
& VT_BTYPE
;
3347 int pbt2
= pt2
->t
& VT_BTYPE
;
3348 int newquals
, copied
= 0;
3349 if (pbt1
!= VT_VOID
&& pbt2
!= VT_VOID
3350 && !compare_types(pt1
, pt2
, 1/*unqualif*/)) {
3351 if (op
!= '?' && !TOK_ISCOND(op
))
3354 type_incompatibility_warning(type1
, type2
,
3356 ? "pointer type mismatch in conditional expression ('%s' and '%s')"
3357 : "pointer type mismatch in comparison('%s' and '%s')");
3360 /* pointers to void get preferred, otherwise the
3361 pointed to types minus qualifs should be compatible */
3362 type
= *((pbt1
== VT_VOID
) ? type1
: type2
);
3363 /* combine qualifs */
3364 newquals
= ((pt1
->t
| pt2
->t
) & (VT_CONSTANT
| VT_VOLATILE
));
3365 if ((~pointed_type(&type
)->t
& (VT_CONSTANT
| VT_VOLATILE
))
3368 /* copy the pointer target symbol */
3369 type
.ref
= sym_push(SYM_FIELD
, &type
.ref
->type
,
3372 pointed_type(&type
)->t
|= newquals
;
3374 /* pointers to incomplete arrays get converted to
3375 pointers to completed ones if possible */
3376 if (pt1
->t
& VT_ARRAY
3377 && pt2
->t
& VT_ARRAY
3378 && pointed_type(&type
)->ref
->c
< 0
3379 && (pt1
->ref
->c
> 0 || pt2
->ref
->c
> 0))
3382 type
.ref
= sym_push(SYM_FIELD
, &type
.ref
->type
,
3384 pointed_type(&type
)->ref
=
3385 sym_push(SYM_FIELD
, &pointed_type(&type
)->ref
->type
,
3386 0, pointed_type(&type
)->ref
->c
);
3387 pointed_type(&type
)->ref
->c
=
3388 0 < pt1
->ref
->c
? pt1
->ref
->c
: pt2
->ref
->c
;
3394 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
3395 if (op
!= '?' || !compare_types(type1
, type2
, 1))
3398 } else if (is_float(bt1
) || is_float(bt2
)) {
3399 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3400 type
.t
= VT_LDOUBLE
;
3401 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3406 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3407 /* cast to biggest op */
3408 type
.t
= VT_LLONG
| VT_LONG
;
3409 if (bt1
== VT_LLONG
)
3411 if (bt2
== VT_LLONG
)
3413 /* convert to unsigned if it does not fit in a long long */
3414 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3415 (t2
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_LLONG
| VT_UNSIGNED
))
3416 type
.t
|= VT_UNSIGNED
;
3418 /* integer operations */
3419 type
.t
= VT_INT
| (VT_LONG
& (t1
| t2
));
3420 /* convert to unsigned if it does not fit in an integer */
3421 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_INT
| VT_UNSIGNED
) ||
3422 (t2
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_INT
| VT_UNSIGNED
))
3423 type
.t
|= VT_UNSIGNED
;
3430 /* generic gen_op: handles types problems */
3431 ST_FUNC
void gen_op(int op
)
3433 int t1
, t2
, bt1
, bt2
, t
;
3434 CType type1
, combtype
;
3437 t1
= vtop
[-1].type
.t
;
3438 t2
= vtop
[0].type
.t
;
3439 bt1
= t1
& VT_BTYPE
;
3440 bt2
= t2
& VT_BTYPE
;
3442 if (bt1
== VT_FUNC
|| bt2
== VT_FUNC
) {
3443 if (bt2
== VT_FUNC
) {
3444 mk_pointer(&vtop
->type
);
3447 if (bt1
== VT_FUNC
) {
3449 mk_pointer(&vtop
->type
);
3454 } else if (!combine_types(&combtype
, vtop
- 1, vtop
, op
)) {
3455 tcc_error_noabort("invalid operand types for binary operation");
3457 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3458 /* at least one operand is a pointer */
3459 /* relational op: must be both pointers */
3463 /* if both pointers, then it must be the '-' op */
3464 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
3466 tcc_error("cannot use pointers here");
3467 vpush_type_size(pointed_type(&vtop
[-1].type
), &align
);
3470 vtop
->type
.t
= VT_PTRDIFF_T
;
3474 /* exactly one pointer : must be '+' or '-'. */
3475 if (op
!= '-' && op
!= '+')
3476 tcc_error("cannot use pointers here");
3477 /* Put pointer as first operand */
3478 if (bt2
== VT_PTR
) {
3480 t
= t1
, t1
= t2
, t2
= t
;
3483 if ((vtop
[0].type
.t
& VT_BTYPE
) == VT_LLONG
)
3484 /* XXX: truncate here because gen_opl can't handle ptr + long long */
3487 type1
= vtop
[-1].type
;
3488 vpush_type_size(pointed_type(&vtop
[-1].type
), &align
);
3490 #ifdef CONFIG_TCC_BCHECK
3491 if (tcc_state
->do_bounds_check
&& !const_wanted
) {
3492 /* if bounded pointers, we generate a special code to
3499 gen_bounded_ptr_add();
3505 type1
.t
&= ~(VT_ARRAY
|VT_VLA
);
3506 /* put again type if gen_opic() swaped operands */
3510 /* floats can only be used for a few operations */
3511 if (is_float(combtype
.t
)
3512 && op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/'
3514 tcc_error("invalid operands for binary operation");
3515 else if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
) {
3516 t
= bt1
== VT_LLONG
? VT_LLONG
: VT_INT
;
3517 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (t
| VT_UNSIGNED
))
3519 t
|= (VT_LONG
& t1
);
3523 t
= t2
= combtype
.t
;
3524 /* XXX: currently, some unsigned operations are explicit, so
3525 we modify them here */
3526 if (t
& VT_UNSIGNED
) {
3533 else if (op
== TOK_LT
)
3535 else if (op
== TOK_GT
)
3537 else if (op
== TOK_LE
)
3539 else if (op
== TOK_GE
)
3545 /* special case for shifts and long long: we keep the shift as
3547 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3554 if (TOK_ISCOND(op
)) {
3555 /* relational op: the result is an int */
3556 vtop
->type
.t
= VT_INT
;
3561 // Make sure that we have converted to an rvalue:
3562 if (vtop
->r
& VT_LVAL
)
3563 gv(is_float(vtop
->type
.t
& VT_BTYPE
) ? RC_FLOAT
: RC_INT
);
3566 #if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 || defined TCC_TARGET_ARM
3567 #define gen_cvt_itof1 gen_cvt_itof
3569 /* generic itof for unsigned long long case */
3570 static void gen_cvt_itof1(int t
)
3572 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3573 (VT_LLONG
| VT_UNSIGNED
)) {
3576 vpush_helper_func(TOK___floatundisf
);
3577 #if LDOUBLE_SIZE != 8
3578 else if (t
== VT_LDOUBLE
)
3579 vpush_helper_func(TOK___floatundixf
);
3582 vpush_helper_func(TOK___floatundidf
);
3593 #if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
3594 #define gen_cvt_ftoi1 gen_cvt_ftoi
3596 /* generic ftoi for unsigned long long case */
3597 static void gen_cvt_ftoi1(int t
)
3600 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3601 /* not handled natively */
3602 st
= vtop
->type
.t
& VT_BTYPE
;
3604 vpush_helper_func(TOK___fixunssfdi
);
3605 #if LDOUBLE_SIZE != 8
3606 else if (st
== VT_LDOUBLE
)
3607 vpush_helper_func(TOK___fixunsxfdi
);
3610 vpush_helper_func(TOK___fixunsdfdi
);
3621 /* special delayed cast for char/short */
3622 static void force_charshort_cast(void)
3624 int sbt
= BFGET(vtop
->r
, VT_MUSTCAST
) == 2 ? VT_LLONG
: VT_INT
;
3625 int dbt
= vtop
->type
.t
;
3626 vtop
->r
&= ~VT_MUSTCAST
;
3628 gen_cast_s(dbt
== VT_BOOL
? VT_BYTE
|VT_UNSIGNED
: dbt
);
3632 static void gen_cast_s(int t
)
3640 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
3641 static void gen_cast(CType
*type
)
3643 int sbt
, dbt
, sf
, df
, c
;
3644 int dbt_bt
, sbt_bt
, ds
, ss
, bits
, trunc
;
3646 /* special delayed cast for char/short */
3647 if (vtop
->r
& VT_MUSTCAST
)
3648 force_charshort_cast();
3650 /* bitfields first get cast to ints */
3651 if (vtop
->type
.t
& VT_BITFIELD
)
3654 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3655 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
3663 dbt_bt
= dbt
& VT_BTYPE
;
3664 sbt_bt
= sbt
& VT_BTYPE
;
3665 if (dbt_bt
== VT_VOID
)
3667 if (sbt_bt
== VT_VOID
) {
3669 cast_error(&vtop
->type
, type
);
3672 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3673 #if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
3674 c
&= (dbt
!= VT_LDOUBLE
) | !!nocode_wanted
;
3677 /* constant case: we can do it now */
3678 /* XXX: in ISOC, cannot do it if error in convert */
3679 if (sbt
== VT_FLOAT
)
3680 vtop
->c
.ld
= vtop
->c
.f
;
3681 else if (sbt
== VT_DOUBLE
)
3682 vtop
->c
.ld
= vtop
->c
.d
;
3685 if (sbt_bt
== VT_LLONG
) {
3686 if ((sbt
& VT_UNSIGNED
) || !(vtop
->c
.i
>> 63))
3687 vtop
->c
.ld
= vtop
->c
.i
;
3689 vtop
->c
.ld
= -(long double)-vtop
->c
.i
;
3691 if ((sbt
& VT_UNSIGNED
) || !(vtop
->c
.i
>> 31))
3692 vtop
->c
.ld
= (uint32_t)vtop
->c
.i
;
3694 vtop
->c
.ld
= -(long double)-(uint32_t)vtop
->c
.i
;
3697 if (dbt
== VT_FLOAT
)
3698 vtop
->c
.f
= (float)vtop
->c
.ld
;
3699 else if (dbt
== VT_DOUBLE
)
3700 vtop
->c
.d
= (double)vtop
->c
.ld
;
3701 } else if (sf
&& dbt
== VT_BOOL
) {
3702 vtop
->c
.i
= (vtop
->c
.ld
!= 0);
3705 vtop
->c
.i
= vtop
->c
.ld
;
3706 else if (sbt_bt
== VT_LLONG
|| (PTR_SIZE
== 8 && sbt
== VT_PTR
))
3708 else if (sbt
& VT_UNSIGNED
)
3709 vtop
->c
.i
= (uint32_t)vtop
->c
.i
;
3711 vtop
->c
.i
= ((uint32_t)vtop
->c
.i
| -(vtop
->c
.i
& 0x80000000));
3713 if (dbt_bt
== VT_LLONG
|| (PTR_SIZE
== 8 && dbt
== VT_PTR
))
3715 else if (dbt
== VT_BOOL
)
3716 vtop
->c
.i
= (vtop
->c
.i
!= 0);
3718 uint32_t m
= dbt_bt
== VT_BYTE
? 0xff :
3719 dbt_bt
== VT_SHORT
? 0xffff :
3722 if (!(dbt
& VT_UNSIGNED
))
3723 vtop
->c
.i
|= -(vtop
->c
.i
& ((m
>> 1) + 1));
3728 } else if (dbt
== VT_BOOL
3729 && (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
))
3730 == (VT_CONST
| VT_SYM
)) {
3731 /* addresses are considered non-zero (see tcctest.c:sinit23) */
3737 /* cannot generate code for global or static initializers */
3738 if (STATIC_DATA_WANTED
)
3741 /* non constant case: generate code */
3742 if (dbt
== VT_BOOL
) {
3743 gen_test_zero(TOK_NE
);
3749 /* convert from fp to fp */
3752 /* convert int to fp */
3755 /* convert fp to int */
3757 if (dbt_bt
!= VT_LLONG
&& dbt_bt
!= VT_INT
)
3760 goto again
; /* may need char/short cast */
3765 ds
= btype_size(dbt_bt
);
3766 ss
= btype_size(sbt_bt
);
3767 if (ds
== 0 || ss
== 0)
3770 if (IS_ENUM(type
->t
) && type
->ref
->c
< 0)
3771 tcc_error("cast to incomplete type");
3773 /* same size and no sign conversion needed */
3774 if (ds
== ss
&& ds
>= 4)
3776 if (dbt_bt
== VT_PTR
|| sbt_bt
== VT_PTR
) {
3777 tcc_warning("cast between pointer and integer of different size");
3778 if (sbt_bt
== VT_PTR
) {
3779 /* put integer type to allow logical operations below */
3780 vtop
->type
.t
= (PTR_SIZE
== 8 ? VT_LLONG
: VT_INT
);
3784 /* processor allows { int a = 0, b = *(char*)&a; }
3785 That means that if we cast to less width, we can just
3786 change the type and read it still later. */
3787 #define ALLOW_SUBTYPE_ACCESS 1
3789 if (ALLOW_SUBTYPE_ACCESS
&& (vtop
->r
& VT_LVAL
)) {
3790 /* value still in memory */
3794 if (ds
<= 4 && !(dbt
== (VT_SHORT
| VT_UNSIGNED
) && sbt
== VT_BYTE
)) {
3796 goto done
; /* no 64bit envolved */
3804 /* generate high word */
3805 if (sbt
& VT_UNSIGNED
) {
3814 } else if (ss
== 8) {
3815 /* from long long: just take low order word */
3823 /* need to convert from 32bit to 64bit */
3824 if (sbt
& VT_UNSIGNED
) {
3825 #if defined(TCC_TARGET_RISCV64)
3826 /* RISC-V keeps 32bit vals in registers sign-extended.
3827 So here we need a zero-extension. */
3836 ss
= ds
, ds
= 4, dbt
= sbt
;
3837 } else if (ss
== 8) {
3838 /* RISC-V keeps 32bit vals in registers sign-extended.
3839 So here we need a sign-extension for signed types and
3840 zero-extension. for unsigned types. */
3841 #if !defined(TCC_TARGET_RISCV64)
3842 trunc
= 32; /* zero upper 32 bits for non RISC-V targets */
3851 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM64
3857 bits
= (ss
- ds
) * 8;
3858 /* for unsigned, gen_op will convert SAR to SHR */
3859 vtop
->type
.t
= (ss
== 8 ? VT_LLONG
: VT_INT
) | (dbt
& VT_UNSIGNED
);
3862 vpushi(bits
- trunc
);
3869 vtop
->type
.t
&= ~ ( VT_CONSTANT
| VT_VOLATILE
| VT_ARRAY
);
3872 /* return type size as known at compile time. Put alignment at 'a' */
3873 ST_FUNC
int type_size(CType
*type
, int *a
)
3878 bt
= type
->t
& VT_BTYPE
;
3879 if (bt
== VT_STRUCT
) {
3884 } else if (bt
== VT_PTR
) {
3885 if (type
->t
& VT_ARRAY
) {
3889 ts
= type_size(&s
->type
, a
);
3891 if (ts
< 0 && s
->c
< 0)
3899 } else if (IS_ENUM(type
->t
) && type
->ref
->c
< 0) {
3900 return -1; /* incomplete enum */
3901 } else if (bt
== VT_LDOUBLE
) {
3903 return LDOUBLE_SIZE
;
3904 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3905 #ifdef TCC_TARGET_I386
3906 #ifdef TCC_TARGET_PE
3911 #elif defined(TCC_TARGET_ARM)
3921 } else if (bt
== VT_INT
|| bt
== VT_FLOAT
) {
3924 } else if (bt
== VT_SHORT
) {
3927 } else if (bt
== VT_QLONG
|| bt
== VT_QFLOAT
) {
3931 /* char, void, function, _Bool */
3937 /* push type size as known at runtime time on top of value stack. Put
3939 static void vpush_type_size(CType
*type
, int *a
)
3941 if (type
->t
& VT_VLA
) {
3942 type_size(&type
->ref
->type
, a
);
3943 vset(&int_type
, VT_LOCAL
|VT_LVAL
, type
->ref
->c
);
3945 int size
= type_size(type
, a
);
3947 tcc_error("unknown type size");
3952 /* return the pointed type of t */
3953 static inline CType
*pointed_type(CType
*type
)
3955 return &type
->ref
->type
;
3958 /* modify type so that its it is a pointer to type. */
3959 ST_FUNC
void mk_pointer(CType
*type
)
3962 s
= sym_push(SYM_FIELD
, type
, 0, -1);
3963 type
->t
= VT_PTR
| (type
->t
& VT_STORAGE
);
3967 /* return true if type1 and type2 are exactly the same (including
3970 static int is_compatible_types(CType
*type1
, CType
*type2
)
3972 return compare_types(type1
,type2
,0);
3975 /* return true if type1 and type2 are the same (ignoring qualifiers).
3977 static int is_compatible_unqualified_types(CType
*type1
, CType
*type2
)
3979 return compare_types(type1
,type2
,1);
3982 static void cast_error(CType
*st
, CType
*dt
)
3984 type_incompatibility_error(st
, dt
, "cannot convert '%s' to '%s'");
3987 /* verify type compatibility to store vtop in 'dt' type */
3988 static void verify_assign_cast(CType
*dt
)
3990 CType
*st
, *type1
, *type2
;
3991 int dbt
, sbt
, qualwarn
, lvl
;
3993 st
= &vtop
->type
; /* source type */
3994 dbt
= dt
->t
& VT_BTYPE
;
3995 sbt
= st
->t
& VT_BTYPE
;
3996 if (dt
->t
& VT_CONSTANT
)
3997 tcc_warning("assignment of read-only location");
4001 tcc_error("assignment to void expression");
4004 /* special cases for pointers */
4005 /* '0' can also be a pointer */
4006 if (is_null_pointer(vtop
))
4008 /* accept implicit pointer to integer cast with warning */
4009 if (is_integer_btype(sbt
)) {
4010 tcc_warning("assignment makes pointer from integer without a cast");
4013 type1
= pointed_type(dt
);
4015 type2
= pointed_type(st
);
4016 else if (sbt
== VT_FUNC
)
4017 type2
= st
; /* a function is implicitly a function pointer */
4020 if (is_compatible_types(type1
, type2
))
4022 for (qualwarn
= lvl
= 0;; ++lvl
) {
4023 if (((type2
->t
& VT_CONSTANT
) && !(type1
->t
& VT_CONSTANT
)) ||
4024 ((type2
->t
& VT_VOLATILE
) && !(type1
->t
& VT_VOLATILE
)))
4026 dbt
= type1
->t
& (VT_BTYPE
|VT_LONG
);
4027 sbt
= type2
->t
& (VT_BTYPE
|VT_LONG
);
4028 if (dbt
!= VT_PTR
|| sbt
!= VT_PTR
)
4030 type1
= pointed_type(type1
);
4031 type2
= pointed_type(type2
);
4033 if (!is_compatible_unqualified_types(type1
, type2
)) {
4034 if ((dbt
== VT_VOID
|| sbt
== VT_VOID
) && lvl
== 0) {
4035 /* void * can match anything */
4036 } else if (dbt
== sbt
4037 && is_integer_btype(sbt
& VT_BTYPE
)
4038 && IS_ENUM(type1
->t
) + IS_ENUM(type2
->t
)
4039 + !!((type1
->t
^ type2
->t
) & VT_UNSIGNED
) < 2) {
4040 /* Like GCC don't warn by default for merely changes
4041 in pointer target signedness. Do warn for different
4042 base types, though, in particular for unsigned enums
4043 and signed int targets. */
4045 tcc_warning("assignment from incompatible pointer type");
4050 tcc_warning_c(warn_discarded_qualifiers
)("assignment discards qualifiers from pointer target type");
4056 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
4057 tcc_warning("assignment makes integer from pointer without a cast");
4058 } else if (sbt
== VT_STRUCT
) {
4059 goto case_VT_STRUCT
;
4061 /* XXX: more tests */
4065 if (!is_compatible_unqualified_types(dt
, st
)) {
4073 static void gen_assign_cast(CType
*dt
)
4075 verify_assign_cast(dt
);
4079 /* store vtop in lvalue pushed on stack */
4080 ST_FUNC
void vstore(void)
4082 int sbt
, dbt
, ft
, r
, size
, align
, bit_size
, bit_pos
, delayed_cast
;
4084 ft
= vtop
[-1].type
.t
;
4085 sbt
= vtop
->type
.t
& VT_BTYPE
;
4086 dbt
= ft
& VT_BTYPE
;
4088 verify_assign_cast(&vtop
[-1].type
);
4090 if (sbt
== VT_STRUCT
) {
4091 /* if structure, only generate pointer */
4092 /* structure assignment : generate memcpy */
4093 /* XXX: optimize if small size */
4094 size
= type_size(&vtop
->type
, &align
);
4098 #ifdef CONFIG_TCC_BCHECK
4099 if (vtop
->r
& VT_MUSTBOUND
)
4100 gbound(); /* check would be wrong after gaddrof() */
4102 vtop
->type
.t
= VT_PTR
;
4105 /* address of memcpy() */
4108 vpush_helper_func(TOK_memmove8
);
4109 else if(!(align
& 3))
4110 vpush_helper_func(TOK_memmove4
);
4113 /* Use memmove, rather than memcpy, as dest and src may be same: */
4114 vpush_helper_func(TOK_memmove
);
4119 #ifdef CONFIG_TCC_BCHECK
4120 if (vtop
->r
& VT_MUSTBOUND
)
4123 vtop
->type
.t
= VT_PTR
;
4128 /* leave source on stack */
4130 } else if (ft
& VT_BITFIELD
) {
4131 /* bitfield store handling */
4133 /* save lvalue as expression result (example: s.b = s.a = n;) */
4134 vdup(), vtop
[-1] = vtop
[-2];
4136 bit_pos
= BIT_POS(ft
);
4137 bit_size
= BIT_SIZE(ft
);
4138 /* remove bit field info to avoid loops */
4139 vtop
[-1].type
.t
= ft
& ~VT_STRUCT_MASK
;
4141 if (dbt
== VT_BOOL
) {
4142 gen_cast(&vtop
[-1].type
);
4143 vtop
[-1].type
.t
= (vtop
[-1].type
.t
& ~VT_BTYPE
) | (VT_BYTE
| VT_UNSIGNED
);
4145 r
= adjust_bf(vtop
- 1, bit_pos
, bit_size
);
4146 if (dbt
!= VT_BOOL
) {
4147 gen_cast(&vtop
[-1].type
);
4148 dbt
= vtop
[-1].type
.t
& VT_BTYPE
;
4150 if (r
== VT_STRUCT
) {
4151 store_packed_bf(bit_pos
, bit_size
);
4153 unsigned long long mask
= (1ULL << bit_size
) - 1;
4154 if (dbt
!= VT_BOOL
) {
4156 if (dbt
== VT_LLONG
)
4159 vpushi((unsigned)mask
);
4166 /* duplicate destination */
4169 /* load destination, mask and or with source */
4170 if (dbt
== VT_LLONG
)
4171 vpushll(~(mask
<< bit_pos
));
4173 vpushi(~((unsigned)mask
<< bit_pos
));
4178 /* ... and discard */
4181 } else if (dbt
== VT_VOID
) {
4184 /* optimize char/short casts */
4186 if ((dbt
== VT_BYTE
|| dbt
== VT_SHORT
)
4187 && is_integer_btype(sbt
)
4189 if ((vtop
->r
& VT_MUSTCAST
)
4190 && btype_size(dbt
) > btype_size(sbt
)
4192 force_charshort_cast();
4195 gen_cast(&vtop
[-1].type
);
4198 #ifdef CONFIG_TCC_BCHECK
4199 /* bound check case */
4200 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4206 gv(RC_TYPE(dbt
)); /* generate value */
4209 vtop
->r
|= BFVAL(VT_MUSTCAST
, (sbt
== VT_LLONG
) + 1);
4210 //tcc_warning("deley cast %x -> %x", sbt, dbt);
4211 vtop
->type
.t
= ft
& VT_TYPE
;
4214 /* if lvalue was saved on stack, must read it */
4215 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4217 r
= get_reg(RC_INT
);
4218 sv
.type
.t
= VT_PTRDIFF_T
;
4219 sv
.r
= VT_LOCAL
| VT_LVAL
;
4220 sv
.c
.i
= vtop
[-1].c
.i
;
4222 vtop
[-1].r
= r
| VT_LVAL
;
4225 r
= vtop
->r
& VT_VALMASK
;
4226 /* two word case handling :
4227 store second register at word + 4 (or +8 for x86-64) */
4228 if (USING_TWO_WORDS(dbt
)) {
4229 int load_type
= (dbt
== VT_QFLOAT
) ? VT_DOUBLE
: VT_PTRDIFF_T
;
4230 vtop
[-1].type
.t
= load_type
;
4233 /* convert to int to increment easily */
4234 vtop
->type
.t
= VT_PTRDIFF_T
;
4240 vtop
[-1].type
.t
= load_type
;
4241 /* XXX: it works because r2 is spilled last ! */
4242 store(vtop
->r2
, vtop
- 1);
4248 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4252 /* post defines POST/PRE add. c is the token ++ or -- */
4253 ST_FUNC
void inc(int post
, int c
)
4256 vdup(); /* save lvalue */
4258 gv_dup(); /* duplicate value */
4263 vpushi(c
- TOK_MID
);
4265 vstore(); /* store value */
4267 vpop(); /* if post op, return saved value */
4270 ST_FUNC
void parse_mult_str (CString
*astr
, const char *msg
)
4272 /* read the string */
4276 while (tok
== TOK_STR
) {
4277 /* XXX: add \0 handling too ? */
4278 cstr_cat(astr
, tokc
.str
.data
, -1);
4281 cstr_ccat(astr
, '\0');
4284 /* If I is >= 1 and a power of two, returns log2(i)+1.
4285 If I is 0 returns 0. */
4286 ST_FUNC
int exact_log2p1(int i
)
4291 for (ret
= 1; i
>= 1 << 8; ret
+= 8)
4302 /* Parse __attribute__((...)) GNUC extension. */
4303 static void parse_attribute(AttributeDef
*ad
)
4309 if (tok
!= TOK_ATTRIBUTE1
&& tok
!= TOK_ATTRIBUTE2
)
4314 while (tok
!= ')') {
4315 if (tok
< TOK_IDENT
)
4316 expect("attribute name");
4328 tcc_warning_c(warn_implicit_function_declaration
)(
4329 "implicit declaration of function '%s'", get_tok_str(tok
, &tokc
));
4330 s
= external_global_sym(tok
, &func_old_type
);
4331 } else if ((s
->type
.t
& VT_BTYPE
) != VT_FUNC
)
4332 tcc_error("'%s' is not declared as function", get_tok_str(tok
, &tokc
));
4333 ad
->cleanup_func
= s
;
4338 case TOK_CONSTRUCTOR1
:
4339 case TOK_CONSTRUCTOR2
:
4340 ad
->f
.func_ctor
= 1;
4342 case TOK_DESTRUCTOR1
:
4343 case TOK_DESTRUCTOR2
:
4344 ad
->f
.func_dtor
= 1;
4346 case TOK_ALWAYS_INLINE1
:
4347 case TOK_ALWAYS_INLINE2
:
4348 ad
->f
.func_alwinl
= 1;
4353 parse_mult_str(&astr
, "section name");
4354 ad
->section
= find_section(tcc_state
, (char *)astr
.data
);
4361 parse_mult_str(&astr
, "alias(\"target\")");
4362 ad
->alias_target
= /* save string as token, for later */
4363 tok_alloc((char*)astr
.data
, astr
.size
-1)->tok
;
4367 case TOK_VISIBILITY1
:
4368 case TOK_VISIBILITY2
:
4370 parse_mult_str(&astr
,
4371 "visibility(\"default|hidden|internal|protected\")");
4372 if (!strcmp (astr
.data
, "default"))
4373 ad
->a
.visibility
= STV_DEFAULT
;
4374 else if (!strcmp (astr
.data
, "hidden"))
4375 ad
->a
.visibility
= STV_HIDDEN
;
4376 else if (!strcmp (astr
.data
, "internal"))
4377 ad
->a
.visibility
= STV_INTERNAL
;
4378 else if (!strcmp (astr
.data
, "protected"))
4379 ad
->a
.visibility
= STV_PROTECTED
;
4381 expect("visibility(\"default|hidden|internal|protected\")");
4390 if (n
<= 0 || (n
& (n
- 1)) != 0)
4391 tcc_error("alignment must be a positive power of two");
4396 ad
->a
.aligned
= exact_log2p1(n
);
4397 if (n
!= 1 << (ad
->a
.aligned
- 1))
4398 tcc_error("alignment of %d is larger than implemented", n
);
4410 /* currently, no need to handle it because tcc does not
4411 track unused objects */
4415 ad
->f
.func_noreturn
= 1;
4420 ad
->f
.func_call
= FUNC_CDECL
;
4425 ad
->f
.func_call
= FUNC_STDCALL
;
4427 #ifdef TCC_TARGET_I386
4437 ad
->f
.func_call
= FUNC_FASTCALL1
+ n
- 1;
4443 ad
->f
.func_call
= FUNC_FASTCALLW
;
4450 ad
->attr_mode
= VT_LLONG
+ 1;
4453 ad
->attr_mode
= VT_BYTE
+ 1;
4456 ad
->attr_mode
= VT_SHORT
+ 1;
4460 ad
->attr_mode
= VT_INT
+ 1;
4463 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok
, NULL
));
4470 ad
->a
.dllexport
= 1;
4472 case TOK_NODECORATE
:
4473 ad
->a
.nodecorate
= 1;
4476 ad
->a
.dllimport
= 1;
4479 tcc_warning_c(warn_unsupported
)("'%s' attribute ignored", get_tok_str(t
, NULL
));
4480 /* skip parameters */
4482 int parenthesis
= 0;
4486 else if (tok
== ')')
4489 } while (parenthesis
&& tok
!= -1);
4502 static Sym
* find_field (CType
*type
, int v
, int *cumofs
)
4506 while ((s
= s
->next
) != NULL
) {
4507 if ((s
->v
& SYM_FIELD
) &&
4508 (s
->type
.t
& VT_BTYPE
) == VT_STRUCT
&&
4509 (s
->v
& ~SYM_FIELD
) >= SYM_FIRST_ANOM
) {
4510 Sym
*ret
= find_field (&s
->type
, v
, cumofs
);
4522 static void check_fields (CType
*type
, int check
)
4526 while ((s
= s
->next
) != NULL
) {
4527 int v
= s
->v
& ~SYM_FIELD
;
4528 if (v
< SYM_FIRST_ANOM
) {
4529 TokenSym
*ts
= table_ident
[v
- TOK_IDENT
];
4530 if (check
&& (ts
->tok
& SYM_FIELD
))
4531 tcc_error("duplicate member '%s'", get_tok_str(v
, NULL
));
4532 ts
->tok
^= SYM_FIELD
;
4533 } else if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
)
4534 check_fields (&s
->type
, check
);
4538 static void struct_layout(CType
*type
, AttributeDef
*ad
)
4540 int size
, align
, maxalign
, offset
, c
, bit_pos
, bit_size
;
4541 int packed
, a
, bt
, prevbt
, prev_bit_size
;
4542 int pcc
= !tcc_state
->ms_bitfields
;
4543 int pragma_pack
= *tcc_state
->pack_stack_ptr
;
4550 prevbt
= VT_STRUCT
; /* make it never match */
4555 for (f
= type
->ref
->next
; f
; f
= f
->next
) {
4556 if (f
->type
.t
& VT_BITFIELD
)
4557 bit_size
= BIT_SIZE(f
->type
.t
);
4560 size
= type_size(&f
->type
, &align
);
4561 a
= f
->a
.aligned
? 1 << (f
->a
.aligned
- 1) : 0;
4564 if (pcc
&& bit_size
== 0) {
4565 /* in pcc mode, packing does not affect zero-width bitfields */
4568 /* in pcc mode, attribute packed overrides if set. */
4569 if (pcc
&& (f
->a
.packed
|| ad
->a
.packed
))
4572 /* pragma pack overrides align if lesser and packs bitfields always */
4575 if (pragma_pack
< align
)
4576 align
= pragma_pack
;
4577 /* in pcc mode pragma pack also overrides individual align */
4578 if (pcc
&& pragma_pack
< a
)
4582 /* some individual align was specified */
4586 if (type
->ref
->type
.t
== VT_UNION
) {
4587 if (pcc
&& bit_size
>= 0)
4588 size
= (bit_size
+ 7) >> 3;
4593 } else if (bit_size
< 0) {
4595 c
+= (bit_pos
+ 7) >> 3;
4596 c
= (c
+ align
- 1) & -align
;
4605 /* A bit-field. Layout is more complicated. There are two
4606 options: PCC (GCC) compatible and MS compatible */
4608 /* In PCC layout a bit-field is placed adjacent to the
4609 preceding bit-fields, except if:
4611 - an individual alignment was given
4612 - it would overflow its base type container and
4613 there is no packing */
4614 if (bit_size
== 0) {
4616 c
= (c
+ ((bit_pos
+ 7) >> 3) + align
- 1) & -align
;
4618 } else if (f
->a
.aligned
) {
4620 } else if (!packed
) {
4622 int ofs
= ((c
* 8 + bit_pos
) % a8
+ bit_size
+ a8
- 1) / a8
;
4623 if (ofs
> size
/ align
)
4627 /* in pcc mode, long long bitfields have type int if they fit */
4628 if (size
== 8 && bit_size
<= 32)
4629 f
->type
.t
= (f
->type
.t
& ~VT_BTYPE
) | VT_INT
, size
= 4;
4631 while (bit_pos
>= align
* 8)
4632 c
+= align
, bit_pos
-= align
* 8;
4635 /* In PCC layout named bit-fields influence the alignment
4636 of the containing struct using the base types alignment,
4637 except for packed fields (which here have correct align). */
4638 if (f
->v
& SYM_FIRST_ANOM
4639 // && bit_size // ??? gcc on ARM/rpi does that
4644 bt
= f
->type
.t
& VT_BTYPE
;
4645 if ((bit_pos
+ bit_size
> size
* 8)
4646 || (bit_size
> 0) == (bt
!= prevbt
)
4648 c
= (c
+ align
- 1) & -align
;
4651 /* In MS bitfield mode a bit-field run always uses
4652 at least as many bits as the underlying type.
4653 To start a new run it's also required that this
4654 or the last bit-field had non-zero width. */
4655 if (bit_size
|| prev_bit_size
)
4658 /* In MS layout the records alignment is normally
4659 influenced by the field, except for a zero-width
4660 field at the start of a run (but by further zero-width
4661 fields it is again). */
4662 if (bit_size
== 0 && prevbt
!= bt
)
4665 prev_bit_size
= bit_size
;
4668 f
->type
.t
= (f
->type
.t
& ~(0x3f << VT_STRUCT_SHIFT
))
4669 | (bit_pos
<< VT_STRUCT_SHIFT
);
4670 bit_pos
+= bit_size
;
4672 if (align
> maxalign
)
4676 printf("set field %s offset %-2d size %-2d align %-2d",
4677 get_tok_str(f
->v
& ~SYM_FIELD
, NULL
), offset
, size
, align
);
4678 if (f
->type
.t
& VT_BITFIELD
) {
4679 printf(" pos %-2d bits %-2d",
4692 c
+= (bit_pos
+ 7) >> 3;
4694 /* store size and alignment */
4695 a
= bt
= ad
->a
.aligned
? 1 << (ad
->a
.aligned
- 1) : 1;
4699 if (pragma_pack
&& pragma_pack
< maxalign
&& 0 == pcc
) {
4700 /* can happen if individual align for some member was given. In
4701 this case MSVC ignores maxalign when aligning the size */
4706 c
= (c
+ a
- 1) & -a
;
4710 printf("struct size %-2d align %-2d\n\n", c
, a
), fflush(stdout
);
4713 /* check whether we can access bitfields by their type */
4714 for (f
= type
->ref
->next
; f
; f
= f
->next
) {
4718 if (0 == (f
->type
.t
& VT_BITFIELD
))
4722 bit_size
= BIT_SIZE(f
->type
.t
);
4725 bit_pos
= BIT_POS(f
->type
.t
);
4726 size
= type_size(&f
->type
, &align
);
4728 if (bit_pos
+ bit_size
<= size
* 8 && f
->c
+ size
<= c
4729 #ifdef TCC_TARGET_ARM
4730 && !(f
->c
& (align
- 1))
4735 /* try to access the field using a different type */
4736 c0
= -1, s
= align
= 1;
4739 px
= f
->c
* 8 + bit_pos
;
4740 cx
= (px
>> 3) & -align
;
4741 px
= px
- (cx
<< 3);
4744 s
= (px
+ bit_size
+ 7) >> 3;
4754 s
= type_size(&t
, &align
);
4758 if (px
+ bit_size
<= s
* 8 && cx
+ s
<= c
4759 #ifdef TCC_TARGET_ARM
4760 && !(cx
& (align
- 1))
4763 /* update offset and bit position */
4766 f
->type
.t
= (f
->type
.t
& ~(0x3f << VT_STRUCT_SHIFT
))
4767 | (bit_pos
<< VT_STRUCT_SHIFT
);
4771 printf("FIX field %s offset %-2d size %-2d align %-2d "
4772 "pos %-2d bits %-2d\n",
4773 get_tok_str(f
->v
& ~SYM_FIELD
, NULL
),
4774 cx
, s
, align
, px
, bit_size
);
4777 /* fall back to load/store single-byte wise */
4778 f
->auxtype
= VT_STRUCT
;
4780 printf("FIX field %s : load byte-wise\n",
4781 get_tok_str(f
->v
& ~SYM_FIELD
, NULL
));
4787 /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
4788 static void struct_decl(CType
*type
, int u
)
4790 int v
, c
, size
, align
, flexible
;
4791 int bit_size
, bsize
, bt
;
4793 AttributeDef ad
, ad1
;
4796 memset(&ad
, 0, sizeof ad
);
4798 parse_attribute(&ad
);
4802 /* struct already defined ? return it */
4804 expect("struct/union/enum name");
4806 if (s
&& (s
->sym_scope
== local_scope
|| tok
!= '{')) {
4809 if (u
== VT_ENUM
&& IS_ENUM(s
->type
.t
))
4811 tcc_error("redefinition of '%s'", get_tok_str(v
, NULL
));
4816 /* Record the original enum/struct/union token. */
4817 type1
.t
= u
== VT_ENUM
? u
| VT_INT
| VT_UNSIGNED
: u
;
4819 /* we put an undefined size for struct/union */
4820 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
4821 s
->r
= 0; /* default alignment is zero as gcc */
4823 type
->t
= s
->type
.t
;
4829 tcc_error("struct/union/enum already defined");
4831 /* cannot be empty */
4832 /* non empty enums are not allowed */
4835 long long ll
= 0, pl
= 0, nl
= 0;
4838 /* enum symbols have static storage */
4839 t
.t
= VT_INT
|VT_STATIC
|VT_ENUM_VAL
;
4843 expect("identifier");
4845 if (ss
&& !local_stack
)
4846 tcc_error("redefinition of enumerator '%s'",
4847 get_tok_str(v
, NULL
));
4851 ll
= expr_const64();
4853 ss
= sym_push(v
, &t
, VT_CONST
, 0);
4855 *ps
= ss
, ps
= &ss
->next
;
4864 /* NOTE: we accept a trailing comma */
4869 /* set integral type of the enum */
4872 if (pl
!= (unsigned)pl
)
4873 t
.t
= (LONG_SIZE
==8 ? VT_LLONG
|VT_LONG
: VT_LLONG
);
4875 } else if (pl
!= (int)pl
|| nl
!= (int)nl
)
4876 t
.t
= (LONG_SIZE
==8 ? VT_LLONG
|VT_LONG
: VT_LLONG
);
4877 s
->type
.t
= type
->t
= t
.t
| VT_ENUM
;
4879 /* set type for enum members */
4880 for (ss
= s
->next
; ss
; ss
= ss
->next
) {
4882 if (ll
== (int)ll
) /* default is int if it fits */
4884 if (t
.t
& VT_UNSIGNED
) {
4885 ss
->type
.t
|= VT_UNSIGNED
;
4886 if (ll
== (unsigned)ll
)
4889 ss
->type
.t
= (ss
->type
.t
& ~VT_BTYPE
)
4890 | (LONG_SIZE
==8 ? VT_LLONG
|VT_LONG
: VT_LLONG
);
4895 while (tok
!= '}') {
4896 if (!parse_btype(&btype
, &ad1
)) {
4902 tcc_error("flexible array member '%s' not at the end of struct",
4903 get_tok_str(v
, NULL
));
4909 type_decl(&type1
, &ad1
, &v
, TYPE_DIRECT
);
4911 if ((type1
.t
& VT_BTYPE
) != VT_STRUCT
)
4912 expect("identifier");
4914 int v
= btype
.ref
->v
;
4915 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
4916 if (tcc_state
->ms_extensions
== 0)
4917 expect("identifier");
4921 if (type_size(&type1
, &align
) < 0) {
4922 if ((u
== VT_STRUCT
) && (type1
.t
& VT_ARRAY
) && c
)
4925 tcc_error("field '%s' has incomplete type",
4926 get_tok_str(v
, NULL
));
4928 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
4929 (type1
.t
& VT_BTYPE
) == VT_VOID
||
4930 (type1
.t
& VT_STORAGE
))
4931 tcc_error("invalid type for '%s'",
4932 get_tok_str(v
, NULL
));
4936 bit_size
= expr_const();
4937 /* XXX: handle v = 0 case for messages */
4939 tcc_error("negative width in bit-field '%s'",
4940 get_tok_str(v
, NULL
));
4941 if (v
&& bit_size
== 0)
4942 tcc_error("zero width for bit-field '%s'",
4943 get_tok_str(v
, NULL
));
4944 parse_attribute(&ad1
);
4946 size
= type_size(&type1
, &align
);
4947 if (bit_size
>= 0) {
4948 bt
= type1
.t
& VT_BTYPE
;
4954 tcc_error("bitfields must have scalar type");
4956 if (bit_size
> bsize
) {
4957 tcc_error("width of '%s' exceeds its type",
4958 get_tok_str(v
, NULL
));
4959 } else if (bit_size
== bsize
4960 && !ad
.a
.packed
&& !ad1
.a
.packed
) {
4961 /* no need for bit fields */
4963 } else if (bit_size
== 64) {
4964 tcc_error("field width 64 not implemented");
4966 type1
.t
= (type1
.t
& ~VT_STRUCT_MASK
)
4968 | (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4971 if (v
!= 0 || (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
4972 /* Remember we've seen a real field to check
4973 for placement of flexible array member. */
4976 /* If member is a struct or bit-field, enforce
4977 placing into the struct (as anonymous). */
4979 ((type1
.t
& VT_BTYPE
) == VT_STRUCT
||
4984 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, 0);
4989 if (tok
== ';' || tok
== TOK_EOF
)
4996 parse_attribute(&ad
);
4997 if (ad
.cleanup_func
) {
4998 tcc_warning("attribute '__cleanup__' ignored on type");
5000 check_fields(type
, 1);
5001 check_fields(type
, 0);
5002 struct_layout(type
, &ad
);
5007 static void sym_to_attr(AttributeDef
*ad
, Sym
*s
)
5009 merge_symattr(&ad
->a
, &s
->a
);
5010 merge_funcattr(&ad
->f
, &s
->f
);
5013 /* Add type qualifiers to a type. If the type is an array then the qualifiers
5014 are added to the element type, copied because it could be a typedef. */
5015 static void parse_btype_qualify(CType
*type
, int qualifiers
)
5017 while (type
->t
& VT_ARRAY
) {
5018 type
->ref
= sym_push(SYM_FIELD
, &type
->ref
->type
, 0, type
->ref
->c
);
5019 type
= &type
->ref
->type
;
5021 type
->t
|= qualifiers
;
5024 /* return 0 if no type declaration. otherwise, return the basic type
5027 static int parse_btype(CType
*type
, AttributeDef
*ad
)
5029 int t
, u
, bt
, st
, type_found
, typespec_found
, g
, n
;
5033 memset(ad
, 0, sizeof(AttributeDef
));
5043 /* currently, we really ignore extension */
5053 if (u
== VT_SHORT
|| u
== VT_LONG
) {
5054 if (st
!= -1 || (bt
!= -1 && bt
!= VT_INT
))
5055 tmbt
: tcc_error("too many basic types");
5058 if (bt
!= -1 || (st
!= -1 && u
!= VT_INT
))
5063 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | u
;
5080 memset(&ad1
, 0, sizeof(AttributeDef
));
5081 if (parse_btype(&type1
, &ad1
)) {
5082 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
5084 n
= 1 << (ad1
.a
.aligned
- 1);
5086 type_size(&type1
, &n
);
5089 if (n
<= 0 || (n
& (n
- 1)) != 0)
5090 tcc_error("alignment must be a positive power of two");
5093 ad
->a
.aligned
= exact_log2p1(n
);
5097 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
5098 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | VT_LDOUBLE
;
5099 } else if ((t
& (VT_BTYPE
|VT_LONG
)) == VT_LONG
) {
5100 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | VT_LLONG
;
5107 #ifdef TCC_TARGET_ARM64
5109 /* GCC's __uint128_t appears in some Linux header files. Make it a
5110 synonym for long double to get the size and alignment right. */
5121 if ((t
& (VT_BTYPE
|VT_LONG
)) == VT_LONG
) {
5122 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | VT_LDOUBLE
;
5130 struct_decl(&type1
, VT_ENUM
);
5133 type
->ref
= type1
.ref
;
5136 struct_decl(&type1
, VT_STRUCT
);
5139 struct_decl(&type1
, VT_UNION
);
5142 /* type modifiers */
5146 parse_btype_qualify(type
, VT_ATOMIC
);
5149 parse_expr_type(&type1
);
5150 /* remove all storage modifiers except typedef */
5151 type1
.t
&= ~(VT_STORAGE
&~VT_TYPEDEF
);
5153 sym_to_attr(ad
, type1
.ref
);
5161 parse_btype_qualify(type
, VT_CONSTANT
);
5169 parse_btype_qualify(type
, VT_VOLATILE
);
5176 if ((t
& (VT_DEFSIGN
|VT_UNSIGNED
)) == (VT_DEFSIGN
|VT_UNSIGNED
))
5177 tcc_error("signed and unsigned modifier");
5190 if ((t
& (VT_DEFSIGN
|VT_UNSIGNED
)) == VT_DEFSIGN
)
5191 tcc_error("signed and unsigned modifier");
5192 t
|= VT_DEFSIGN
| VT_UNSIGNED
;
5208 if (t
& (VT_EXTERN
|VT_STATIC
|VT_TYPEDEF
) & ~g
)
5209 tcc_error("multiple storage classes");
5221 ad
->f
.func_noreturn
= 1;
5223 /* GNUC attribute */
5224 case TOK_ATTRIBUTE1
:
5225 case TOK_ATTRIBUTE2
:
5226 parse_attribute(ad
);
5227 if (ad
->attr_mode
) {
5228 u
= ad
->attr_mode
-1;
5229 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | u
;
5237 parse_expr_type(&type1
);
5238 /* remove all storage modifiers except typedef */
5239 type1
.t
&= ~(VT_STORAGE
&~VT_TYPEDEF
);
5241 sym_to_attr(ad
, type1
.ref
);
5247 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
5251 if (tok
== ':' && !in_generic
) {
5252 /* ignore if it's a label */
5257 t
&= ~(VT_BTYPE
|VT_LONG
);
5258 u
= t
& ~(VT_CONSTANT
| VT_VOLATILE
), t
^= u
;
5259 type
->t
= (s
->type
.t
& ~VT_TYPEDEF
) | u
;
5260 type
->ref
= s
->type
.ref
;
5262 parse_btype_qualify(type
, t
);
5264 /* get attributes from typedef */
5273 if (tcc_state
->char_is_unsigned
) {
5274 if ((t
& (VT_DEFSIGN
|VT_BTYPE
)) == VT_BYTE
)
5277 /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
5278 bt
= t
& (VT_BTYPE
|VT_LONG
);
5280 t
|= LONG_SIZE
== 8 ? VT_LLONG
: VT_INT
;
5281 #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
5282 if (bt
== VT_LDOUBLE
)
5283 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | (VT_DOUBLE
|VT_LONG
);
5289 /* convert a function parameter type (array to pointer and function to
5290 function pointer) */
5291 static inline void convert_parameter_type(CType
*pt
)
5293 /* remove const and volatile qualifiers (XXX: const could be used
5294 to indicate a const function parameter */
5295 pt
->t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
5296 /* array must be transformed to pointer according to ANSI C */
5298 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
5303 ST_FUNC
void parse_asm_str(CString
*astr
)
5306 parse_mult_str(astr
, "string constant");
5309 /* Parse an asm label and return the token */
5310 static int asm_label_instr(void)
5316 parse_asm_str(&astr
);
5319 printf("asm_alias: \"%s\"\n", (char *)astr
.data
);
5321 v
= tok_alloc(astr
.data
, astr
.size
- 1)->tok
;
5326 static int post_type(CType
*type
, AttributeDef
*ad
, int storage
, int td
)
5328 int n
, l
, t1
, arg_size
, align
, unused_align
;
5329 Sym
**plast
, *s
, *first
;
5334 /* function type, or recursive declarator (return if so) */
5336 if (TYPE_DIRECT
== (td
& (TYPE_DIRECT
|TYPE_ABSTRACT
)))
5340 else if (parse_btype(&pt
, &ad1
))
5342 else if (td
& (TYPE_DIRECT
|TYPE_ABSTRACT
)) {
5343 merge_attr (ad
, &ad1
);
5354 /* read param name and compute offset */
5355 if (l
!= FUNC_OLD
) {
5356 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
5358 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
| TYPE_PARAM
);
5359 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
5360 tcc_error("parameter declared as void");
5365 pt
.t
= VT_VOID
; /* invalid type */
5370 expect("identifier");
5371 convert_parameter_type(&pt
);
5372 arg_size
+= (type_size(&pt
, &align
) + PTR_SIZE
- 1) / PTR_SIZE
;
5373 s
= sym_push(n
, &pt
, 0, 0);
5379 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
5384 if (l
== FUNC_NEW
&& !parse_btype(&pt
, &ad1
))
5385 tcc_error("invalid type");
5388 /* if no parameters, then old type prototype */
5391 /* remove parameter symbols from token table, keep on stack */
5393 sym_pop(local_stack
? &local_stack
: &global_stack
, first
->prev
, 1);
5394 for (s
= first
; s
; s
= s
->next
)
5398 /* NOTE: const is ignored in returned type as it has a special
5399 meaning in gcc / C++ */
5400 type
->t
&= ~VT_CONSTANT
;
5401 /* some ancient pre-K&R C allows a function to return an array
5402 and the array brackets to be put after the arguments, such
5403 that "int c()[]" means something like "int[] c()" */
5406 skip(']'); /* only handle simple "[]" */
5409 /* we push a anonymous symbol which will contain the function prototype */
5410 ad
->f
.func_args
= arg_size
;
5411 ad
->f
.func_type
= l
;
5412 s
= sym_push(SYM_FIELD
, type
, 0, 0);
5418 } else if (tok
== '[') {
5419 int saved_nocode_wanted
= nocode_wanted
;
5420 /* array definition */
5424 if (td
& TYPE_PARAM
) while (1) {
5425 /* XXX The optional type-quals and static should only be accepted
5426 in parameter decls. The '*' as well, and then even only
5427 in prototypes (not function defs). */
5429 case TOK_RESTRICT1
: case TOK_RESTRICT2
: case TOK_RESTRICT3
:
5445 } else if (tok
!= ']') {
5446 if (!local_stack
|| (storage
& VT_STATIC
))
5447 vpushi(expr_const());
5449 /* VLAs (which can only happen with local_stack && !VT_STATIC)
5450 length must always be evaluated, even under nocode_wanted,
5451 so that its size slot is initialized (e.g. under sizeof
5456 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
5459 tcc_error("invalid array size");
5461 if (!is_integer_btype(vtop
->type
.t
& VT_BTYPE
))
5462 tcc_error("size of variable length array should be an integer");
5468 /* parse next post type */
5469 post_type(type
, ad
, storage
, td
& ~(TYPE_DIRECT
|TYPE_ABSTRACT
));
5471 if ((type
->t
& VT_BTYPE
) == VT_FUNC
)
5472 tcc_error("declaration of an array of functions");
5473 if ((type
->t
& VT_BTYPE
) == VT_VOID
5474 || type_size(type
, &unused_align
) < 0)
5475 tcc_error("declaration of an array of incomplete type elements");
5477 t1
|= type
->t
& VT_VLA
;
5481 tcc_error("need explicit inner array size in VLAs");
5482 loc
-= type_size(&int_type
, &align
);
5486 vpush_type_size(type
, &align
);
5488 vset(&int_type
, VT_LOCAL
|VT_LVAL
, n
);
5494 nocode_wanted
= saved_nocode_wanted
;
5496 /* we push an anonymous symbol which will contain the array
5498 s
= sym_push(SYM_FIELD
, type
, 0, n
);
5499 type
->t
= (t1
? VT_VLA
: VT_ARRAY
) | VT_PTR
;
5505 /* Parse a type declarator (except basic type), and return the type
5506 in 'type'. 'td' is a bitmask indicating which kind of type decl is
5507 expected. 'type' should contain the basic type. 'ad' is the
5508 attribute definition of the basic type. It can be modified by
5509 type_decl(). If this (possibly abstract) declarator is a pointer chain
5510 it returns the innermost pointed to type (equals *type, but is a different
5511 pointer), otherwise returns type itself, that's used for recursive calls. */
5512 static CType
*type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
5515 int qualifiers
, storage
;
5517 /* recursive type, remove storage bits first, apply them later again */
5518 storage
= type
->t
& VT_STORAGE
;
5519 type
->t
&= ~VT_STORAGE
;
5522 while (tok
== '*') {
5528 qualifiers
|= VT_ATOMIC
;
5533 qualifiers
|= VT_CONSTANT
;
5538 qualifiers
|= VT_VOLATILE
;
5544 /* XXX: clarify attribute handling */
5545 case TOK_ATTRIBUTE1
:
5546 case TOK_ATTRIBUTE2
:
5547 parse_attribute(ad
);
5551 type
->t
|= qualifiers
;
5553 /* innermost pointed to type is the one for the first derivation */
5554 ret
= pointed_type(type
);
5558 /* This is possibly a parameter type list for abstract declarators
5559 ('int ()'), use post_type for testing this. */
5560 if (!post_type(type
, ad
, 0, td
)) {
5561 /* It's not, so it's a nested declarator, and the post operations
5562 apply to the innermost pointed to type (if any). */
5563 /* XXX: this is not correct to modify 'ad' at this point, but
5564 the syntax is not clear */
5565 parse_attribute(ad
);
5566 post
= type_decl(type
, ad
, v
, td
);
5570 } else if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
5571 /* type identifier */
5576 if (!(td
& TYPE_ABSTRACT
))
5577 expect("identifier");
5580 post_type(post
, ad
, storage
, td
& ~(TYPE_DIRECT
|TYPE_ABSTRACT
));
5581 parse_attribute(ad
);
5586 /* indirection with full error checking and bound check */
5587 ST_FUNC
void indir(void)
5589 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
) {
5590 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
5594 if (vtop
->r
& VT_LVAL
)
5596 vtop
->type
= *pointed_type(&vtop
->type
);
5597 /* Arrays and functions are never lvalues */
5598 if (!(vtop
->type
.t
& (VT_ARRAY
| VT_VLA
))
5599 && (vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
5601 /* if bound checking, the referenced pointer must be checked */
5602 #ifdef CONFIG_TCC_BCHECK
5603 if (tcc_state
->do_bounds_check
)
5604 vtop
->r
|= VT_MUSTBOUND
;
5609 /* pass a parameter to a function and do type checking and casting */
5610 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
5615 func_type
= func
->f
.func_type
;
5616 if (func_type
== FUNC_OLD
||
5617 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
5618 /* default casting : only need to convert float to double */
5619 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
5620 gen_cast_s(VT_DOUBLE
);
5621 } else if (vtop
->type
.t
& VT_BITFIELD
) {
5622 type
.t
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5623 type
.ref
= vtop
->type
.ref
;
5625 } else if (vtop
->r
& VT_MUSTCAST
) {
5626 force_charshort_cast();
5628 } else if (arg
== NULL
) {
5629 tcc_error("too many arguments to function");
5632 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
5633 gen_assign_cast(&type
);
5637 /* parse an expression and return its type without any side effect. */
5638 static void expr_type(CType
*type
, void (*expr_fn
)(void))
5647 /* parse an expression of the form '(type)' or '(expr)' and return its
5649 static void parse_expr_type(CType
*type
)
5655 if (parse_btype(type
, &ad
)) {
5656 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
5658 expr_type(type
, gexpr
);
5663 static void parse_type(CType
*type
)
5668 if (!parse_btype(type
, &ad
)) {
5671 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
5674 static void parse_builtin_params(int nc
, const char *args
)
5683 while ((c
= *args
++)) {
5698 type
.t
= VT_CONSTANT
;
5704 type
.t
= VT_CONSTANT
;
5706 type
.t
|= char_type
.t
;
5718 gen_assign_cast(&type
);
5725 static void parse_atomic(int atok
)
5727 int size
, align
, arg
;
5728 CType
*atom
, *atom_ptr
, ct
= {0};
5730 static const char *const templates
[] = {
5732 * Each entry consists of callback and function template.
5733 * The template represents argument types and return type.
5735 * ? void (return-only)
5738 * A read-only atomic
5739 * p pointer to memory
5744 /* keep in order of appearance in tcctok.h: */
5745 /* __atomic_store */ "avm.?",
5746 /* __atomic_load */ "Am.v",
5747 /* __atomic_exchange */ "avm.v",
5748 /* __atomic_compare_exchange */ "apvbmm.b",
5749 /* __atomic_fetch_add */ "avm.v",
5750 /* __atomic_fetch_sub */ "avm.v",
5751 /* __atomic_fetch_or */ "avm.v",
5752 /* __atomic_fetch_xor */ "avm.v",
5753 /* __atomic_fetch_and */ "avm.v"
5755 const char *template = templates
[(atok
- TOK___atomic_store
)];
5757 atom
= atom_ptr
= NULL
;
5758 size
= 0; /* pacify compiler */
5763 switch (template[arg
]) {
5766 atom_ptr
= &vtop
->type
;
5767 if ((atom_ptr
->t
& VT_BTYPE
) != VT_PTR
)
5769 atom
= pointed_type(atom_ptr
);
5770 size
= type_size(atom
, &align
);
5772 || (size
& (size
- 1))
5773 || (atok
> TOK___atomic_compare_exchange
5774 && (0 == btype_size(atom
->t
& VT_BTYPE
)
5775 || (atom
->t
& VT_BTYPE
) == VT_PTR
)))
5776 expect("integral or integer-sized pointer target type");
5777 /* GCC does not care either: */
5778 /* if (!(atom->t & VT_ATOMIC))
5779 tcc_warning("pointer target declaration is missing '_Atomic'"); */
5783 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
5784 || type_size(pointed_type(&vtop
->type
), &align
) != size
)
5785 tcc_error("pointer target type mismatch in argument %d", arg
+ 1);
5786 gen_assign_cast(atom_ptr
);
5789 gen_assign_cast(atom
);
5792 gen_assign_cast(&int_type
);
5796 gen_assign_cast(&ct
);
5799 if ('.' == template[++arg
])
5806 switch (template[arg
+ 1]) {
5815 sprintf(buf
, "%s_%d", get_tok_str(atok
, 0), size
);
5816 vpush_helper_func(tok_alloc_const(buf
));
5821 PUT_R_RET(vtop
, ct
.t
);
5822 if (ct
.t
== VT_BOOL
) {
5824 vtop
->r
|= BFVAL(VT_MUSTCAST
, 1);
5826 vtop
->type
.t
= VT_INT
;
5831 ST_FUNC
void unary(void)
5833 int n
, t
, align
, size
, r
, sizeof_caller
;
5838 /* generate line number info */
5840 tcc_debug_line(tcc_state
), tcc_tcov_check_line (1);
5842 sizeof_caller
= in_sizeof
;
5845 /* XXX: GCC 2.95.3 does not generate a table although it should be
5853 #ifdef TCC_TARGET_PE
5854 t
= VT_SHORT
|VT_UNSIGNED
;
5862 vsetc(&type
, VT_CONST
, &tokc
);
5866 t
= VT_INT
| VT_UNSIGNED
;
5872 t
= VT_LLONG
| VT_UNSIGNED
;
5884 t
= (LONG_SIZE
== 8 ? VT_LLONG
: VT_INT
) | VT_LONG
;
5887 t
= (LONG_SIZE
== 8 ? VT_LLONG
: VT_INT
) | VT_LONG
| VT_UNSIGNED
;
5889 case TOK___FUNCTION__
:
5891 goto tok_identifier
;
5897 /* special function name identifier */
5898 len
= strlen(funcname
) + 1;
5899 /* generate char[len] type */
5900 type
.t
= char_type
.t
;
5901 if (tcc_state
->warn_write_strings
& WARN_ON
)
5902 type
.t
|= VT_CONSTANT
;
5906 sec
= rodata_section
;
5907 vpush_ref(&type
, sec
, sec
->data_offset
, len
);
5909 memcpy(section_ptr_add(sec
, len
), funcname
, len
);
5914 #ifdef TCC_TARGET_PE
5915 t
= VT_SHORT
| VT_UNSIGNED
;
5921 /* string parsing */
5924 if (tcc_state
->warn_write_strings
& WARN_ON
)
5929 memset(&ad
, 0, sizeof(AttributeDef
));
5930 ad
.section
= rodata_section
;
5931 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
5936 if (parse_btype(&type
, &ad
)) {
5937 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
5939 /* check ISOC99 compound literal */
5941 /* data is allocated locally by default */
5946 /* all except arrays are lvalues */
5947 if (!(type
.t
& VT_ARRAY
))
5949 memset(&ad
, 0, sizeof(AttributeDef
));
5950 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
5952 if (sizeof_caller
) {
5959 } else if (tok
== '{') {
5960 int saved_nocode_wanted
= nocode_wanted
;
5961 if (const_wanted
&& !(nocode_wanted
& unevalmask
))
5963 if (0 == local_scope
)
5964 tcc_error("statement expression outside of function");
5965 /* save all registers */
5967 /* statement expression : we do not accept break/continue
5968 inside as GCC does. We do retain the nocode_wanted state,
5969 as statement expressions can't ever be entered from the
5970 outside, so any reactivation of code emission (from labels
5971 or loop heads) can be disabled again after the end of it. */
5973 /* or'ing to keep however possible CODE_OFF() from e.g. "return 0;"
5974 in the statement expression */
5975 nocode_wanted
|= saved_nocode_wanted
;
5990 /* functions names must be treated as function pointers,
5991 except for unary '&' and sizeof. Since we consider that
5992 functions are not lvalues, we only have to handle it
5993 there and in function calls. */
5994 /* arrays can also be used although they are not lvalues */
5995 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
5996 !(vtop
->type
.t
& VT_ARRAY
))
5999 vtop
->sym
->a
.addrtaken
= 1;
6000 mk_pointer(&vtop
->type
);
6006 gen_test_zero(TOK_EQ
);
6017 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
6018 tcc_error("pointer not accepted for unary plus");
6019 /* In order to force cast, we add zero, except for floating point
6020 where we really need an noop (otherwise -0.0 will be transformed
6022 if (!is_float(vtop
->type
.t
)) {
6034 expr_type(&type
, unary
); /* Perform a in_sizeof = 0; */
6035 if (t
== TOK_SIZEOF
) {
6036 vpush_type_size(&type
, &align
);
6037 gen_cast_s(VT_SIZE_T
);
6039 type_size(&type
, &align
);
6041 if (vtop
[1].r
& VT_SYM
)
6042 s
= vtop
[1].sym
; /* hack: accessing previous vtop */
6043 if (s
&& s
->a
.aligned
)
6044 align
= 1 << (s
->a
.aligned
- 1);
6049 case TOK_builtin_expect
:
6050 /* __builtin_expect is a no-op for now */
6051 parse_builtin_params(0, "ee");
6054 case TOK_builtin_types_compatible_p
:
6055 parse_builtin_params(0, "tt");
6056 vtop
[-1].type
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6057 vtop
[0].type
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6058 n
= is_compatible_types(&vtop
[-1].type
, &vtop
[0].type
);
6062 case TOK_builtin_choose_expr
:
6089 case TOK_builtin_constant_p
:
6090 parse_builtin_params(1, "e");
6091 n
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
&&
6092 !((vtop
->r
& VT_SYM
) && vtop
->sym
->a
.addrtaken
);
6096 case TOK_builtin_frame_address
:
6097 case TOK_builtin_return_address
:
6103 if (tok
!= TOK_CINT
) {
6104 tcc_error("%s only takes positive integers",
6105 tok1
== TOK_builtin_return_address
?
6106 "__builtin_return_address" :
6107 "__builtin_frame_address");
6109 level
= (uint32_t)tokc
.i
;
6114 vset(&type
, VT_LOCAL
, 0); /* local frame */
6116 #ifdef TCC_TARGET_RISCV64
6120 mk_pointer(&vtop
->type
);
6121 indir(); /* -> parent frame */
6123 if (tok1
== TOK_builtin_return_address
) {
6124 // assume return address is just above frame pointer on stack
6125 #ifdef TCC_TARGET_ARM
6128 #elif defined TCC_TARGET_RISCV64
6135 mk_pointer(&vtop
->type
);
6140 #ifdef TCC_TARGET_RISCV64
6141 case TOK_builtin_va_start
:
6142 parse_builtin_params(0, "ee");
6143 r
= vtop
->r
& VT_VALMASK
;
6147 tcc_error("__builtin_va_start expects a local variable");
6152 #ifdef TCC_TARGET_X86_64
6153 #ifdef TCC_TARGET_PE
6154 case TOK_builtin_va_start
:
6155 parse_builtin_params(0, "ee");
6156 r
= vtop
->r
& VT_VALMASK
;
6160 tcc_error("__builtin_va_start expects a local variable");
6162 vtop
->type
= char_pointer_type
;
6167 case TOK_builtin_va_arg_types
:
6168 parse_builtin_params(0, "t");
6169 vpushi(classify_x86_64_va_arg(&vtop
->type
));
6176 #ifdef TCC_TARGET_ARM64
6177 case TOK_builtin_va_start
: {
6178 parse_builtin_params(0, "ee");
6182 vtop
->type
.t
= VT_VOID
;
6185 case TOK_builtin_va_arg
: {
6186 parse_builtin_params(0, "et");
6194 case TOK___arm64_clear_cache
: {
6195 parse_builtin_params(0, "ee");
6198 vtop
->type
.t
= VT_VOID
;
6203 /* atomic operations */
6204 case TOK___atomic_store
:
6205 case TOK___atomic_load
:
6206 case TOK___atomic_exchange
:
6207 case TOK___atomic_compare_exchange
:
6208 case TOK___atomic_fetch_add
:
6209 case TOK___atomic_fetch_sub
:
6210 case TOK___atomic_fetch_or
:
6211 case TOK___atomic_fetch_xor
:
6212 case TOK___atomic_fetch_and
:
6216 /* pre operations */
6227 if (is_float(vtop
->type
.t
)) {
6237 goto tok_identifier
;
6239 /* allow to take the address of a label */
6240 if (tok
< TOK_UIDENT
)
6241 expect("label identifier");
6242 s
= label_find(tok
);
6244 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
6246 if (s
->r
== LABEL_DECLARED
)
6247 s
->r
= LABEL_FORWARD
;
6250 s
->type
.t
= VT_VOID
;
6251 mk_pointer(&s
->type
);
6252 s
->type
.t
|= VT_STATIC
;
6254 vpushsym(&s
->type
, s
);
6260 CType controlling_type
;
6261 int has_default
= 0;
6264 TokenString
*str
= NULL
;
6265 int saved_const_wanted
= const_wanted
;
6270 expr_type(&controlling_type
, expr_eq
);
6271 controlling_type
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
| VT_ARRAY
);
6272 if ((controlling_type
.t
& VT_BTYPE
) == VT_FUNC
)
6273 mk_pointer(&controlling_type
);
6274 const_wanted
= saved_const_wanted
;
6278 if (tok
== TOK_DEFAULT
) {
6280 tcc_error("too many 'default'");
6286 AttributeDef ad_tmp
;
6291 parse_btype(&cur_type
, &ad_tmp
);
6294 type_decl(&cur_type
, &ad_tmp
, &itmp
, TYPE_ABSTRACT
);
6295 if (compare_types(&controlling_type
, &cur_type
, 0)) {
6297 tcc_error("type match twice");
6307 skip_or_save_block(&str
);
6309 skip_or_save_block(NULL
);
6316 type_to_str(buf
, sizeof buf
, &controlling_type
, NULL
);
6317 tcc_error("type '%s' does not match any association", buf
);
6319 begin_macro(str
, 1);
6328 // special qnan , snan and infinity values
6333 vtop
->type
.t
= VT_FLOAT
;
6338 goto special_math_val
;
6341 goto special_math_val
;
6348 expect("identifier");
6350 if (!s
|| IS_ASM_SYM(s
)) {
6351 const char *name
= get_tok_str(t
, NULL
);
6353 tcc_error("'%s' undeclared", name
);
6354 /* for simple function calls, we tolerate undeclared
6355 external reference to int() function */
6356 tcc_warning_c(warn_implicit_function_declaration
)(
6357 "implicit declaration of function '%s'", name
);
6358 s
= external_global_sym(t
, &func_old_type
);
6362 /* A symbol that has a register is a local register variable,
6363 which starts out as VT_LOCAL value. */
6364 if ((r
& VT_VALMASK
) < VT_CONST
)
6365 r
= (r
& ~VT_VALMASK
) | VT_LOCAL
;
6367 vset(&s
->type
, r
, s
->c
);
6368 /* Point to s as backpointer (even without r&VT_SYM).
6369 Will be used by at least the x86 inline asm parser for
6375 } else if (r
== VT_CONST
&& IS_ENUM_VAL(s
->type
.t
)) {
6376 vtop
->c
.i
= s
->enum_val
;
6381 /* post operations */
6383 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
6386 } else if (tok
== '.' || tok
== TOK_ARROW
|| tok
== TOK_CDOUBLE
) {
6387 int qualifiers
, cumofs
= 0;
6389 if (tok
== TOK_ARROW
)
6391 qualifiers
= vtop
->type
.t
& (VT_CONSTANT
| VT_VOLATILE
);
6394 /* expect pointer on structure */
6395 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
6396 expect("struct or union");
6397 if (tok
== TOK_CDOUBLE
)
6398 expect("field name");
6400 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
6401 expect("field name");
6402 s
= find_field(&vtop
->type
, tok
, &cumofs
);
6404 tcc_error("field not found: %s", get_tok_str(tok
& ~SYM_FIELD
, &tokc
));
6405 /* add field offset to pointer */
6406 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
6407 vpushi(cumofs
+ s
->c
);
6409 /* change type to field type, and set to lvalue */
6410 vtop
->type
= s
->type
;
6411 vtop
->type
.t
|= qualifiers
;
6412 /* an array is never an lvalue */
6413 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6415 #ifdef CONFIG_TCC_BCHECK
6416 /* if bound checking, the referenced pointer must be checked */
6417 if (tcc_state
->do_bounds_check
)
6418 vtop
->r
|= VT_MUSTBOUND
;
6422 } else if (tok
== '[') {
6428 } else if (tok
== '(') {
6431 int nb_args
, ret_nregs
, ret_align
, regsize
, variadic
;
6434 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
6435 /* pointer test (no array accepted) */
6436 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
6437 vtop
->type
= *pointed_type(&vtop
->type
);
6438 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
6442 expect("function pointer");
6445 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
6447 /* get return type */
6450 sa
= s
->next
; /* first parameter */
6451 nb_args
= regsize
= 0;
6453 /* compute first implicit argument if a structure is returned */
6454 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
6455 variadic
= (s
->f
.func_type
== FUNC_ELLIPSIS
);
6456 ret_nregs
= gfunc_sret(&s
->type
, variadic
, &ret
.type
,
6457 &ret_align
, ®size
);
6458 if (ret_nregs
<= 0) {
6459 /* get some space for the returned structure */
6460 size
= type_size(&s
->type
, &align
);
6461 #ifdef TCC_TARGET_ARM64
6462 /* On arm64, a small struct is return in registers.
6463 It is much easier to write it to memory if we know
6464 that we are allowed to write some extra bytes, so
6465 round the allocated space up to a power of 2: */
6467 while (size
& (size
- 1))
6468 size
= (size
| (size
- 1)) + 1;
6470 loc
= (loc
- size
) & -align
;
6472 ret
.r
= VT_LOCAL
| VT_LVAL
;
6473 /* pass it as 'int' to avoid structure arg passing
6475 vseti(VT_LOCAL
, loc
);
6476 #ifdef CONFIG_TCC_BCHECK
6477 if (tcc_state
->do_bounds_check
)
6491 if (ret_nregs
> 0) {
6492 /* return in register */
6494 PUT_R_RET(&ret
, ret
.type
.t
);
6499 gfunc_param_typed(s
, sa
);
6509 tcc_error("too few arguments to function");
6511 gfunc_call(nb_args
);
6513 if (ret_nregs
< 0) {
6514 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
6515 #ifdef TCC_TARGET_RISCV64
6516 arch_transfer_ret_regs(1);
6520 for (r
= ret
.r
+ ret_nregs
+ !ret_nregs
; r
-- > ret
.r
;) {
6521 vsetc(&ret
.type
, r
, &ret
.c
);
6522 vtop
->r2
= ret
.r2
; /* Loop only happens when r2 is VT_CONST */
6525 /* handle packed struct return */
6526 if (((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) && ret_nregs
) {
6529 size
= type_size(&s
->type
, &align
);
6530 /* We're writing whole regs often, make sure there's enough
6531 space. Assume register size is power of 2. */
6532 if (regsize
> align
)
6534 loc
= (loc
- size
) & -align
;
6538 vset(&ret
.type
, VT_LOCAL
| VT_LVAL
, addr
+ offset
);
6542 if (--ret_nregs
== 0)
6546 vset(&s
->type
, VT_LOCAL
| VT_LVAL
, addr
);
6549 /* Promote char/short return values. This is matters only
6550 for calling function that were not compiled by TCC and
6551 only on some architectures. For those where it doesn't
6552 matter we expect things to be already promoted to int,
6554 t
= s
->type
.t
& VT_BTYPE
;
6555 if (t
== VT_BYTE
|| t
== VT_SHORT
|| t
== VT_BOOL
) {
6557 vtop
->r
|= BFVAL(VT_MUSTCAST
, 1);
6559 vtop
->type
.t
= VT_INT
;
6563 if (s
->f
.func_noreturn
) {
6565 tcc_tcov_block_end (tcov_data
.line
);
6574 #ifndef precedence_parser /* original top-down parser */
6576 static void expr_prod(void)
6581 while ((t
= tok
) == '*' || t
== '/' || t
== '%') {
6588 static void expr_sum(void)
6593 while ((t
= tok
) == '+' || t
== '-') {
6600 static void expr_shift(void)
6605 while ((t
= tok
) == TOK_SHL
|| t
== TOK_SAR
) {
6612 static void expr_cmp(void)
6617 while (((t
= tok
) >= TOK_ULE
&& t
<= TOK_GT
) ||
6618 t
== TOK_ULT
|| t
== TOK_UGE
) {
6625 static void expr_cmpeq(void)
6630 while ((t
= tok
) == TOK_EQ
|| t
== TOK_NE
) {
6637 static void expr_and(void)
6640 while (tok
== '&') {
6647 static void expr_xor(void)
6650 while (tok
== '^') {
6657 static void expr_or(void)
6660 while (tok
== '|') {
6667 static void expr_landor(int op
);
6669 static void expr_land(void)
6672 if (tok
== TOK_LAND
)
6676 static void expr_lor(void)
6683 # define expr_landor_next(op) op == TOK_LAND ? expr_or() : expr_land()
6684 #else /* defined precedence_parser */
6685 # define expr_landor_next(op) unary(), expr_infix(precedence(op) + 1)
6686 # define expr_lor() unary(), expr_infix(1)
6688 static int precedence(int tok
)
6691 case TOK_LOR
: return 1;
6692 case TOK_LAND
: return 2;
6696 case TOK_EQ
: case TOK_NE
: return 6;
6697 relat
: case TOK_ULT
: case TOK_UGE
: return 7;
6698 case TOK_SHL
: case TOK_SAR
: return 8;
6699 case '+': case '-': return 9;
6700 case '*': case '/': case '%': return 10;
6702 if (tok
>= TOK_ULE
&& tok
<= TOK_GT
)
6707 static unsigned char prec
[256];
6708 static void init_prec(void)
6711 for (i
= 0; i
< 256; i
++)
6712 prec
[i
] = precedence(i
);
6714 #define precedence(i) ((unsigned)i < 256 ? prec[i] : 0)
6716 static void expr_landor(int op
);
6718 static void expr_infix(int p
)
6721 while ((p2
= precedence(t
)) >= p
) {
6722 if (t
== TOK_LOR
|| t
== TOK_LAND
) {
6727 if (precedence(tok
) > p2
)
6736 /* Assuming vtop is a value used in a conditional context
6737 (i.e. compared with zero) return 0 if it's false, 1 if
6738 true and -1 if it can't be statically determined. */
6739 static int condition_3way(void)
6742 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
&&
6743 (!(vtop
->r
& VT_SYM
) || !vtop
->sym
->a
.weak
)) {
6745 gen_cast_s(VT_BOOL
);
6752 static void expr_landor(int op
)
6754 int t
= 0, cc
= 1, f
= 0, i
= op
== TOK_LAND
, c
;
6756 c
= f
? i
: condition_3way();
6758 save_regs(1), cc
= 0;
6760 nocode_wanted
++, f
= 1;
6768 expr_landor_next(op
);
6780 static int is_cond_bool(SValue
*sv
)
6782 if ((sv
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
6783 && (sv
->type
.t
& VT_BTYPE
) == VT_INT
)
6784 return (unsigned)sv
->c
.i
< 2;
6785 if (sv
->r
== VT_CMP
)
6790 static void expr_cond(void)
6792 int tt
, u
, r1
, r2
, rc
, t1
, t2
, islv
, c
, g
;
6800 c
= condition_3way();
6801 g
= (tok
== ':' && gnu_ext
);
6811 /* needed to avoid having different registers saved in
6818 ncw_prev
= nocode_wanted
;
6824 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
6825 mk_pointer(&vtop
->type
);
6826 sv
= *vtop
; /* save value to handle it later */
6827 vtop
--; /* no vpop so that FP stack is not flushed */
6837 nocode_wanted
= ncw_prev
;
6843 if (c
< 0 && is_cond_bool(vtop
) && is_cond_bool(&sv
)) {
6844 /* optimize "if (f ? a > b : c || d) ..." for example, where normally
6845 "a < b" and "c || d" would be forced to "(int)0/1" first, whereas
6846 this code jumps directly to the if's then/else branches. */
6851 /* combine jump targets of 2nd op with VT_CMP of 1st op */
6854 nocode_wanted
= ncw_prev
;
6855 // tcc_warning("two conditions expr_cond");
6859 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
6860 mk_pointer(&vtop
->type
);
6862 /* cast operands to correct type according to ISOC rules */
6863 if (!combine_types(&type
, &sv
, vtop
, '?'))
6864 type_incompatibility_error(&sv
.type
, &vtop
->type
,
6865 "type mismatch in conditional expression (have '%s' and '%s')");
6866 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
6867 that `(expr ? a : b).mem` does not error with "lvalue expected" */
6868 islv
= (vtop
->r
& VT_LVAL
) && (sv
.r
& VT_LVAL
) && VT_STRUCT
== (type
.t
& VT_BTYPE
);
6870 /* now we convert second operand */
6874 mk_pointer(&vtop
->type
);
6876 } else if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
6880 rc
= RC_TYPE(type
.t
);
6881 /* for long longs, we use fixed registers to avoid having
6882 to handle a complicated move */
6883 if (USING_TWO_WORDS(type
.t
))
6884 rc
= RC_RET(type
.t
);
6892 nocode_wanted
= ncw_prev
;
6894 /* this is horrible, but we must also convert first
6900 mk_pointer(&vtop
->type
);
6902 } else if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
6908 move_reg(r2
, r1
, islv
? VT_PTR
: type
.t
);
6918 static void expr_eq(void)
6923 if ((t
= tok
) == '=' || TOK_ASSIGN(t
)) {
6931 gen_op(TOK_ASSIGN_OP(t
));
6937 ST_FUNC
void gexpr(void)
6948 /* parse a constant expression and return value in vtop. */
6949 static void expr_const1(void)
6952 nocode_wanted
+= unevalmask
+ 1;
6954 nocode_wanted
-= unevalmask
+ 1;
6958 /* parse an integer constant and return its value. */
6959 static inline int64_t expr_const64(void)
6963 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
6964 expect("constant expression");
6970 /* parse an integer constant and return its value.
6971 Complain if it doesn't fit 32bit (signed or unsigned). */
6972 ST_FUNC
int expr_const(void)
6975 int64_t wc
= expr_const64();
6977 if (c
!= wc
&& (unsigned)c
!= wc
)
6978 tcc_error("constant exceeds 32 bit");
6982 /* ------------------------------------------------------------------------- */
6983 /* return from function */
6985 #ifndef TCC_TARGET_ARM64
6986 static void gfunc_return(CType
*func_type
)
6988 if ((func_type
->t
& VT_BTYPE
) == VT_STRUCT
) {
6989 CType type
, ret_type
;
6990 int ret_align
, ret_nregs
, regsize
;
6991 ret_nregs
= gfunc_sret(func_type
, func_var
, &ret_type
,
6992 &ret_align
, ®size
);
6993 if (ret_nregs
< 0) {
6994 #ifdef TCC_TARGET_RISCV64
6995 arch_transfer_ret_regs(0);
6997 } else if (0 == ret_nregs
) {
6998 /* if returning structure, must copy it to implicit
6999 first pointer arg location */
7002 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
7005 /* copy structure value to pointer */
7008 /* returning structure packed into registers */
7009 int size
, addr
, align
, rc
;
7010 size
= type_size(func_type
,&align
);
7011 if ((vtop
->r
!= (VT_LOCAL
| VT_LVAL
) ||
7012 (vtop
->c
.i
& (ret_align
-1)))
7013 && (align
& (ret_align
-1))) {
7014 loc
= (loc
- size
) & -ret_align
;
7017 vset(&type
, VT_LOCAL
| VT_LVAL
, addr
);
7021 vset(&ret_type
, VT_LOCAL
| VT_LVAL
, addr
);
7023 vtop
->type
= ret_type
;
7024 rc
= RC_RET(ret_type
.t
);
7032 if (--ret_nregs
== 0)
7034 /* We assume that when a structure is returned in multiple
7035 registers, their classes are consecutive values of the
7038 vtop
->c
.i
+= regsize
;
7043 gv(RC_RET(func_type
->t
));
7045 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
7049 static void check_func_return(void)
7051 if ((func_vt
.t
& VT_BTYPE
) == VT_VOID
)
7053 if (!strcmp (funcname
, "main")
7054 && (func_vt
.t
& VT_BTYPE
) == VT_INT
) {
7055 /* main returns 0 by default */
7057 gen_assign_cast(&func_vt
);
7058 gfunc_return(&func_vt
);
7060 tcc_warning("function might return no value: '%s'", funcname
);
7064 /* ------------------------------------------------------------------------- */
7067 static int case_cmpi(const void *pa
, const void *pb
)
7069 int64_t a
= (*(struct case_t
**) pa
)->v1
;
7070 int64_t b
= (*(struct case_t
**) pb
)->v1
;
7071 return a
< b
? -1 : a
> b
;
7074 static int case_cmpu(const void *pa
, const void *pb
)
7076 uint64_t a
= (uint64_t)(*(struct case_t
**) pa
)->v1
;
7077 uint64_t b
= (uint64_t)(*(struct case_t
**) pb
)->v1
;
7078 return a
< b
? -1 : a
> b
;
7081 static void gtst_addr(int t
, int a
)
7083 gsym_addr(gvtst(0, t
), a
);
7086 static void gcase(struct case_t
**base
, int len
, int *bsym
)
7090 int ll
= (vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
;
7107 gtst_addr(0, p
->sym
); /* v1 <= x <= v2 */
7109 gcase(base
, len
/2, bsym
);
7113 base
+= e
; len
-= e
;
7123 if (p
->v1
== p
->v2
) {
7125 gtst_addr(0, p
->sym
);
7135 gtst_addr(0, p
->sym
);
7139 *bsym
= gjmp(*bsym
);
7142 /* ------------------------------------------------------------------------- */
7143 /* __attribute__((cleanup(fn))) */
7145 static void try_call_scope_cleanup(Sym
*stop
)
7147 Sym
*cls
= cur_scope
->cl
.s
;
7149 for (; cls
!= stop
; cls
= cls
->ncl
) {
7150 Sym
*fs
= cls
->next
;
7151 Sym
*vs
= cls
->prev_tok
;
7153 vpushsym(&fs
->type
, fs
);
7154 vset(&vs
->type
, vs
->r
, vs
->c
);
7156 mk_pointer(&vtop
->type
);
7162 static void try_call_cleanup_goto(Sym
*cleanupstate
)
7167 if (!cur_scope
->cl
.s
)
7170 /* search NCA of both cleanup chains given parents and initial depth */
7171 ocd
= cleanupstate
? cleanupstate
->v
& ~SYM_FIELD
: 0;
7172 for (ccd
= cur_scope
->cl
.n
, oc
= cleanupstate
; ocd
> ccd
; --ocd
, oc
= oc
->ncl
)
7174 for (cc
= cur_scope
->cl
.s
; ccd
> ocd
; --ccd
, cc
= cc
->ncl
)
7176 for (; cc
!= oc
; cc
= cc
->ncl
, oc
= oc
->ncl
, --ccd
)
7179 try_call_scope_cleanup(cc
);
7182 /* call 'func' for each __attribute__((cleanup(func))) */
7183 static void block_cleanup(struct scope
*o
)
7187 for (pg
= &pending_gotos
; (g
= *pg
) && g
->c
> o
->cl
.n
;) {
7188 if (g
->prev_tok
->r
& LABEL_FORWARD
) {
7193 try_call_scope_cleanup(o
->cl
.s
);
7194 pcl
->jnext
= gjmp(0);
7196 goto remove_pending
;
7206 try_call_scope_cleanup(o
->cl
.s
);
7209 /* ------------------------------------------------------------------------- */
7212 static void vla_restore(int loc
)
7215 gen_vla_sp_restore(loc
);
7218 static void vla_leave(struct scope
*o
)
7220 struct scope
*c
= cur_scope
, *v
= NULL
;
7221 for (; c
!= o
&& c
; c
= c
->prev
)
7225 vla_restore(v
->vla
.locorig
);
7228 /* ------------------------------------------------------------------------- */
7231 static void new_scope(struct scope
*o
)
7233 /* copy and link previous scope */
7235 o
->prev
= cur_scope
;
7237 cur_scope
->vla
.num
= 0;
7239 /* record local declaration stack position */
7240 o
->lstk
= local_stack
;
7241 o
->llstk
= local_label_stack
;
7245 tcc_debug_stabn(tcc_state
, N_LBRAC
, ind
- func_ind
);
7248 static void prev_scope(struct scope
*o
, int is_expr
)
7252 if (o
->cl
.s
!= o
->prev
->cl
.s
)
7253 block_cleanup(o
->prev
);
7255 /* pop locally defined labels */
7256 label_pop(&local_label_stack
, o
->llstk
, is_expr
);
7258 /* In the is_expr case (a statement expression is finished here),
7259 vtop might refer to symbols on the local_stack. Either via the
7260 type or via vtop->sym. We can't pop those nor any that in turn
7261 might be referred to. To make it easier we don't roll back
7262 any symbols in that case; some upper level call to block() will
7263 do that. We do have to remove such symbols from the lookup
7264 tables, though. sym_pop will do that. */
7266 /* pop locally defined symbols */
7267 pop_local_syms(o
->lstk
, is_expr
);
7268 cur_scope
= o
->prev
;
7272 tcc_debug_stabn(tcc_state
, N_RBRAC
, ind
- func_ind
);
7275 /* leave a scope via break/continue(/goto) */
7276 static void leave_scope(struct scope
*o
)
7280 try_call_scope_cleanup(o
->cl
.s
);
7284 /* ------------------------------------------------------------------------- */
7285 /* call block from 'for do while' loops */
7287 static void lblock(int *bsym
, int *csym
)
7289 struct scope
*lo
= loop_scope
, *co
= cur_scope
;
7290 int *b
= co
->bsym
, *c
= co
->csym
;
7304 static void block(int is_expr
)
7306 int a
, b
, c
, d
, e
, t
;
7311 /* default return value is (void) */
7313 vtop
->type
.t
= VT_VOID
;
7318 /* If the token carries a value, next() might destroy it. Only with
7319 invalid code such as f(){"123"4;} */
7320 if (TOK_HAS_VALUE(t
))
7325 tcc_tcov_check_line (0), tcc_tcov_block_begin ();
7333 if (tok
== TOK_ELSE
) {
7338 gsym(d
); /* patch else jmp */
7343 } else if (t
== TOK_WHILE
) {
7355 } else if (t
== '{') {
7358 /* handle local labels declarations */
7359 while (tok
== TOK_LABEL
) {
7362 if (tok
< TOK_UIDENT
)
7363 expect("label identifier");
7364 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
7366 } while (tok
== ',');
7370 while (tok
!= '}') {
7379 prev_scope(&o
, is_expr
);
7382 else if (!nocode_wanted
)
7383 check_func_return();
7385 } else if (t
== TOK_RETURN
) {
7386 b
= (func_vt
.t
& VT_BTYPE
) != VT_VOID
;
7390 gen_assign_cast(&func_vt
);
7392 if (vtop
->type
.t
!= VT_VOID
)
7393 tcc_warning("void function returns a value");
7397 tcc_warning("'return' with no value");
7400 leave_scope(root_scope
);
7402 gfunc_return(&func_vt
);
7404 /* jump unless last stmt in top-level block */
7405 if (tok
!= '}' || local_scope
!= 1)
7408 tcc_tcov_block_end (tcov_data
.line
);
7411 } else if (t
== TOK_BREAK
) {
7413 if (!cur_scope
->bsym
)
7414 tcc_error("cannot break");
7415 if (cur_switch
&& cur_scope
->bsym
== cur_switch
->bsym
)
7416 leave_scope(cur_switch
->scope
);
7418 leave_scope(loop_scope
);
7419 *cur_scope
->bsym
= gjmp(*cur_scope
->bsym
);
7422 } else if (t
== TOK_CONTINUE
) {
7424 if (!cur_scope
->csym
)
7425 tcc_error("cannot continue");
7426 leave_scope(loop_scope
);
7427 *cur_scope
->csym
= gjmp(*cur_scope
->csym
);
7430 } else if (t
== TOK_FOR
) {
7435 /* c99 for-loop init decl? */
7436 if (!decl0(VT_LOCAL
, 1, NULL
)) {
7437 /* no, regular for-loop init expr */
7465 } else if (t
== TOK_DO
) {
7479 } else if (t
== TOK_SWITCH
) {
7480 struct switch_t
*sw
;
7482 sw
= tcc_mallocz(sizeof *sw
);
7484 sw
->scope
= cur_scope
;
7485 sw
->prev
= cur_switch
;
7491 sw
->sv
= *vtop
--; /* save switch value */
7494 b
= gjmp(0); /* jump to first case */
7496 a
= gjmp(a
); /* add implicit break */
7500 if (sw
->sv
.type
.t
& VT_UNSIGNED
)
7501 qsort(sw
->p
, sw
->n
, sizeof(void*), case_cmpu
);
7503 qsort(sw
->p
, sw
->n
, sizeof(void*), case_cmpi
);
7505 for (b
= 1; b
< sw
->n
; b
++)
7506 if (sw
->sv
.type
.t
& VT_UNSIGNED
7507 ? (uint64_t)sw
->p
[b
- 1]->v2
>= (uint64_t)sw
->p
[b
]->v1
7508 : sw
->p
[b
- 1]->v2
>= sw
->p
[b
]->v1
)
7509 tcc_error("duplicate case value");
7513 d
= 0, gcase(sw
->p
, sw
->n
, &d
);
7516 gsym_addr(d
, sw
->def_sym
);
7522 dynarray_reset(&sw
->p
, &sw
->n
);
7523 cur_switch
= sw
->prev
;
7526 } else if (t
== TOK_CASE
) {
7527 struct case_t
*cr
= tcc_malloc(sizeof(struct case_t
));
7530 cr
->v1
= cr
->v2
= expr_const64();
7531 if (gnu_ext
&& tok
== TOK_DOTS
) {
7533 cr
->v2
= expr_const64();
7534 if ((!(cur_switch
->sv
.type
.t
& VT_UNSIGNED
) && cr
->v2
< cr
->v1
)
7535 || (cur_switch
->sv
.type
.t
& VT_UNSIGNED
&& (uint64_t)cr
->v2
< (uint64_t)cr
->v1
))
7536 tcc_warning("empty case range");
7540 dynarray_add(&cur_switch
->p
, &cur_switch
->n
, cr
);
7543 goto block_after_label
;
7545 } else if (t
== TOK_DEFAULT
) {
7548 if (cur_switch
->def_sym
)
7549 tcc_error("too many 'default'");
7551 cur_switch
->def_sym
= gind();
7554 goto block_after_label
;
7556 } else if (t
== TOK_GOTO
) {
7557 if (cur_scope
->vla
.num
)
7558 vla_restore(cur_scope
->vla
.locorig
);
7559 if (tok
== '*' && gnu_ext
) {
7563 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
7567 } else if (tok
>= TOK_UIDENT
) {
7568 s
= label_find(tok
);
7569 /* put forward definition if needed */
7571 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7572 else if (s
->r
== LABEL_DECLARED
)
7573 s
->r
= LABEL_FORWARD
;
7575 if (s
->r
& LABEL_FORWARD
) {
7576 /* start new goto chain for cleanups, linked via label->next */
7577 if (cur_scope
->cl
.s
&& !nocode_wanted
) {
7578 sym_push2(&pending_gotos
, SYM_FIELD
, 0, cur_scope
->cl
.n
);
7579 pending_gotos
->prev_tok
= s
;
7580 s
= sym_push2(&s
->next
, SYM_FIELD
, 0, 0);
7581 pending_gotos
->next
= s
;
7583 s
->jnext
= gjmp(s
->jnext
);
7585 try_call_cleanup_goto(s
->cleanupstate
);
7586 gjmp_addr(s
->jnext
);
7591 expect("label identifier");
7595 } else if (t
== TOK_ASM1
|| t
== TOK_ASM2
|| t
== TOK_ASM3
) {
7599 if (tok
== ':' && t
>= TOK_UIDENT
) {
7604 if (s
->r
== LABEL_DEFINED
)
7605 tcc_error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
7606 s
->r
= LABEL_DEFINED
;
7608 Sym
*pcl
; /* pending cleanup goto */
7609 for (pcl
= s
->next
; pcl
; pcl
= pcl
->prev
)
7611 sym_pop(&s
->next
, NULL
, 0);
7615 s
= label_push(&global_label_stack
, t
, LABEL_DEFINED
);
7618 s
->cleanupstate
= cur_scope
->cl
.s
;
7621 vla_restore(cur_scope
->vla
.loc
);
7624 /* we accept this, but it is a mistake */
7625 tcc_warning_c(warn_all
)("deprecated use of label at end of compound statement");
7628 /* expression case */
7645 tcc_tcov_check_line (0), tcc_tcov_block_end (0);
7648 /* This skips over a stream of tokens containing balanced {} and ()
7649 pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started
7650 with a '{'). If STR then allocates and stores the skipped tokens
7651 in *STR. This doesn't check if () and {} are nested correctly,
7652 i.e. "({)}" is accepted. */
7653 static void skip_or_save_block(TokenString
**str
)
7655 int braces
= tok
== '{';
7658 *str
= tok_str_alloc();
7660 while ((level
> 0 || (tok
!= '}' && tok
!= ',' && tok
!= ';' && tok
!= ')'))) {
7662 if (tok
== TOK_EOF
) {
7663 if (str
|| level
> 0)
7664 tcc_error("unexpected end of file");
7669 tok_str_add_tok(*str
);
7672 if (t
== '{' || t
== '(') {
7674 } else if (t
== '}' || t
== ')') {
7676 if (level
== 0 && braces
&& t
== '}')
7681 tok_str_add(*str
, -1);
7682 tok_str_add(*str
, 0);
7686 #define EXPR_CONST 1
7689 static void parse_init_elem(int expr_type
)
7691 int saved_global_expr
;
7694 /* compound literals must be allocated globally in this case */
7695 saved_global_expr
= global_expr
;
7698 global_expr
= saved_global_expr
;
7699 /* NOTE: symbols are accepted, as well as lvalue for anon symbols
7700 (compound literals). */
7701 if (((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
7702 && ((vtop
->r
& (VT_SYM
|VT_LVAL
)) != (VT_SYM
|VT_LVAL
)
7703 || vtop
->sym
->v
< SYM_FIRST_ANOM
))
7704 #ifdef TCC_TARGET_PE
7705 || ((vtop
->r
& VT_SYM
) && vtop
->sym
->a
.dllimport
)
7708 tcc_error("initializer element is not constant");
7717 static void init_assert(init_params
*p
, int offset
)
7719 if (p
->sec
? !NODATA_WANTED
&& offset
> p
->sec
->data_offset
7720 : !nocode_wanted
&& offset
> p
->local_offset
)
7721 tcc_internal_error("initializer overflow");
7724 #define init_assert(sec, offset)
7727 /* put zeros for variable based init */
7728 static void init_putz(init_params
*p
, unsigned long c
, int size
)
7730 init_assert(p
, c
+ size
);
7732 /* nothing to do because globals are already set to zero */
7734 vpush_helper_func(TOK_memset
);
7736 #ifdef TCC_TARGET_ARM
7748 #define DIF_SIZE_ONLY 2
7749 #define DIF_HAVE_ELEM 4
7752 /* delete relocations for specified range c ... c + size. Unfortunatly
7753 in very special cases, relocations may occur unordered */
7754 static void decl_design_delrels(Section
*sec
, int c
, int size
)
7756 ElfW_Rel
*rel
, *rel2
, *rel_end
;
7757 if (!sec
|| !sec
->reloc
)
7759 rel
= rel2
= (ElfW_Rel
*)sec
->reloc
->data
;
7760 rel_end
= (ElfW_Rel
*)(sec
->reloc
->data
+ sec
->reloc
->data_offset
);
7761 while (rel
< rel_end
) {
7762 if (rel
->r_offset
>= c
&& rel
->r_offset
< c
+ size
) {
7763 sec
->reloc
->data_offset
-= sizeof *rel
;
7766 memcpy(rel2
, rel
, sizeof *rel
);
7773 static void decl_design_flex(init_params
*p
, Sym
*ref
, int index
)
7775 if (ref
== p
->flex_array_ref
) {
7776 if (index
>= ref
->c
)
7778 } else if (ref
->c
< 0)
7779 tcc_error("flexible array has zero size in this context");
7782 /* t is the array or struct type. c is the array or struct
7783 address. cur_field is the pointer to the current
7784 field, for arrays the 'c' member contains the current start
7785 index. 'flags' is as in decl_initializer.
7786 'al' contains the already initialized length of the
7787 current container (starting at c). This returns the new length of that. */
7788 static int decl_designator(init_params
*p
, CType
*type
, unsigned long c
,
7789 Sym
**cur_field
, int flags
, int al
)
7792 int index
, index_last
, align
, l
, nb_elems
, elem_size
;
7793 unsigned long corig
= c
;
7798 if (flags
& DIF_HAVE_ELEM
)
7801 if (gnu_ext
&& tok
>= TOK_UIDENT
) {
7808 /* NOTE: we only support ranges for last designator */
7809 while (nb_elems
== 1 && (tok
== '[' || tok
== '.')) {
7811 if (!(type
->t
& VT_ARRAY
))
7812 expect("array type");
7814 index
= index_last
= expr_const();
7815 if (tok
== TOK_DOTS
&& gnu_ext
) {
7817 index_last
= expr_const();
7821 decl_design_flex(p
, s
, index_last
);
7822 if (index
< 0 || index_last
>= s
->c
|| index_last
< index
)
7823 tcc_error("index exceeds array bounds or range is empty");
7825 (*cur_field
)->c
= index_last
;
7826 type
= pointed_type(type
);
7827 elem_size
= type_size(type
, &align
);
7828 c
+= index
* elem_size
;
7829 nb_elems
= index_last
- index
+ 1;
7836 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
7837 expect("struct/union type");
7839 f
= find_field(type
, l
, &cumofs
);
7852 } else if (!gnu_ext
) {
7857 if (type
->t
& VT_ARRAY
) {
7858 index
= (*cur_field
)->c
;
7860 decl_design_flex(p
, s
, index
);
7862 tcc_error("too many initializers");
7863 type
= pointed_type(type
);
7864 elem_size
= type_size(type
, &align
);
7865 c
+= index
* elem_size
;
7868 while (f
&& (f
->v
& SYM_FIRST_ANOM
) && (f
->type
.t
& VT_BITFIELD
))
7869 *cur_field
= f
= f
->next
;
7871 tcc_error("too many initializers");
7877 if (!elem_size
) /* for structs */
7878 elem_size
= type_size(type
, &align
);
7880 /* Using designators the same element can be initialized more
7881 than once. In that case we need to delete possibly already
7882 existing relocations. */
7883 if (!(flags
& DIF_SIZE_ONLY
) && c
- corig
< al
) {
7884 decl_design_delrels(p
->sec
, c
, elem_size
* nb_elems
);
7885 flags
&= ~DIF_CLEAR
; /* mark stack dirty too */
7888 decl_initializer(p
, type
, c
, flags
& ~DIF_FIRST
);
7890 if (!(flags
& DIF_SIZE_ONLY
) && nb_elems
> 1) {
7894 if (p
->sec
|| (type
->t
& VT_ARRAY
)) {
7895 /* make init_putv/vstore believe it were a struct */
7897 t1
.t
= VT_STRUCT
, t1
.ref
= &aref
;
7901 vpush_ref(type
, p
->sec
, c
, elem_size
);
7903 vset(type
, VT_LOCAL
|VT_LVAL
, c
);
7904 for (i
= 1; i
< nb_elems
; i
++) {
7906 init_putv(p
, type
, c
+ elem_size
* i
);
7911 c
+= nb_elems
* elem_size
;
7917 /* store a value or an expression directly in global data or in local array */
7918 static void init_putv(init_params
*p
, CType
*type
, unsigned long c
)
7924 Section
*sec
= p
->sec
;
7928 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
7930 size
= type_size(type
, &align
);
7931 if (type
->t
& VT_BITFIELD
)
7932 size
= (BIT_POS(type
->t
) + BIT_SIZE(type
->t
) + 7) / 8;
7933 init_assert(p
, c
+ size
);
7936 /* XXX: not portable */
7937 /* XXX: generate error if incorrect relocation */
7938 gen_assign_cast(&dtype
);
7939 bt
= type
->t
& VT_BTYPE
;
7941 if ((vtop
->r
& VT_SYM
)
7943 && (bt
!= (PTR_SIZE
== 8 ? VT_LLONG
: VT_INT
)
7944 || (type
->t
& VT_BITFIELD
))
7945 && !((vtop
->r
& VT_CONST
) && vtop
->sym
->v
>= SYM_FIRST_ANOM
)
7947 tcc_error("initializer element is not computable at load time");
7949 if (NODATA_WANTED
) {
7954 ptr
= sec
->data
+ c
;
7957 /* XXX: make code faster ? */
7958 if ((vtop
->r
& (VT_SYM
|VT_CONST
)) == (VT_SYM
|VT_CONST
) &&
7959 vtop
->sym
->v
>= SYM_FIRST_ANOM
&&
7960 /* XXX This rejects compound literals like
7961 '(void *){ptr}'. The problem is that '&sym' is
7962 represented the same way, which would be ruled out
7963 by the SYM_FIRST_ANOM check above, but also '"string"'
7964 in 'char *p = "string"' is represented the same
7965 with the type being VT_PTR and the symbol being an
7966 anonymous one. That is, there's no difference in vtop
7967 between '(void *){x}' and '&(void *){x}'. Ignore
7968 pointer typed entities here. Hopefully no real code
7969 will ever use compound literals with scalar type. */
7970 (vtop
->type
.t
& VT_BTYPE
) != VT_PTR
) {
7971 /* These come from compound literals, memcpy stuff over. */
7975 esym
= elfsym(vtop
->sym
);
7976 ssec
= tcc_state
->sections
[esym
->st_shndx
];
7977 memmove (ptr
, ssec
->data
+ esym
->st_value
+ (int)vtop
->c
.i
, size
);
7979 /* We need to copy over all memory contents, and that
7980 includes relocations. Use the fact that relocs are
7981 created it order, so look from the end of relocs
7982 until we hit one before the copied region. */
7983 unsigned long relofs
= ssec
->reloc
->data_offset
;
7984 while (relofs
>= sizeof(*rel
)) {
7985 relofs
-= sizeof(*rel
);
7986 rel
= (ElfW_Rel
*)(ssec
->reloc
->data
+ relofs
);
7987 if (rel
->r_offset
>= esym
->st_value
+ size
)
7989 if (rel
->r_offset
< esym
->st_value
)
7991 put_elf_reloca(symtab_section
, sec
,
7992 c
+ rel
->r_offset
- esym
->st_value
,
7993 ELFW(R_TYPE
)(rel
->r_info
),
7994 ELFW(R_SYM
)(rel
->r_info
),
8004 if (type
->t
& VT_BITFIELD
) {
8005 int bit_pos
, bit_size
, bits
, n
;
8006 unsigned char *p
, v
, m
;
8007 bit_pos
= BIT_POS(vtop
->type
.t
);
8008 bit_size
= BIT_SIZE(vtop
->type
.t
);
8009 p
= (unsigned char*)ptr
+ (bit_pos
>> 3);
8010 bit_pos
&= 7, bits
= 0;
8015 v
= val
>> bits
<< bit_pos
;
8016 m
= ((1 << n
) - 1) << bit_pos
;
8017 *p
= (*p
& ~m
) | (v
& m
);
8018 bits
+= n
, bit_size
-= n
, bit_pos
= 0, ++p
;
8023 *(char *)ptr
= val
!= 0;
8029 write16le(ptr
, val
);
8032 write32le(ptr
, val
);
8035 write64le(ptr
, val
);
8038 #if defined TCC_IS_NATIVE_387
8039 /* Host and target platform may be different but both have x87.
8040 On windows, tcc does not use VT_LDOUBLE, except when it is a
8041 cross compiler. In this case a mingw gcc as host compiler
8042 comes here with 10-byte long doubles, while msvc or tcc won't.
8043 tcc itself can still translate by asm.
8044 In any case we avoid possibly random bytes 11 and 12.
8046 if (sizeof (long double) >= 10)
8047 memcpy(ptr
, &vtop
->c
.ld
, 10);
8049 else if (sizeof (long double) == sizeof (double))
8050 __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr
) : "m" (vtop
->c
.ld
));
8052 else if (vtop
->c
.ld
== 0.0)
8056 /* For other platforms it should work natively, but may not work
8057 for cross compilers */
8058 if (sizeof(long double) == LDOUBLE_SIZE
)
8059 memcpy(ptr
, &vtop
->c
.ld
, LDOUBLE_SIZE
);
8060 else if (sizeof(double) == LDOUBLE_SIZE
)
8061 memcpy(ptr
, &vtop
->c
.ld
, LDOUBLE_SIZE
);
8062 #ifndef TCC_CROSS_TEST
8064 tcc_error("can't cross compile long double constants");
8069 /* intptr_t may need a reloc too, see tcctest.c:relocation_test() */
8072 if (vtop
->r
& VT_SYM
)
8073 greloca(sec
, vtop
->sym
, c
, R_DATA_PTR
, val
);
8075 write64le(ptr
, val
);
8078 write32le(ptr
, val
);
8082 write64le(ptr
, val
);
8086 if (vtop
->r
& VT_SYM
)
8087 greloc(sec
, vtop
->sym
, c
, R_DATA_PTR
);
8088 write32le(ptr
, val
);
8092 //tcc_internal_error("unexpected type");
8098 vset(&dtype
, VT_LOCAL
|VT_LVAL
, c
);
8105 /* 't' contains the type and storage info. 'c' is the offset of the
8106 object in section 'sec'. If 'sec' is NULL, it means stack based
8107 allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi
8108 dimension implicit array init handling). 'flags & DIF_SIZE_ONLY' is true if
8109 size only evaluation is wanted (only for arrays). */
8110 static void decl_initializer(init_params
*p
, CType
*type
, unsigned long c
, int flags
)
8112 int len
, n
, no_oblock
, i
;
8118 /* generate line number info */
8119 if (debug_modes
&& !p
->sec
)
8120 tcc_debug_line(tcc_state
), tcc_tcov_check_line (1);
8122 if (!(flags
& DIF_HAVE_ELEM
) && tok
!= '{' &&
8123 /* In case of strings we have special handling for arrays, so
8124 don't consume them as initializer value (which would commit them
8125 to some anonymous symbol). */
8126 tok
!= TOK_LSTR
&& tok
!= TOK_STR
&&
8127 (!(flags
& DIF_SIZE_ONLY
)
8128 /* a struct may be initialized from a struct of same type, as in
8129 struct {int x,y;} a = {1,2}, b = {3,4}, c[] = {a,b};
8130 In that case we need to parse the element in order to check
8131 it for compatibility below */
8132 || (type
->t
& VT_BTYPE
) == VT_STRUCT
)
8134 int ncw_prev
= nocode_wanted
;
8135 if ((flags
& DIF_SIZE_ONLY
) && !p
->sec
)
8137 parse_init_elem(!p
->sec
? EXPR_ANY
: EXPR_CONST
);
8138 nocode_wanted
= ncw_prev
;
8139 flags
|= DIF_HAVE_ELEM
;
8142 if (type
->t
& VT_ARRAY
) {
8144 if (((flags
& DIF_FIRST
) && tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
8152 t1
= pointed_type(type
);
8153 size1
= type_size(t1
, &align1
);
8155 /* only parse strings here if correct type (otherwise: handle
8156 them as ((w)char *) expressions */
8157 if ((tok
== TOK_LSTR
&&
8158 #ifdef TCC_TARGET_PE
8159 (t1
->t
& VT_BTYPE
) == VT_SHORT
&& (t1
->t
& VT_UNSIGNED
)
8161 (t1
->t
& VT_BTYPE
) == VT_INT
8163 ) || (tok
== TOK_STR
&& (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
8165 cstr_reset(&initstr
);
8166 if (size1
!= (tok
== TOK_STR
? 1 : sizeof(nwchar_t
)))
8167 tcc_error("unhandled string literal merging");
8168 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8170 initstr
.size
-= size1
;
8172 len
+= tokc
.str
.size
;
8174 len
+= tokc
.str
.size
/ sizeof(nwchar_t
);
8176 cstr_cat(&initstr
, tokc
.str
.data
, tokc
.str
.size
);
8179 if (tok
!= ')' && tok
!= '}' && tok
!= ',' && tok
!= ';'
8180 && tok
!= TOK_EOF
) {
8181 /* Not a lone literal but part of a bigger expression. */
8182 unget_tok(size1
== 1 ? TOK_STR
: TOK_LSTR
);
8183 tokc
.str
.size
= initstr
.size
;
8184 tokc
.str
.data
= initstr
.data
;
8188 decl_design_flex(p
, s
, len
);
8189 if (!(flags
& DIF_SIZE_ONLY
)) {
8194 tcc_warning("initializer-string for array is too long");
8195 /* in order to go faster for common case (char
8196 string in global variable, we handle it
8198 if (p
->sec
&& size1
== 1) {
8199 init_assert(p
, c
+ nb
);
8201 memcpy(p
->sec
->data
+ c
, initstr
.data
, nb
);
8205 /* only add trailing zero if enough storage (no
8206 warning in this case since it is standard) */
8207 if (flags
& DIF_CLEAR
)
8210 init_putz(p
, c
+ i
* size1
, (n
- i
) * size1
);
8214 } else if (size1
== 1)
8215 ch
= ((unsigned char *)initstr
.data
)[i
];
8217 ch
= ((nwchar_t
*)initstr
.data
)[i
];
8219 init_putv(p
, t1
, c
+ i
* size1
);
8230 /* zero memory once in advance */
8231 if (!(flags
& (DIF_CLEAR
| DIF_SIZE_ONLY
))) {
8232 init_putz(p
, c
, n
*size1
);
8237 while (tok
!= '}' || (flags
& DIF_HAVE_ELEM
)) {
8238 len
= decl_designator(p
, type
, c
, &f
, flags
, len
);
8239 flags
&= ~DIF_HAVE_ELEM
;
8240 if (type
->t
& VT_ARRAY
) {
8242 /* special test for multi dimensional arrays (may not
8243 be strictly correct if designators are used at the
8245 if (no_oblock
&& len
>= n
*size1
)
8248 if (s
->type
.t
== VT_UNION
)
8252 if (no_oblock
&& f
== NULL
)
8264 } else if ((flags
& DIF_HAVE_ELEM
)
8265 /* Use i_c_parameter_t, to strip toplevel qualifiers.
8266 The source type might have VT_CONSTANT set, which is
8267 of course assignable to non-const elements. */
8268 && is_compatible_unqualified_types(type
, &vtop
->type
)) {
8271 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
) {
8273 if ((flags
& DIF_FIRST
) || tok
== '{') {
8283 } else if (tok
== '{') {
8284 if (flags
& DIF_HAVE_ELEM
)
8287 decl_initializer(p
, type
, c
, flags
& ~DIF_HAVE_ELEM
);
8290 } else one_elem
: if ((flags
& DIF_SIZE_ONLY
)) {
8291 /* If we supported only ISO C we wouldn't have to accept calling
8292 this on anything than an array if DIF_SIZE_ONLY (and even then
8293 only on the outermost level, so no recursion would be needed),
8294 because initializing a flex array member isn't supported.
8295 But GNU C supports it, so we need to recurse even into
8296 subfields of structs and arrays when DIF_SIZE_ONLY is set. */
8297 /* just skip expression */
8298 if (flags
& DIF_HAVE_ELEM
)
8301 skip_or_save_block(NULL
);
8304 if (!(flags
& DIF_HAVE_ELEM
)) {
8305 /* This should happen only when we haven't parsed
8306 the init element above for fear of committing a
8307 string constant to memory too early. */
8308 if (tok
!= TOK_STR
&& tok
!= TOK_LSTR
)
8309 expect("string constant");
8310 parse_init_elem(!p
->sec
? EXPR_ANY
: EXPR_CONST
);
8312 if (!p
->sec
&& (flags
& DIF_CLEAR
) /* container was already zero'd */
8313 && (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
8315 && btype_size(type
->t
& VT_BTYPE
) /* not for fp constants */
8319 init_putv(p
, type
, c
);
8323 /* parse an initializer for type 't' if 'has_init' is non zero, and
8324 allocate space in local or global data space ('r' is either
8325 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
8326 variable 'v' of scope 'scope' is declared before initializers
8327 are parsed. If 'v' is zero, then a reference to the new object
8328 is put in the value stack. If 'has_init' is 2, a special parsing
8329 is done to handle string constants. */
8330 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
8331 int has_init
, int v
, int scope
)
8333 int size
, align
, addr
;
8334 TokenString
*init_str
= NULL
;
8337 Sym
*flexible_array
;
8339 int saved_nocode_wanted
= nocode_wanted
;
8340 #ifdef CONFIG_TCC_BCHECK
8341 int bcheck
= tcc_state
->do_bounds_check
&& !NODATA_WANTED
;
8343 init_params p
= {0};
8345 /* Always allocate static or global variables */
8346 if (v
&& (r
& VT_VALMASK
) == VT_CONST
)
8347 nocode_wanted
|= 0x80000000;
8349 flexible_array
= NULL
;
8350 size
= type_size(type
, &align
);
8352 /* exactly one flexible array may be initialized, either the
8353 toplevel array or the last member of the toplevel struct */
8356 /* If the base type itself was an array type of unspecified size
8357 (like in 'typedef int arr[]; arr x = {1};') then we will
8358 overwrite the unknown size by the real one for this decl.
8359 We need to unshare the ref symbol holding that size. */
8360 type
->ref
= sym_push(SYM_FIELD
, &type
->ref
->type
, 0, type
->ref
->c
);
8361 p
.flex_array_ref
= type
->ref
;
8363 } else if (has_init
&& (type
->t
& VT_BTYPE
) == VT_STRUCT
) {
8364 Sym
*field
= type
->ref
->next
;
8367 field
= field
->next
;
8368 if (field
->type
.t
& VT_ARRAY
&& field
->type
.ref
->c
< 0) {
8369 flexible_array
= field
;
8370 p
.flex_array_ref
= field
->type
.ref
;
8377 /* If unknown size, do a dry-run 1st pass */
8379 tcc_error("unknown type size");
8380 if (has_init
== 2) {
8381 /* only get strings */
8382 init_str
= tok_str_alloc();
8383 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8384 tok_str_add_tok(init_str
);
8387 tok_str_add(init_str
, -1);
8388 tok_str_add(init_str
, 0);
8390 skip_or_save_block(&init_str
);
8394 begin_macro(init_str
, 1);
8396 decl_initializer(&p
, type
, 0, DIF_FIRST
| DIF_SIZE_ONLY
);
8397 /* prepare second initializer parsing */
8398 macro_ptr
= init_str
->str
;
8401 /* if still unknown size, error */
8402 size
= type_size(type
, &align
);
8404 tcc_error("unknown type size");
8406 /* If there's a flex member and it was used in the initializer
8408 if (flexible_array
&& flexible_array
->type
.ref
->c
> 0)
8409 size
+= flexible_array
->type
.ref
->c
8410 * pointed_size(&flexible_array
->type
);
8413 /* take into account specified alignment if bigger */
8414 if (ad
->a
.aligned
) {
8415 int speca
= 1 << (ad
->a
.aligned
- 1);
8418 } else if (ad
->a
.packed
) {
8422 if (!v
&& NODATA_WANTED
)
8423 size
= 0, align
= 1;
8425 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
8427 #ifdef CONFIG_TCC_BCHECK
8429 /* add padding between stack variables for bound checking */
8433 loc
= (loc
- size
) & -align
;
8435 p
.local_offset
= addr
+ size
;
8436 #ifdef CONFIG_TCC_BCHECK
8438 /* add padding between stack variables for bound checking */
8443 /* local variable */
8444 #ifdef CONFIG_TCC_ASM
8445 if (ad
->asm_label
) {
8446 int reg
= asm_parse_regvar(ad
->asm_label
);
8448 r
= (r
& ~VT_VALMASK
) | reg
;
8451 sym
= sym_push(v
, type
, r
, addr
);
8452 if (ad
->cleanup_func
) {
8453 Sym
*cls
= sym_push2(&all_cleanups
,
8454 SYM_FIELD
| ++cur_scope
->cl
.n
, 0, 0);
8455 cls
->prev_tok
= sym
;
8456 cls
->next
= ad
->cleanup_func
;
8457 cls
->ncl
= cur_scope
->cl
.s
;
8458 cur_scope
->cl
.s
= cls
;
8463 /* push local reference */
8464 vset(type
, r
, addr
);
8468 if (v
&& scope
== VT_CONST
) {
8469 /* see if the symbol was already defined */
8472 if (p
.flex_array_ref
&& (sym
->type
.t
& type
->t
& VT_ARRAY
)
8473 && sym
->type
.ref
->c
> type
->ref
->c
) {
8474 /* flex array was already declared with explicit size
8476 int arr[] = { 1,2,3 }; */
8477 type
->ref
->c
= sym
->type
.ref
->c
;
8478 size
= type_size(type
, &align
);
8480 patch_storage(sym
, ad
, type
);
8481 /* we accept several definitions of the same global variable. */
8482 if (!has_init
&& sym
->c
&& elfsym(sym
)->st_shndx
!= SHN_UNDEF
)
8487 /* allocate symbol in corresponding section */
8491 while ((tp
->t
& (VT_BTYPE
|VT_ARRAY
)) == (VT_PTR
|VT_ARRAY
))
8492 tp
= &tp
->ref
->type
;
8493 if (tp
->t
& VT_CONSTANT
) {
8494 sec
= rodata_section
;
8495 } else if (has_init
) {
8497 /*if (tcc_state->g_debug & 4)
8498 tcc_warning("rw data: %s", get_tok_str(v, 0));*/
8499 } else if (tcc_state
->nocommon
)
8504 addr
= section_add(sec
, size
, align
);
8505 #ifdef CONFIG_TCC_BCHECK
8506 /* add padding if bound check */
8508 section_add(sec
, 1, 1);
8511 addr
= align
; /* SHN_COMMON is special, symbol value is align */
8512 sec
= common_section
;
8517 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
8518 patch_storage(sym
, ad
, NULL
);
8520 /* update symbol definition */
8521 put_extern_sym(sym
, sec
, addr
, size
);
8523 /* push global reference */
8524 vpush_ref(type
, sec
, addr
, size
);
8529 #ifdef CONFIG_TCC_BCHECK
8530 /* handles bounds now because the symbol must be defined
8531 before for the relocation */
8535 greloca(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_PTR
, 0);
8536 /* then add global bound info */
8537 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(addr_t
));
8538 bounds_ptr
[0] = 0; /* relocated */
8539 bounds_ptr
[1] = size
;
8544 if (type
->t
& VT_VLA
) {
8550 /* save before-VLA stack pointer if needed */
8551 if (cur_scope
->vla
.num
== 0) {
8552 if (cur_scope
->prev
&& cur_scope
->prev
->vla
.num
) {
8553 cur_scope
->vla
.locorig
= cur_scope
->prev
->vla
.loc
;
8555 gen_vla_sp_save(loc
-= PTR_SIZE
);
8556 cur_scope
->vla
.locorig
= loc
;
8560 vpush_type_size(type
, &a
);
8561 gen_vla_alloc(type
, a
);
8562 #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
8563 /* on _WIN64, because of the function args scratch area, the
8564 result of alloca differs from RSP and is returned in RAX. */
8565 gen_vla_result(addr
), addr
= (loc
-= PTR_SIZE
);
8567 gen_vla_sp_save(addr
);
8568 cur_scope
->vla
.loc
= addr
;
8569 cur_scope
->vla
.num
++;
8570 } else if (has_init
) {
8572 decl_initializer(&p
, type
, addr
, DIF_FIRST
);
8573 /* patch flexible array member size back to -1, */
8574 /* for possible subsequent similar declarations */
8576 flexible_array
->type
.ref
->c
= -1;
8580 /* restore parse state if needed */
8586 nocode_wanted
= saved_nocode_wanted
;
8589 /* parse a function defined by symbol 'sym' and generate its code in
8590 'cur_text_section' */
8591 static void gen_function(Sym
*sym
)
8593 struct scope f
= { 0 };
8594 cur_scope
= root_scope
= &f
;
8596 ind
= cur_text_section
->data_offset
;
8597 if (sym
->a
.aligned
) {
8598 size_t newoff
= section_add(cur_text_section
, 0,
8599 1 << (sym
->a
.aligned
- 1));
8600 gen_fill_nops(newoff
- ind
);
8602 /* NOTE: we patch the symbol size later */
8603 put_extern_sym(sym
, cur_text_section
, ind
, 0);
8604 if (sym
->type
.ref
->f
.func_ctor
)
8605 add_array (tcc_state
, ".init_array", sym
->c
);
8606 if (sym
->type
.ref
->f
.func_dtor
)
8607 add_array (tcc_state
, ".fini_array", sym
->c
);
8609 funcname
= get_tok_str(sym
->v
, NULL
);
8611 func_vt
= sym
->type
.ref
->type
;
8612 func_var
= sym
->type
.ref
->f
.func_type
== FUNC_ELLIPSIS
;
8614 /* put debug symbol */
8615 tcc_debug_funcstart(tcc_state
, sym
);
8616 /* push a dummy symbol to enable local sym storage */
8617 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
8618 local_scope
= 1; /* for function parameters */
8622 clear_temp_local_var_list();
8626 /* reset local stack */
8627 pop_local_syms(NULL
, 0);
8629 cur_text_section
->data_offset
= ind
;
8631 label_pop(&global_label_stack
, NULL
, 0);
8632 sym_pop(&all_cleanups
, NULL
, 0);
8633 /* patch symbol size */
8634 elfsym(sym
)->st_size
= ind
- func_ind
;
8635 /* end of function */
8636 tcc_debug_funcend(tcc_state
, ind
- func_ind
);
8637 /* It's better to crash than to generate wrong code */
8638 cur_text_section
= NULL
;
8639 funcname
= ""; /* for safety */
8640 func_vt
.t
= VT_VOID
; /* for safety */
8641 func_var
= 0; /* for safety */
8642 ind
= 0; /* for safety */
8643 nocode_wanted
= 0x80000000;
8645 /* do this after funcend debug info */
8649 static void gen_inline_functions(TCCState
*s
)
8652 int inline_generated
, i
;
8653 struct InlineFunc
*fn
;
8655 tcc_open_bf(s
, ":inline:", 0);
8656 /* iterate while inline function are referenced */
8658 inline_generated
= 0;
8659 for (i
= 0; i
< s
->nb_inline_fns
; ++i
) {
8660 fn
= s
->inline_fns
[i
];
8662 if (sym
&& (sym
->c
|| !(sym
->type
.t
& VT_INLINE
))) {
8663 /* the function was used or forced (and then not internal):
8664 generate its code and convert it to a normal function */
8666 tcc_debug_putfile(s
, fn
->filename
);
8667 begin_macro(fn
->func_str
, 1);
8669 cur_text_section
= text_section
;
8673 inline_generated
= 1;
8676 } while (inline_generated
);
8680 static void free_inline_functions(TCCState
*s
)
8683 /* free tokens of unused inline functions */
8684 for (i
= 0; i
< s
->nb_inline_fns
; ++i
) {
8685 struct InlineFunc
*fn
= s
->inline_fns
[i
];
8687 tok_str_free(fn
->func_str
);
8689 dynarray_reset(&s
->inline_fns
, &s
->nb_inline_fns
);
8692 /* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
8693 if parsing old style parameter decl list (and FUNC_SYM is set then) */
8694 static int decl0(int l
, int is_for_loop_init
, Sym
*func_sym
)
8696 int v
, has_init
, r
, oldint
;
8699 AttributeDef ad
, adbase
;
8702 if (tok
== TOK_STATIC_ASSERT
) {
8712 tcc_error("_Static_assert fail");
8714 goto static_assert_out
;
8718 parse_mult_str(&error_str
, "string constant");
8720 tcc_error("%s", (char *)error_str
.data
);
8721 cstr_free(&error_str
);
8729 if (!parse_btype(&btype
, &adbase
)) {
8730 if (is_for_loop_init
)
8732 /* skip redundant ';' if not in old parameter decl scope */
8733 if (tok
== ';' && l
!= VT_CMP
) {
8739 if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
8740 /* global asm block */
8744 if (tok
>= TOK_UIDENT
) {
8745 /* special test for old K&R protos without explicit int
8746 type. Only accepted when defining global data */
8751 expect("declaration");
8757 if ((btype
.t
& VT_BTYPE
) == VT_STRUCT
) {
8759 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
)
8760 tcc_warning("unnamed struct/union that defines no instances");
8764 if (IS_ENUM(btype
.t
)) {
8770 while (1) { /* iterate thru each declaration */
8773 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8777 type_to_str(buf
, sizeof(buf
), &type
, get_tok_str(v
, NULL
));
8778 printf("type = '%s'\n", buf
);
8781 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8782 if ((type
.t
& VT_STATIC
) && (l
== VT_LOCAL
))
8783 tcc_error("function without file scope cannot be static");
8784 /* if old style function prototype, we accept a
8787 if (sym
->f
.func_type
== FUNC_OLD
&& l
== VT_CONST
)
8788 decl0(VT_CMP
, 0, sym
);
8789 #ifdef TCC_TARGET_MACHO
8790 if (sym
->f
.func_alwinl
8791 && ((type
.t
& (VT_EXTERN
| VT_INLINE
))
8792 == (VT_EXTERN
| VT_INLINE
))) {
8793 /* always_inline functions must be handled as if they
8794 don't generate multiple global defs, even if extern
8795 inline, i.e. GNU inline semantics for those. Rewrite
8796 them into static inline. */
8797 type
.t
&= ~VT_EXTERN
;
8798 type
.t
|= VT_STATIC
;
8801 /* always compile 'extern inline' */
8802 if (type
.t
& VT_EXTERN
)
8803 type
.t
&= ~VT_INLINE
;
8805 } else if (oldint
) {
8806 tcc_warning("type defaults to int");
8809 if (gnu_ext
&& (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
8810 ad
.asm_label
= asm_label_instr();
8811 /* parse one last attribute list, after asm label */
8812 parse_attribute(&ad
);
8814 /* gcc does not allow __asm__("label") with function definition,
8821 #ifdef TCC_TARGET_PE
8822 if (ad
.a
.dllimport
|| ad
.a
.dllexport
) {
8823 if (type
.t
& VT_STATIC
)
8824 tcc_error("cannot have dll linkage with static");
8825 if (type
.t
& VT_TYPEDEF
) {
8826 tcc_warning("'%s' attribute ignored for typedef",
8827 ad
.a
.dllimport
? (ad
.a
.dllimport
= 0, "dllimport") :
8828 (ad
.a
.dllexport
= 0, "dllexport"));
8829 } else if (ad
.a
.dllimport
) {
8830 if ((type
.t
& VT_BTYPE
) == VT_FUNC
)
8833 type
.t
|= VT_EXTERN
;
8839 tcc_error("cannot use local functions");
8840 if ((type
.t
& VT_BTYPE
) != VT_FUNC
)
8841 expect("function definition");
8843 /* reject abstract declarators in function definition
8844 make old style params without decl have int type */
8846 while ((sym
= sym
->next
) != NULL
) {
8847 if (!(sym
->v
& ~SYM_FIELD
))
8848 expect("identifier");
8849 if (sym
->type
.t
== VT_VOID
)
8850 sym
->type
= int_type
;
8853 /* apply post-declaraton attributes */
8854 merge_funcattr(&type
.ref
->f
, &ad
.f
);
8856 /* put function symbol */
8857 type
.t
&= ~VT_EXTERN
;
8858 sym
= external_sym(v
, &type
, 0, &ad
);
8860 /* static inline functions are just recorded as a kind
8861 of macro. Their code will be emitted at the end of
8862 the compilation unit only if they are used */
8863 if (sym
->type
.t
& VT_INLINE
) {
8864 struct InlineFunc
*fn
;
8865 fn
= tcc_malloc(sizeof *fn
+ strlen(file
->filename
));
8866 strcpy(fn
->filename
, file
->filename
);
8868 skip_or_save_block(&fn
->func_str
);
8869 dynarray_add(&tcc_state
->inline_fns
,
8870 &tcc_state
->nb_inline_fns
, fn
);
8872 /* compute text section */
8873 cur_text_section
= ad
.section
;
8874 if (!cur_text_section
)
8875 cur_text_section
= text_section
;
8881 /* find parameter in function parameter list */
8882 for (sym
= func_sym
->next
; sym
; sym
= sym
->next
)
8883 if ((sym
->v
& ~SYM_FIELD
) == v
)
8885 tcc_error("declaration for parameter '%s' but no such parameter",
8886 get_tok_str(v
, NULL
));
8888 if (type
.t
& VT_STORAGE
) /* 'register' is okay */
8889 tcc_error("storage class specified for '%s'",
8890 get_tok_str(v
, NULL
));
8891 if (sym
->type
.t
!= VT_VOID
)
8892 tcc_error("redefinition of parameter '%s'",
8893 get_tok_str(v
, NULL
));
8894 convert_parameter_type(&type
);
8896 } else if (type
.t
& VT_TYPEDEF
) {
8897 /* save typedefed type */
8898 /* XXX: test storage specifiers ? */
8900 if (sym
&& sym
->sym_scope
== local_scope
) {
8901 if (!is_compatible_types(&sym
->type
, &type
)
8902 || !(sym
->type
.t
& VT_TYPEDEF
))
8903 tcc_error("incompatible redefinition of '%s'",
8904 get_tok_str(v
, NULL
));
8907 sym
= sym_push(v
, &type
, 0, 0);
8912 tcc_debug_typedef (tcc_state
, sym
);
8913 } else if ((type
.t
& VT_BTYPE
) == VT_VOID
8914 && !(type
.t
& VT_EXTERN
)) {
8915 tcc_error("declaration of void object");
8918 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8919 /* external function definition */
8920 /* specific case for func_call attribute */
8922 } else if (!(type
.t
& VT_ARRAY
)) {
8923 /* not lvalue if array */
8926 has_init
= (tok
== '=');
8927 if (has_init
&& (type
.t
& VT_VLA
))
8928 tcc_error("variable length array cannot be initialized");
8929 if (((type
.t
& VT_EXTERN
) && (!has_init
|| l
!= VT_CONST
))
8930 || (type
.t
& VT_BTYPE
) == VT_FUNC
8931 /* as with GCC, uninitialized global arrays with no size
8932 are considered extern: */
8933 || ((type
.t
& VT_ARRAY
) && !has_init
8934 && l
== VT_CONST
&& type
.ref
->c
< 0)
8936 /* external variable or function */
8937 type
.t
|= VT_EXTERN
;
8938 sym
= external_sym(v
, &type
, r
, &ad
);
8939 if (ad
.alias_target
) {
8940 /* Aliases need to be emitted when their target
8941 symbol is emitted, even if perhaps unreferenced.
8942 We only support the case where the base is
8943 already defined, otherwise we would need
8944 deferring to emit the aliases until the end of
8945 the compile unit. */
8946 Sym
*alias_target
= sym_find(ad
.alias_target
);
8947 ElfSym
*esym
= elfsym(alias_target
);
8949 tcc_error("unsupported forward __alias__ attribute");
8950 put_extern_sym2(sym
, esym
->st_shndx
,
8951 esym
->st_value
, esym
->st_size
, 1);
8954 if (type
.t
& VT_STATIC
)
8960 else if (l
== VT_CONST
)
8961 /* uninitialized global variables may be overridden */
8962 type
.t
|= VT_EXTERN
;
8963 decl_initializer_alloc(&type
, &ad
, r
, has_init
, v
, l
);
8967 if (is_for_loop_init
)
8979 static void decl(int l
)
8984 /* ------------------------------------------------------------------------- */
8987 /* ------------------------------------------------------------------------- */