2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /********************************************************/
25 /* global variables */
27 /* loc : local variable index
28 ind : output code index
30 anon_sym: anonymous symbol index
32 ST_DATA
int rsym
, anon_sym
, ind
, loc
;
34 ST_DATA Sym
*global_stack
;
35 ST_DATA Sym
*local_stack
;
36 ST_DATA Sym
*define_stack
;
37 ST_DATA Sym
*global_label_stack
;
38 ST_DATA Sym
*local_label_stack
;
40 static Sym
*sym_free_first
;
41 static void **sym_pools
;
42 static int nb_sym_pools
;
44 static Sym
*all_cleanups
, *pending_gotos
;
45 static int local_scope
;
47 static int in_generic
;
48 static int section_sym
;
51 static SValue _vstack
[1 + VSTACK_SIZE
];
52 #define vstack (_vstack + 1)
54 ST_DATA
int const_wanted
; /* true if constant wanted */
55 ST_DATA
int nocode_wanted
; /* no code generation wanted */
56 #define unevalmask 0xffff /* unevaluated subexpression */
57 #define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
58 #define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */
60 /* Automagical code suppression ----> */
61 #define CODE_OFF() (nocode_wanted |= 0x20000000)
62 #define CODE_ON() (nocode_wanted &= ~0x20000000)
64 /* Clear 'nocode_wanted' at label if it was used */
65 ST_FUNC
void gsym(int t
) { if (t
) { gsym_addr(t
, ind
); CODE_ON(); }}
66 static int gind(void) { CODE_ON(); return ind
; }
68 /* Set 'nocode_wanted' after unconditional jumps */
69 static void gjmp_addr_acs(int t
) { gjmp_addr(t
); CODE_OFF(); }
70 static int gjmp_acs(int t
) { t
= gjmp(t
); CODE_OFF(); return t
; }
72 /* These are #undef'd at the end of this file */
73 #define gjmp_addr gjmp_addr_acs
77 ST_DATA
int global_expr
; /* true if compound literals must be allocated globally (used during initializers parsing */
78 ST_DATA CType func_vt
; /* current function return type (used by return instruction) */
79 ST_DATA
int func_var
; /* true if current function is variadic (used by return instruction) */
81 static int last_line_num
, new_file
, func_ind
; /* debug info control */
82 ST_DATA
const char *funcname
;
83 ST_DATA CType int_type
, func_old_type
, char_type
, char_pointer_type
;
84 static CString initstr
;
87 #define VT_SIZE_T (VT_INT | VT_UNSIGNED)
88 #define VT_PTRDIFF_T VT_INT
90 #define VT_SIZE_T (VT_LLONG | VT_UNSIGNED)
91 #define VT_PTRDIFF_T VT_LLONG
93 #define VT_SIZE_T (VT_LONG | VT_LLONG | VT_UNSIGNED)
94 #define VT_PTRDIFF_T (VT_LONG | VT_LLONG)
97 ST_DATA
struct switch_t
{
101 } **p
; int n
; /* list of case ranges */
102 int def_sym
; /* default symbol */
105 struct switch_t
*prev
;
107 } *cur_switch
; /* current switch */
109 #define MAX_TEMP_LOCAL_VARIABLE_NUMBER 8
110 /*list of temporary local variables on the stack in current function. */
111 ST_DATA
struct temp_local_variable
{
112 int location
; //offset on stack. Svalue.c.i
115 } arr_temp_local_vars
[MAX_TEMP_LOCAL_VARIABLE_NUMBER
];
116 short nb_temp_local_vars
;
118 static struct scope
{
120 struct { int loc
, num
; } vla
;
121 struct { Sym
*s
; int n
; } cl
;
124 } *cur_scope
, *loop_scope
, *root_scope
;
132 /********************************************************/
133 /* stab debug support */
135 static const struct {
138 } default_debug
[] = {
139 { VT_INT
, "int:t1=r1;-2147483648;2147483647;" },
140 { VT_BYTE
, "char:t2=r2;0;127;" },
142 { VT_LONG
| VT_INT
, "long int:t3=r3;-2147483648;2147483647;" },
144 { VT_LLONG
| VT_LONG
, "long int:t3=r3;-9223372036854775808;9223372036854775807;" },
146 { VT_INT
| VT_UNSIGNED
, "unsigned int:t4=r4;0;037777777777;" },
148 { VT_LONG
| VT_INT
| VT_UNSIGNED
, "long unsigned int:t5=r5;0;037777777777;" },
150 /* use octal instead of -1 so size_t works (-gstabs+ in gcc) */
151 { VT_LLONG
| VT_LONG
| VT_UNSIGNED
, "long unsigned int:t5=r5;0;01777777777777777777777;" },
153 { VT_QLONG
, "__int128:t6=r6;0;-1;" },
154 { VT_QLONG
| VT_UNSIGNED
, "__int128 unsigned:t7=r7;0;-1;" },
155 { VT_LLONG
, "long long int:t8=r8;-9223372036854775808;9223372036854775807;" },
156 { VT_LLONG
| VT_UNSIGNED
, "long long unsigned int:t9=r9;0;01777777777777777777777;" },
157 { VT_SHORT
, "short int:t10=r10;-32768;32767;" },
158 { VT_SHORT
| VT_UNSIGNED
, "short unsigned int:t11=r11;0;65535;" },
159 { VT_BYTE
| VT_DEFSIGN
, "signed char:t12=r12;-128;127;" },
160 { VT_BYTE
| VT_DEFSIGN
| VT_UNSIGNED
, "unsigned char:t13=r13;0;255;" },
161 { VT_FLOAT
, "float:t14=r1;4;0;" },
162 { VT_DOUBLE
, "double:t15=r1;8;0;" },
163 #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
164 { VT_DOUBLE
| VT_LONG
, "long double:t16=r1;8;0;" },
166 { VT_LDOUBLE
, "long double:t16=r1;16;0;" },
168 { -1, "_Float32:t17=r1;4;0;" },
169 { -1, "_Float64:t18=r1;8;0;" },
170 { -1, "_Float128:t19=r1;16;0;" },
171 { -1, "_Float32x:t20=r1;8;0;" },
172 { -1, "_Float64x:t21=r1;16;0;" },
173 { -1, "_Decimal32:t22=r1;4;0;" },
174 { -1, "_Decimal64:t23=r1;8;0;" },
175 { -1, "_Decimal128:t24=r1;16;0;" },
176 /* if default char is unsigned */
177 { VT_BYTE
| VT_UNSIGNED
, "unsigned char:t25=r25;0;255;" },
179 { VT_BOOL
, "bool:t26=r26;0;255;" },
180 { VT_VOID
, "void:t27=27" },
183 static int debug_next_type
;
185 static struct debug_hash
{
190 static int n_debug_hash
;
192 static struct debug_info
{
203 struct debug_info
*child
, *next
, *last
, *parent
;
204 } *debug_info
, *debug_info_root
;
206 /********************************************************/
208 #define precedence_parser
209 static void init_prec(void);
211 /********************************************************/
212 #ifndef CONFIG_TCC_ASM
213 ST_FUNC
void asm_instr(void)
215 tcc_error("inline asm() not supported");
217 ST_FUNC
void asm_global_instr(void)
219 tcc_error("inline asm() not supported");
223 /* ------------------------------------------------------------------------- */
224 static void gen_cast(CType
*type
);
225 static void gen_cast_s(int t
);
226 static inline CType
*pointed_type(CType
*type
);
227 static int is_compatible_types(CType
*type1
, CType
*type2
);
228 static int parse_btype(CType
*type
, AttributeDef
*ad
);
229 static CType
*type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
230 static void parse_expr_type(CType
*type
);
231 static void init_putv(init_params
*p
, CType
*type
, unsigned long c
);
232 static void decl_initializer(init_params
*p
, CType
*type
, unsigned long c
, int flags
);
233 static void block(int is_expr
);
234 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
, int has_init
, int v
, int scope
);
235 static void decl(int l
);
236 static int decl0(int l
, int is_for_loop_init
, Sym
*);
237 static void expr_eq(void);
238 static void vla_runtime_type_size(CType
*type
, int *a
);
239 static int is_compatible_unqualified_types(CType
*type1
, CType
*type2
);
240 static inline int64_t expr_const64(void);
241 static void vpush64(int ty
, unsigned long long v
);
242 static void vpush(CType
*type
);
243 static int gvtst(int inv
, int t
);
244 static void gen_inline_functions(TCCState
*s
);
245 static void free_inline_functions(TCCState
*s
);
246 static void skip_or_save_block(TokenString
**str
);
247 static void gv_dup(void);
248 static int get_temp_local_var(int size
,int align
);
249 static void clear_temp_local_var_list();
250 static void cast_error(CType
*st
, CType
*dt
);
252 ST_INLN
int is_float(int t
)
254 int bt
= t
& VT_BTYPE
;
255 return bt
== VT_LDOUBLE
261 static inline int is_integer_btype(int bt
)
270 static int btype_size(int bt
)
272 return bt
== VT_BYTE
|| bt
== VT_BOOL
? 1 :
276 bt
== VT_PTR
? PTR_SIZE
: 0;
279 /* returns function return register from type */
280 static int R_RET(int t
)
284 #ifdef TCC_TARGET_X86_64
285 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
287 #elif defined TCC_TARGET_RISCV64
288 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
294 /* returns 2nd function return register, if any */
295 static int R2_RET(int t
)
301 #elif defined TCC_TARGET_X86_64
306 #elif defined TCC_TARGET_RISCV64
313 /* returns true for two-word types */
314 #define USING_TWO_WORDS(t) (R2_RET(t) != VT_CONST)
316 /* put function return registers to stack value */
317 static void PUT_R_RET(SValue
*sv
, int t
)
319 sv
->r
= R_RET(t
), sv
->r2
= R2_RET(t
);
322 /* returns function return register class for type t */
323 static int RC_RET(int t
)
325 return reg_classes
[R_RET(t
)] & ~(RC_FLOAT
| RC_INT
);
328 /* returns generic register class for type t */
329 static int RC_TYPE(int t
)
333 #ifdef TCC_TARGET_X86_64
334 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
336 if ((t
& VT_BTYPE
) == VT_QFLOAT
)
338 #elif defined TCC_TARGET_RISCV64
339 if ((t
& VT_BTYPE
) == VT_LDOUBLE
)
345 /* returns 2nd register class corresponding to t and rc */
346 static int RC2_TYPE(int t
, int rc
)
348 if (!USING_TWO_WORDS(t
))
363 /* we use our own 'finite' function to avoid potential problems with
364 non standard math libs */
365 /* XXX: endianness dependent */
366 ST_FUNC
int ieee_finite(double d
)
369 memcpy(p
, &d
, sizeof(double));
370 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
373 /* compiling intel long double natively */
374 #if (defined __i386__ || defined __x86_64__) \
375 && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
376 # define TCC_IS_NATIVE_387
379 ST_FUNC
void test_lvalue(void)
381 if (!(vtop
->r
& VT_LVAL
))
385 ST_FUNC
void check_vstack(void)
387 if (vtop
!= vstack
- 1)
388 tcc_error("internal compiler error: vstack leak (%d)",
389 (int)(vtop
- vstack
+ 1));
392 /* ------------------------------------------------------------------------- */
393 /* vstack debugging aid */
396 void pv (const char *lbl
, int a
, int b
)
399 for (i
= a
; i
< a
+ b
; ++i
) {
400 SValue
*p
= &vtop
[-i
];
401 printf("%s vtop[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n",
402 lbl
, i
, p
->type
.t
, p
->r
, p
->r2
, (int)p
->c
.i
);
407 /* ------------------------------------------------------------------------- */
408 /* start of translation unit info */
409 ST_FUNC
void tcc_debug_start(TCCState
*s1
)
415 /* file info: full path + filename */
416 section_sym
= put_elf_sym(symtab_section
, 0, 0,
417 ELFW(ST_INFO
)(STB_LOCAL
, STT_SECTION
), 0,
418 text_section
->sh_num
, NULL
);
419 getcwd(buf
, sizeof(buf
));
421 normalize_slashes(buf
);
423 pstrcat(buf
, sizeof(buf
), "/");
424 put_stabs_r(s1
, buf
, N_SO
, 0, 0,
425 text_section
->data_offset
, text_section
, section_sym
);
426 put_stabs_r(s1
, file
->prev
? file
->prev
->filename
: file
->filename
,
428 text_section
->data_offset
, text_section
, section_sym
);
429 for (i
= 0; i
< sizeof (default_debug
) / sizeof (default_debug
[0]); i
++)
430 put_stabs(s1
, default_debug
[i
].name
, N_LSYM
, 0, 0, 0);
432 new_file
= last_line_num
= 0;
434 debug_next_type
= sizeof(default_debug
) / sizeof(default_debug
[0]);
438 /* we're currently 'including' the <command line> */
442 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
443 symbols can be safely used */
444 put_elf_sym(symtab_section
, 0, 0,
445 ELFW(ST_INFO
)(STB_LOCAL
, STT_FILE
), 0,
446 SHN_ABS
, file
->filename
);
449 static void tcc_debug_stabs (TCCState
*s1
, const char *str
, int type
, unsigned long value
,
450 Section
*sec
, int sym_index
)
456 (struct debug_sym
*)tcc_realloc (debug_info
->sym
,
457 sizeof(struct debug_sym
) *
458 (debug_info
->n_sym
+ 1));
459 s
= debug_info
->sym
+ debug_info
->n_sym
++;
462 s
->str
= tcc_strdup(str
);
464 s
->sym_index
= sym_index
;
467 put_stabs_r (s1
, str
, type
, 0, 0, value
, sec
, sym_index
);
469 put_stabs (s1
, str
, type
, 0, 0, value
);
472 static void tcc_debug_stabn(int type
, int value
)
474 if (type
== N_LBRAC
) {
475 struct debug_info
*info
=
476 (struct debug_info
*) tcc_mallocz(sizeof (*info
));
479 info
->parent
= debug_info
;
481 if (debug_info
->child
) {
482 if (debug_info
->child
->last
)
483 debug_info
->child
->last
->next
= info
;
485 debug_info
->child
->next
= info
;
486 debug_info
->child
->last
= info
;
489 debug_info
->child
= info
;
492 debug_info_root
= info
;
496 debug_info
->end
= value
;
497 debug_info
= debug_info
->parent
;
501 static void tcc_get_debug_info(TCCState
*s1
, Sym
*s
, CString
*result
)
510 type
= t
->type
.t
& ~(VT_STORAGE
| VT_CONSTANT
| VT_VOLATILE
);
511 if ((type
& VT_BTYPE
) != VT_BYTE
)
513 if (type
== VT_PTR
|| type
== (VT_PTR
| VT_ARRAY
))
514 n
++, t
= t
->type
.ref
;
518 if ((type
& VT_BTYPE
) == VT_STRUCT
) {
522 for (i
= 0; i
< n_debug_hash
; i
++) {
523 if (t
== debug_hash
[i
].type
) {
524 debug_type
= debug_hash
[i
].debug_type
;
528 if (debug_type
== -1) {
529 debug_type
= ++debug_next_type
;
530 debug_hash
= (struct debug_hash
*)
531 tcc_realloc (debug_hash
,
532 (n_debug_hash
+ 1) * sizeof(*debug_hash
));
533 debug_hash
[n_debug_hash
].debug_type
= debug_type
;
534 debug_hash
[n_debug_hash
++].type
= t
;
536 cstr_printf (&str
, "%s:T%d=%c%d",
537 (t
->v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
538 ? "" : get_tok_str(t
->v
& ~SYM_STRUCT
, NULL
),
540 IS_UNION (t
->type
.t
) ? 'u' : 's',
543 int pos
, size
, align
;
546 cstr_printf (&str
, "%s:",
547 (t
->v
& ~SYM_FIELD
) >= SYM_FIRST_ANOM
548 ? "" : get_tok_str(t
->v
& ~SYM_FIELD
, NULL
));
549 tcc_get_debug_info (s1
, t
, &str
);
550 if (t
->type
.t
& VT_BITFIELD
) {
551 pos
= t
->c
* 8 + BIT_POS(t
->type
.t
);
552 size
= BIT_SIZE(t
->type
.t
);
556 size
= type_size(&t
->type
, &align
) * 8;
558 cstr_printf (&str
, ",%d,%d;", pos
, size
);
560 cstr_printf (&str
, ";");
561 tcc_debug_stabs(s1
, str
.data
, N_LSYM
, 0, NULL
, 0);
565 else if (IS_ENUM(type
)) {
566 Sym
*e
= t
= t
->type
.ref
;
568 debug_type
= ++debug_next_type
;
570 cstr_printf (&str
, "%s:T%d=e",
571 (t
->v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
572 ? "" : get_tok_str(t
->v
& ~SYM_STRUCT
, NULL
),
576 cstr_printf (&str
, "%s:",
577 (t
->v
& ~SYM_FIELD
) >= SYM_FIRST_ANOM
578 ? "" : get_tok_str(t
->v
& ~SYM_FIELD
, NULL
));
579 cstr_printf (&str
, e
->type
.t
& VT_UNSIGNED
? "%u," : "%d,",
582 cstr_printf (&str
, ";");
583 tcc_debug_stabs(s1
, str
.data
, N_LSYM
, 0, NULL
, 0);
586 else if ((type
& VT_BTYPE
) != VT_FUNC
) {
587 type
&= ~VT_STRUCT_MASK
;
589 debug_type
<= sizeof(default_debug
) / sizeof(default_debug
[0]);
591 if (default_debug
[debug_type
- 1].type
== type
)
593 if (debug_type
> sizeof(default_debug
) / sizeof(default_debug
[0]))
597 cstr_printf (result
, "%d=", ++debug_next_type
);
600 type
= t
->type
.t
& ~(VT_STORAGE
| VT_CONSTANT
| VT_VOLATILE
);
601 if ((type
& VT_BTYPE
) != VT_BYTE
)
604 cstr_printf (result
, "%d=*", ++debug_next_type
);
605 else if (type
== (VT_PTR
| VT_ARRAY
))
606 cstr_printf (result
, "%d=ar1;0;%d;",
607 ++debug_next_type
, t
->type
.ref
->c
- 1);
608 else if (type
== VT_FUNC
) {
609 cstr_printf (result
, "%d=f", ++debug_next_type
);
610 tcc_get_debug_info (s1
, t
->type
.ref
, result
);
617 cstr_printf (result
, "%d", debug_type
);
620 static void tcc_debug_finish (TCCState
*s1
, struct debug_info
*cur
)
624 struct debug_info
*next
= cur
->next
;
626 for (i
= 0; i
< cur
->n_sym
; i
++) {
627 struct debug_sym
*s
= &cur
->sym
[i
];
630 put_stabs_r(s1
, s
->str
, s
->type
, 0, 0, s
->value
,
631 s
->sec
, s
->sym_index
);
633 put_stabs(s1
, s
->str
, s
->type
, 0, 0, s
->value
);
637 put_stabn(s1
, N_LBRAC
, 0, 0, cur
->start
);
638 tcc_debug_finish (s1
, cur
->child
);
639 put_stabn(s1
, N_RBRAC
, 0, 0, cur
->end
);
645 static void tcc_add_debug_info(TCCState
*s1
, int param
, Sym
*s
, Sym
*e
)
648 cstr_new (&debug_str
);
649 for (; s
!= e
; s
= s
->prev
) {
650 if (!s
->v
|| (s
->r
& VT_VALMASK
) != VT_LOCAL
)
652 cstr_reset (&debug_str
);
653 cstr_printf (&debug_str
, "%s:%s", get_tok_str(s
->v
, NULL
), param
? "p" : "");
654 tcc_get_debug_info(s1
, s
, &debug_str
);
655 tcc_debug_stabs(s1
, debug_str
.data
, param
? N_PSYM
: N_LSYM
, s
->c
, NULL
, 0);
657 cstr_free (&debug_str
);
660 static void tcc_debug_extern_sym(TCCState
*s1
, Sym
*sym
, int sh_num
, int sym_bind
)
662 Section
*s
= s1
->sections
[sh_num
];
666 cstr_printf (&str
, "%s:%c",
667 get_tok_str(sym
->v
, NULL
),
668 sym_bind
== STB_GLOBAL
? 'G' : local_scope
? 'V' : 'S'
670 tcc_get_debug_info(s1
, sym
, &str
);
671 if (sym_bind
== STB_GLOBAL
)
672 tcc_debug_stabs(s1
, str
.data
, N_GSYM
, 0, NULL
, 0);
674 tcc_debug_stabs(s1
, str
.data
,
675 (sym
->type
.t
& VT_STATIC
) && data_section
== s
676 ? N_STSYM
: N_LCSYM
, 0, s
, sym
->c
);
680 static void tcc_debug_typedef(TCCState
*s1
, Sym
*sym
)
685 cstr_printf (&str
, "%s:t",
686 (sym
->v
& ~SYM_FIELD
) >= SYM_FIRST_ANOM
687 ? "" : get_tok_str(sym
->v
& ~SYM_FIELD
, NULL
));
688 tcc_get_debug_info(s1
, sym
, &str
);
689 tcc_debug_stabs(s1
, str
.data
, N_LSYM
, 0, NULL
, 0);
693 /* put end of translation unit info */
694 ST_FUNC
void tcc_debug_end(TCCState
*s1
)
698 put_stabs_r(s1
, NULL
, N_SO
, 0, 0,
699 text_section
->data_offset
, text_section
, section_sym
);
700 tcc_free(debug_hash
);
703 static BufferedFile
* put_new_file(TCCState
*s1
)
705 BufferedFile
*f
= file
;
706 /* use upper file if from inline ":asm:" */
707 if (f
->filename
[0] == ':')
710 put_stabs_r(s1
, f
->filename
, N_SOL
, 0, 0, ind
, text_section
, section_sym
);
711 new_file
= last_line_num
= 0;
716 /* generate line number info */
717 ST_FUNC
void tcc_debug_line(TCCState
*s1
)
721 || cur_text_section
!= text_section
722 || !(f
= put_new_file(s1
))
723 || last_line_num
== f
->line_num
)
725 if (func_ind
!= -1) {
726 put_stabn(s1
, N_SLINE
, 0, f
->line_num
, ind
- func_ind
);
728 /* from tcc_assemble */
729 put_stabs_r(s1
, NULL
, N_SLINE
, 0, f
->line_num
, ind
, text_section
, section_sym
);
731 last_line_num
= f
->line_num
;
734 /* put function symbol */
735 ST_FUNC
void tcc_debug_funcstart(TCCState
*s1
, Sym
*sym
)
741 debug_info_root
= NULL
;
743 tcc_debug_stabn(N_LBRAC
, ind
- func_ind
);
744 if (!(f
= put_new_file(s1
)))
746 cstr_new (&debug_str
);
747 cstr_printf(&debug_str
, "%s:%c", funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
748 tcc_get_debug_info(s1
, sym
->type
.ref
, &debug_str
);
749 put_stabs_r(s1
, debug_str
.data
, N_FUN
, 0, f
->line_num
, 0, cur_text_section
, sym
->c
);
750 cstr_free (&debug_str
);
755 /* put function size */
756 ST_FUNC
void tcc_debug_funcend(TCCState
*s1
, int size
)
760 tcc_debug_stabn(N_RBRAC
, size
);
761 tcc_debug_finish (s1
, debug_info_root
);
764 /* put alternative filename */
765 ST_FUNC
void tcc_debug_putfile(TCCState
*s1
, const char *filename
)
767 if (0 == strcmp(file
->filename
, filename
))
769 pstrcpy(file
->filename
, sizeof(file
->filename
), filename
);
773 /* begin of #include */
774 ST_FUNC
void tcc_debug_bincl(TCCState
*s1
)
778 put_stabs(s1
, file
->filename
, N_BINCL
, 0, 0, 0);
782 /* end of #include */
783 ST_FUNC
void tcc_debug_eincl(TCCState
*s1
)
787 put_stabn(s1
, N_EINCL
, 0, 0, 0);
791 /* ------------------------------------------------------------------------- */
792 /* initialize vstack and types. This must be done also for tcc -E */
793 ST_FUNC
void tccgen_init(TCCState
*s1
)
796 memset(vtop
, 0, sizeof *vtop
);
798 /* define some often used types */
801 char_type
.t
= VT_BYTE
;
802 if (s1
->char_is_unsigned
)
803 char_type
.t
|= VT_UNSIGNED
;
804 char_pointer_type
= char_type
;
805 mk_pointer(&char_pointer_type
);
807 func_old_type
.t
= VT_FUNC
;
808 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, 0, 0);
809 func_old_type
.ref
->f
.func_call
= FUNC_CDECL
;
810 func_old_type
.ref
->f
.func_type
= FUNC_OLD
;
811 #ifdef precedence_parser
817 ST_FUNC
int tccgen_compile(TCCState
*s1
)
819 cur_text_section
= NULL
;
821 anon_sym
= SYM_FIRST_ANOM
;
824 nocode_wanted
= 0x80000000;
828 #ifdef TCC_TARGET_ARM
832 printf("%s: **** new file\n", file
->filename
);
834 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
| PARSE_FLAG_TOK_STR
;
837 gen_inline_functions(s1
);
839 /* end of translation unit info */
844 ST_FUNC
void tccgen_finish(TCCState
*s1
)
847 free_inline_functions(s1
);
848 sym_pop(&global_stack
, NULL
, 0);
849 sym_pop(&local_stack
, NULL
, 0);
850 /* free preprocessor macros */
853 dynarray_reset(&sym_pools
, &nb_sym_pools
);
854 sym_free_first
= NULL
;
857 /* ------------------------------------------------------------------------- */
858 ST_FUNC ElfSym
*elfsym(Sym
*s
)
862 return &((ElfSym
*)symtab_section
->data
)[s
->c
];
865 /* apply storage attributes to Elf symbol */
866 ST_FUNC
void update_storage(Sym
*sym
)
869 int sym_bind
, old_sym_bind
;
875 if (sym
->a
.visibility
)
876 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
879 if (sym
->type
.t
& (VT_STATIC
| VT_INLINE
))
880 sym_bind
= STB_LOCAL
;
881 else if (sym
->a
.weak
)
884 sym_bind
= STB_GLOBAL
;
885 old_sym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
886 if (sym_bind
!= old_sym_bind
) {
887 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, ELFW(ST_TYPE
)(esym
->st_info
));
891 if (sym
->a
.dllimport
)
892 esym
->st_other
|= ST_PE_IMPORT
;
893 if (sym
->a
.dllexport
)
894 esym
->st_other
|= ST_PE_EXPORT
;
898 printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n",
899 get_tok_str(sym
->v
, NULL
),
900 sym_bind
== STB_WEAK
? 'w' : sym_bind
== STB_LOCAL
? 'l' : 'g',
908 /* ------------------------------------------------------------------------- */
909 /* update sym->c so that it points to an external symbol in section
910 'section' with value 'value' */
912 ST_FUNC
void put_extern_sym2(Sym
*sym
, int sh_num
,
913 addr_t value
, unsigned long size
,
914 int can_add_underscore
)
916 int sym_type
, sym_bind
, info
, other
, t
;
922 name
= get_tok_str(sym
->v
, NULL
);
924 if ((t
& VT_BTYPE
) == VT_FUNC
) {
926 } else if ((t
& VT_BTYPE
) == VT_VOID
) {
927 sym_type
= STT_NOTYPE
;
928 if ((t
& (VT_BTYPE
|VT_ASM_FUNC
)) == VT_ASM_FUNC
)
931 sym_type
= STT_OBJECT
;
933 if (t
& (VT_STATIC
| VT_INLINE
))
934 sym_bind
= STB_LOCAL
;
936 sym_bind
= STB_GLOBAL
;
940 if (sym_type
== STT_FUNC
&& sym
->type
.ref
) {
941 Sym
*ref
= sym
->type
.ref
;
942 if (ref
->a
.nodecorate
) {
943 can_add_underscore
= 0;
945 if (ref
->f
.func_call
== FUNC_STDCALL
&& can_add_underscore
) {
946 sprintf(buf1
, "_%s@%d", name
, ref
->f
.func_args
* PTR_SIZE
);
948 other
|= ST_PE_STDCALL
;
949 can_add_underscore
= 0;
954 if (sym
->asm_label
) {
955 name
= get_tok_str(sym
->asm_label
, NULL
);
956 can_add_underscore
= 0;
959 if (tcc_state
->leading_underscore
&& can_add_underscore
) {
961 pstrcpy(buf1
+ 1, sizeof(buf1
) - 1, name
);
965 info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
966 sym
->c
= put_elf_sym(symtab_section
, value
, size
, info
, other
, sh_num
, name
);
968 if (tcc_state
->do_debug
969 && sym_type
!= STT_FUNC
970 && sym
->v
< SYM_FIRST_ANOM
)
971 tcc_debug_extern_sym(tcc_state
, sym
, sh_num
, sym_bind
);
975 esym
->st_value
= value
;
976 esym
->st_size
= size
;
977 esym
->st_shndx
= sh_num
;
982 ST_FUNC
void put_extern_sym(Sym
*sym
, Section
*section
,
983 addr_t value
, unsigned long size
)
985 int sh_num
= section
? section
->sh_num
: SHN_UNDEF
;
986 put_extern_sym2(sym
, sh_num
, value
, size
, 1);
989 /* add a new relocation entry to symbol 'sym' in section 's' */
990 ST_FUNC
void greloca(Section
*s
, Sym
*sym
, unsigned long offset
, int type
,
995 if (nocode_wanted
&& s
== cur_text_section
)
1000 put_extern_sym(sym
, NULL
, 0, 0);
1004 /* now we can add ELF relocation info */
1005 put_elf_reloca(symtab_section
, s
, offset
, type
, c
, addend
);
1009 ST_FUNC
void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
1011 greloca(s
, sym
, offset
, type
, 0);
1015 /* ------------------------------------------------------------------------- */
1016 /* symbol allocator */
1017 static Sym
*__sym_malloc(void)
1019 Sym
*sym_pool
, *sym
, *last_sym
;
1022 sym_pool
= tcc_malloc(SYM_POOL_NB
* sizeof(Sym
));
1023 dynarray_add(&sym_pools
, &nb_sym_pools
, sym_pool
);
1025 last_sym
= sym_free_first
;
1027 for(i
= 0; i
< SYM_POOL_NB
; i
++) {
1028 sym
->next
= last_sym
;
1032 sym_free_first
= last_sym
;
1036 static inline Sym
*sym_malloc(void)
1040 sym
= sym_free_first
;
1042 sym
= __sym_malloc();
1043 sym_free_first
= sym
->next
;
1046 sym
= tcc_malloc(sizeof(Sym
));
1051 ST_INLN
void sym_free(Sym
*sym
)
1054 sym
->next
= sym_free_first
;
1055 sym_free_first
= sym
;
1061 /* push, without hashing */
1062 ST_FUNC Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1067 memset(s
, 0, sizeof *s
);
1077 /* find a symbol and return its associated structure. 's' is the top
1078 of the symbol stack */
1079 ST_FUNC Sym
*sym_find2(Sym
*s
, int v
)
1084 else if (s
->v
== -1)
1091 /* structure lookup */
1092 ST_INLN Sym
*struct_find(int v
)
1095 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1097 return table_ident
[v
]->sym_struct
;
1100 /* find an identifier */
1101 ST_INLN Sym
*sym_find(int v
)
1104 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1106 return table_ident
[v
]->sym_identifier
;
1109 static int sym_scope(Sym
*s
)
1111 if (IS_ENUM_VAL (s
->type
.t
))
1112 return s
->type
.ref
->sym_scope
;
1114 return s
->sym_scope
;
1117 /* push a given symbol on the symbol stack */
1118 ST_FUNC Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1127 s
= sym_push2(ps
, v
, type
->t
, c
);
1128 s
->type
.ref
= type
->ref
;
1130 /* don't record fields or anonymous symbols */
1132 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1133 /* record symbol in token array */
1134 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1136 ps
= &ts
->sym_struct
;
1138 ps
= &ts
->sym_identifier
;
1141 s
->sym_scope
= local_scope
;
1142 if (s
->prev_tok
&& sym_scope(s
->prev_tok
) == s
->sym_scope
)
1143 tcc_error("redeclaration of '%s'",
1144 get_tok_str(v
& ~SYM_STRUCT
, NULL
));
1149 /* push a global identifier */
1150 ST_FUNC Sym
*global_identifier_push(int v
, int t
, int c
)
1153 s
= sym_push2(&global_stack
, v
, t
, c
);
1154 s
->r
= VT_CONST
| VT_SYM
;
1155 /* don't record anonymous symbol */
1156 if (v
< SYM_FIRST_ANOM
) {
1157 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1158 /* modify the top most local identifier, so that sym_identifier will
1159 point to 's' when popped; happens when called from inline asm */
1160 while (*ps
!= NULL
&& (*ps
)->sym_scope
)
1161 ps
= &(*ps
)->prev_tok
;
1168 /* pop symbols until top reaches 'b'. If KEEP is non-zero don't really
1169 pop them yet from the list, but do remove them from the token array. */
1170 ST_FUNC
void sym_pop(Sym
**ptop
, Sym
*b
, int keep
)
1180 /* remove symbol in token array */
1182 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1183 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1185 ps
= &ts
->sym_struct
;
1187 ps
= &ts
->sym_identifier
;
1198 /* ------------------------------------------------------------------------- */
1199 static void vcheck_cmp(void)
1201 /* cannot let cpu flags if other instruction are generated. Also
1202 avoid leaving VT_JMP anywhere except on the top of the stack
1203 because it would complicate the code generator.
1205 Don't do this when nocode_wanted. vtop might come from
1206 !nocode_wanted regions (see 88_codeopt.c) and transforming
1207 it to a register without actually generating code is wrong
1208 as their value might still be used for real. All values
1209 we push under nocode_wanted will eventually be popped
1210 again, so that the VT_CMP/VT_JMP value will be in vtop
1211 when code is unsuppressed again. */
1213 if (vtop
->r
== VT_CMP
&& !nocode_wanted
)
1217 static void vsetc(CType
*type
, int r
, CValue
*vc
)
1219 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
1220 tcc_error("memory full (vstack)");
1225 vtop
->r2
= VT_CONST
;
1230 ST_FUNC
void vswap(void)
1240 /* pop stack value */
1241 ST_FUNC
void vpop(void)
1244 v
= vtop
->r
& VT_VALMASK
;
1245 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1246 /* for x86, we need to pop the FP stack */
1247 if (v
== TREG_ST0
) {
1248 o(0xd8dd); /* fstp %st(0) */
1252 /* need to put correct jump if && or || without test */
1259 /* push constant of type "type" with useless value */
1260 static void vpush(CType
*type
)
1262 vset(type
, VT_CONST
, 0);
1265 /* push arbitrary 64bit constant */
1266 static void vpush64(int ty
, unsigned long long v
)
1273 vsetc(&ctype
, VT_CONST
, &cval
);
1276 /* push integer constant */
1277 ST_FUNC
void vpushi(int v
)
1282 /* push a pointer sized constant */
1283 static void vpushs(addr_t v
)
1285 vpush64(VT_SIZE_T
, v
);
1288 /* push long long constant */
1289 static inline void vpushll(long long v
)
1291 vpush64(VT_LLONG
, v
);
1294 ST_FUNC
void vset(CType
*type
, int r
, int v
)
1298 vsetc(type
, r
, &cval
);
1301 static void vseti(int r
, int v
)
1309 ST_FUNC
void vpushv(SValue
*v
)
1311 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
1312 tcc_error("memory full (vstack)");
1317 static void vdup(void)
1322 /* rotate n first stack elements to the bottom
1323 I1 ... In -> I2 ... In I1 [top is right]
1325 ST_FUNC
void vrotb(int n
)
1332 for(i
=-n
+1;i
!=0;i
++)
1333 vtop
[i
] = vtop
[i
+1];
1337 /* rotate the n elements before entry e towards the top
1338 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1340 ST_FUNC
void vrote(SValue
*e
, int n
)
1347 for(i
= 0;i
< n
- 1; i
++)
1352 /* rotate n first stack elements to the top
1353 I1 ... In -> In I1 ... I(n-1) [top is right]
1355 ST_FUNC
void vrott(int n
)
1360 /* ------------------------------------------------------------------------- */
1361 /* vtop->r = VT_CMP means CPU-flags have been set from comparison or test. */
1363 /* called from generators to set the result from relational ops */
1364 ST_FUNC
void vset_VT_CMP(int op
)
1372 /* called once before asking generators to load VT_CMP to a register */
1373 static void vset_VT_JMP(void)
1375 int op
= vtop
->cmp_op
;
1377 if (vtop
->jtrue
|| vtop
->jfalse
) {
1378 /* we need to jump to 'mov $0,%R' or 'mov $1,%R' */
1379 int inv
= op
& (op
< 2); /* small optimization */
1380 vseti(VT_JMP
+inv
, gvtst(inv
, 0));
1382 /* otherwise convert flags (rsp. 0/1) to register */
1384 if (op
< 2) /* doesn't seem to happen */
1389 /* Set CPU Flags, doesn't yet jump */
1390 static void gvtst_set(int inv
, int t
)
1394 if (vtop
->r
!= VT_CMP
) {
1397 if (vtop
->r
!= VT_CMP
) /* must be VT_CONST then */
1398 vset_VT_CMP(vtop
->c
.i
!= 0);
1401 p
= inv
? &vtop
->jfalse
: &vtop
->jtrue
;
1402 *p
= gjmp_append(*p
, t
);
1405 /* Generate value test
1407 * Generate a test for any value (jump, comparison and integers) */
1408 static int gvtst(int inv
, int t
)
1413 t
= vtop
->jtrue
, u
= vtop
->jfalse
;
1415 x
= u
, u
= t
, t
= x
;
1418 /* jump to the wanted target */
1420 t
= gjmp_cond(op
^ inv
, t
);
1423 /* resolve complementary jumps to here */
1430 /* generate a zero or nozero test */
1431 static void gen_test_zero(int op
)
1433 if (vtop
->r
== VT_CMP
) {
1437 vtop
->jfalse
= vtop
->jtrue
;
1447 /* ------------------------------------------------------------------------- */
1448 /* push a symbol value of TYPE */
1449 ST_FUNC
void vpushsym(CType
*type
, Sym
*sym
)
1453 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
1457 /* Return a static symbol pointing to a section */
1458 ST_FUNC Sym
*get_sym_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
1464 sym
= sym_push(v
, type
, VT_CONST
| VT_SYM
, 0);
1465 sym
->type
.t
|= VT_STATIC
;
1466 put_extern_sym(sym
, sec
, offset
, size
);
1470 /* push a reference to a section offset by adding a dummy symbol */
1471 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
1473 vpushsym(type
, get_sym_ref(type
, sec
, offset
, size
));
1476 /* define a new external reference to a symbol 'v' of type 'u' */
1477 ST_FUNC Sym
*external_global_sym(int v
, CType
*type
)
1483 /* push forward reference */
1484 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
1485 s
->type
.ref
= type
->ref
;
1486 } else if (IS_ASM_SYM(s
)) {
1487 s
->type
.t
= type
->t
| (s
->type
.t
& VT_EXTERN
);
1488 s
->type
.ref
= type
->ref
;
1494 /* create an external reference with no specific type similar to asm labels.
1495 This avoids type conflicts if the symbol is used from C too */
1496 ST_FUNC Sym
*external_helper_sym(int v
)
1498 CType ct
= { VT_ASM_FUNC
, NULL
};
1499 return external_global_sym(v
, &ct
);
1502 /* push a reference to an helper function (such as memmove) */
1503 ST_FUNC
void vpush_helper_func(int v
)
1505 vpushsym(&func_old_type
, external_helper_sym(v
));
1508 /* Merge symbol attributes. */
1509 static void merge_symattr(struct SymAttr
*sa
, struct SymAttr
*sa1
)
1511 if (sa1
->aligned
&& !sa
->aligned
)
1512 sa
->aligned
= sa1
->aligned
;
1513 sa
->packed
|= sa1
->packed
;
1514 sa
->weak
|= sa1
->weak
;
1515 if (sa1
->visibility
!= STV_DEFAULT
) {
1516 int vis
= sa
->visibility
;
1517 if (vis
== STV_DEFAULT
1518 || vis
> sa1
->visibility
)
1519 vis
= sa1
->visibility
;
1520 sa
->visibility
= vis
;
1522 sa
->dllexport
|= sa1
->dllexport
;
1523 sa
->nodecorate
|= sa1
->nodecorate
;
1524 sa
->dllimport
|= sa1
->dllimport
;
1527 /* Merge function attributes. */
1528 static void merge_funcattr(struct FuncAttr
*fa
, struct FuncAttr
*fa1
)
1530 if (fa1
->func_call
&& !fa
->func_call
)
1531 fa
->func_call
= fa1
->func_call
;
1532 if (fa1
->func_type
&& !fa
->func_type
)
1533 fa
->func_type
= fa1
->func_type
;
1534 if (fa1
->func_args
&& !fa
->func_args
)
1535 fa
->func_args
= fa1
->func_args
;
1536 if (fa1
->func_noreturn
)
1537 fa
->func_noreturn
= 1;
1544 /* Merge attributes. */
1545 static void merge_attr(AttributeDef
*ad
, AttributeDef
*ad1
)
1547 merge_symattr(&ad
->a
, &ad1
->a
);
1548 merge_funcattr(&ad
->f
, &ad1
->f
);
1551 ad
->section
= ad1
->section
;
1552 if (ad1
->alias_target
)
1553 ad
->alias_target
= ad1
->alias_target
;
1555 ad
->asm_label
= ad1
->asm_label
;
1557 ad
->attr_mode
= ad1
->attr_mode
;
1560 /* Merge some type attributes. */
1561 static void patch_type(Sym
*sym
, CType
*type
)
1563 if (!(type
->t
& VT_EXTERN
) || IS_ENUM_VAL(sym
->type
.t
)) {
1564 if (!(sym
->type
.t
& VT_EXTERN
))
1565 tcc_error("redefinition of '%s'", get_tok_str(sym
->v
, NULL
));
1566 sym
->type
.t
&= ~VT_EXTERN
;
1569 if (IS_ASM_SYM(sym
)) {
1570 /* stay static if both are static */
1571 sym
->type
.t
= type
->t
& (sym
->type
.t
| ~VT_STATIC
);
1572 sym
->type
.ref
= type
->ref
;
1575 if (!is_compatible_types(&sym
->type
, type
)) {
1576 tcc_error("incompatible types for redefinition of '%s'",
1577 get_tok_str(sym
->v
, NULL
));
1579 } else if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
) {
1580 int static_proto
= sym
->type
.t
& VT_STATIC
;
1581 /* warn if static follows non-static function declaration */
1582 if ((type
->t
& VT_STATIC
) && !static_proto
1583 /* XXX this test for inline shouldn't be here. Until we
1584 implement gnu-inline mode again it silences a warning for
1585 mingw caused by our workarounds. */
1586 && !((type
->t
| sym
->type
.t
) & VT_INLINE
))
1587 tcc_warning("static storage ignored for redefinition of '%s'",
1588 get_tok_str(sym
->v
, NULL
));
1590 /* set 'inline' if both agree or if one has static */
1591 if ((type
->t
| sym
->type
.t
) & VT_INLINE
) {
1592 if (!((type
->t
^ sym
->type
.t
) & VT_INLINE
)
1593 || ((type
->t
| sym
->type
.t
) & VT_STATIC
))
1594 static_proto
|= VT_INLINE
;
1597 if (0 == (type
->t
& VT_EXTERN
)) {
1598 struct FuncAttr f
= sym
->type
.ref
->f
;
1599 /* put complete type, use static from prototype */
1600 sym
->type
.t
= (type
->t
& ~(VT_STATIC
|VT_INLINE
)) | static_proto
;
1601 sym
->type
.ref
= type
->ref
;
1602 merge_funcattr(&sym
->type
.ref
->f
, &f
);
1604 sym
->type
.t
&= ~VT_INLINE
| static_proto
;
1607 if (sym
->type
.ref
->f
.func_type
== FUNC_OLD
1608 && type
->ref
->f
.func_type
!= FUNC_OLD
) {
1609 sym
->type
.ref
= type
->ref
;
1613 if ((sym
->type
.t
& VT_ARRAY
) && type
->ref
->c
>= 0) {
1614 /* set array size if it was omitted in extern declaration */
1615 sym
->type
.ref
->c
= type
->ref
->c
;
1617 if ((type
->t
^ sym
->type
.t
) & VT_STATIC
)
1618 tcc_warning("storage mismatch for redefinition of '%s'",
1619 get_tok_str(sym
->v
, NULL
));
1623 /* Merge some storage attributes. */
1624 static void patch_storage(Sym
*sym
, AttributeDef
*ad
, CType
*type
)
1627 patch_type(sym
, type
);
1629 #ifdef TCC_TARGET_PE
1630 if (sym
->a
.dllimport
!= ad
->a
.dllimport
)
1631 tcc_error("incompatible dll linkage for redefinition of '%s'",
1632 get_tok_str(sym
->v
, NULL
));
1634 merge_symattr(&sym
->a
, &ad
->a
);
1636 sym
->asm_label
= ad
->asm_label
;
1637 update_storage(sym
);
1640 /* copy sym to other stack */
1641 static Sym
*sym_copy(Sym
*s0
, Sym
**ps
)
1644 s
= sym_malloc(), *s
= *s0
;
1645 s
->prev
= *ps
, *ps
= s
;
1646 if (s
->v
< SYM_FIRST_ANOM
) {
1647 ps
= &table_ident
[s
->v
- TOK_IDENT
]->sym_identifier
;
1648 s
->prev_tok
= *ps
, *ps
= s
;
1653 /* copy s->type.ref to stack 'ps' for VT_FUNC and VT_PTR */
1654 static void sym_copy_ref(Sym
*s
, Sym
**ps
)
1656 int bt
= s
->type
.t
& VT_BTYPE
;
1657 if (bt
== VT_FUNC
|| bt
== VT_PTR
) {
1658 Sym
**sp
= &s
->type
.ref
;
1659 for (s
= *sp
, *sp
= NULL
; s
; s
= s
->next
) {
1660 Sym
*s2
= sym_copy(s
, ps
);
1661 sp
= &(*sp
= s2
)->next
;
1662 sym_copy_ref(s2
, ps
);
1667 /* define a new external reference to a symbol 'v' */
1668 static Sym
*external_sym(int v
, CType
*type
, int r
, AttributeDef
*ad
)
1672 /* look for global symbol */
1674 while (s
&& s
->sym_scope
)
1678 /* push forward reference */
1679 s
= global_identifier_push(v
, type
->t
, 0);
1682 s
->asm_label
= ad
->asm_label
;
1683 s
->type
.ref
= type
->ref
;
1684 /* copy type to the global stack */
1686 sym_copy_ref(s
, &global_stack
);
1688 patch_storage(s
, ad
, type
);
1690 /* push variables on local_stack if any */
1691 if (local_stack
&& (s
->type
.t
& VT_BTYPE
) != VT_FUNC
)
1692 s
= sym_copy(s
, &local_stack
);
1696 /* save registers up to (vtop - n) stack entry */
1697 ST_FUNC
void save_regs(int n
)
1700 for(p
= vstack
, p1
= vtop
- n
; p
<= p1
; p
++)
1704 /* save r to the memory stack, and mark it as being free */
1705 ST_FUNC
void save_reg(int r
)
1707 save_reg_upstack(r
, 0);
1710 /* save r to the memory stack, and mark it as being free,
1711 if seen up to (vtop - n) stack entry */
1712 ST_FUNC
void save_reg_upstack(int r
, int n
)
1714 int l
, size
, align
, bt
;
1717 if ((r
&= VT_VALMASK
) >= VT_CONST
)
1722 for(p
= vstack
, p1
= vtop
- n
; p
<= p1
; p
++) {
1723 if ((p
->r
& VT_VALMASK
) == r
|| p
->r2
== r
) {
1724 /* must save value on stack if not already done */
1726 bt
= p
->type
.t
& VT_BTYPE
;
1729 if ((p
->r
& VT_LVAL
) || bt
== VT_FUNC
)
1732 size
= type_size(&sv
.type
, &align
);
1733 l
= get_temp_local_var(size
,align
);
1734 sv
.r
= VT_LOCAL
| VT_LVAL
;
1736 store(p
->r
& VT_VALMASK
, &sv
);
1737 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1738 /* x86 specific: need to pop fp register ST0 if saved */
1739 if (r
== TREG_ST0
) {
1740 o(0xd8dd); /* fstp %st(0) */
1743 /* special long long case */
1744 if (p
->r2
< VT_CONST
&& USING_TWO_WORDS(bt
)) {
1749 /* mark that stack entry as being saved on the stack */
1750 if (p
->r
& VT_LVAL
) {
1751 /* also clear the bounded flag because the
1752 relocation address of the function was stored in
1754 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
1756 p
->r
= VT_LVAL
| VT_LOCAL
;
1764 #ifdef TCC_TARGET_ARM
1765 /* find a register of class 'rc2' with at most one reference on stack.
1766 * If none, call get_reg(rc) */
1767 ST_FUNC
int get_reg_ex(int rc
, int rc2
)
1772 for(r
=0;r
<NB_REGS
;r
++) {
1773 if (reg_classes
[r
] & rc2
) {
1776 for(p
= vstack
; p
<= vtop
; p
++) {
1777 if ((p
->r
& VT_VALMASK
) == r
||
1789 /* find a free register of class 'rc'. If none, save one register */
1790 ST_FUNC
int get_reg(int rc
)
1795 /* find a free register */
1796 for(r
=0;r
<NB_REGS
;r
++) {
1797 if (reg_classes
[r
] & rc
) {
1800 for(p
=vstack
;p
<=vtop
;p
++) {
1801 if ((p
->r
& VT_VALMASK
) == r
||
1810 /* no register left : free the first one on the stack (VERY
1811 IMPORTANT to start from the bottom to ensure that we don't
1812 spill registers used in gen_opi()) */
1813 for(p
=vstack
;p
<=vtop
;p
++) {
1814 /* look at second register (if long long) */
1816 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
1818 r
= p
->r
& VT_VALMASK
;
1819 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
1825 /* Should never comes here */
1829 /* find a free temporary local variable (return the offset on stack) match the size and align. If none, add new temporary stack variable*/
1830 static int get_temp_local_var(int size
,int align
){
1832 struct temp_local_variable
*temp_var
;
1839 for(i
=0;i
<nb_temp_local_vars
;i
++){
1840 temp_var
=&arr_temp_local_vars
[i
];
1841 if(temp_var
->size
<size
||align
!=temp_var
->align
){
1844 /*check if temp_var is free*/
1846 for(p
=vstack
;p
<=vtop
;p
++) {
1848 if(r
==VT_LOCAL
||r
==VT_LLOCAL
){
1849 if(p
->c
.i
==temp_var
->location
){
1856 found_var
=temp_var
->location
;
1862 loc
= (loc
- size
) & -align
;
1863 if(nb_temp_local_vars
<MAX_TEMP_LOCAL_VARIABLE_NUMBER
){
1864 temp_var
=&arr_temp_local_vars
[i
];
1865 temp_var
->location
=loc
;
1866 temp_var
->size
=size
;
1867 temp_var
->align
=align
;
1868 nb_temp_local_vars
++;
1875 static void clear_temp_local_var_list(){
1876 nb_temp_local_vars
=0;
1879 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
1881 static void move_reg(int r
, int s
, int t
)
1895 /* get address of vtop (vtop MUST BE an lvalue) */
1896 ST_FUNC
void gaddrof(void)
1898 vtop
->r
&= ~VT_LVAL
;
1899 /* tricky: if saved lvalue, then we can go back to lvalue */
1900 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
1901 vtop
->r
= (vtop
->r
& ~VT_VALMASK
) | VT_LOCAL
| VT_LVAL
;
1904 #ifdef CONFIG_TCC_BCHECK
1905 /* generate a bounded pointer addition */
1906 static void gen_bounded_ptr_add(void)
1908 int save
= (vtop
[-1].r
& VT_VALMASK
) == VT_LOCAL
;
1913 vpush_helper_func(TOK___bound_ptr_add
);
1918 /* returned pointer is in REG_IRET */
1919 vtop
->r
= REG_IRET
| VT_BOUNDED
;
1922 /* relocation offset of the bounding function call point */
1923 vtop
->c
.i
= (cur_text_section
->reloc
->data_offset
- sizeof(ElfW_Rel
));
1926 /* patch pointer addition in vtop so that pointer dereferencing is
1928 static void gen_bounded_ptr_deref(void)
1938 size
= type_size(&vtop
->type
, &align
);
1940 case 1: func
= TOK___bound_ptr_indir1
; break;
1941 case 2: func
= TOK___bound_ptr_indir2
; break;
1942 case 4: func
= TOK___bound_ptr_indir4
; break;
1943 case 8: func
= TOK___bound_ptr_indir8
; break;
1944 case 12: func
= TOK___bound_ptr_indir12
; break;
1945 case 16: func
= TOK___bound_ptr_indir16
; break;
1947 /* may happen with struct member access */
1950 sym
= external_helper_sym(func
);
1952 put_extern_sym(sym
, NULL
, 0, 0);
1953 /* patch relocation */
1954 /* XXX: find a better solution ? */
1955 rel
= (ElfW_Rel
*)(cur_text_section
->reloc
->data
+ vtop
->c
.i
);
1956 rel
->r_info
= ELFW(R_INFO
)(sym
->c
, ELFW(R_TYPE
)(rel
->r_info
));
1959 /* generate lvalue bound code */
1960 static void gbound(void)
1964 vtop
->r
&= ~VT_MUSTBOUND
;
1965 /* if lvalue, then use checking code before dereferencing */
1966 if (vtop
->r
& VT_LVAL
) {
1967 /* if not VT_BOUNDED value, then make one */
1968 if (!(vtop
->r
& VT_BOUNDED
)) {
1969 /* must save type because we must set it to int to get pointer */
1971 vtop
->type
.t
= VT_PTR
;
1974 gen_bounded_ptr_add();
1978 /* then check for dereferencing */
1979 gen_bounded_ptr_deref();
1983 /* we need to call __bound_ptr_add before we start to load function
1984 args into registers */
1985 ST_FUNC
void gbound_args(int nb_args
)
1990 for (i
= 1; i
<= nb_args
; ++i
)
1991 if (vtop
[1 - i
].r
& VT_MUSTBOUND
) {
1997 sv
= vtop
- nb_args
;
1998 if (sv
->r
& VT_SYM
) {
2002 #ifndef TCC_TARGET_PE
2003 || v
== TOK_sigsetjmp
2004 || v
== TOK___sigsetjmp
2007 vpush_helper_func(TOK___bound_setjmp
);
2010 func_bound_add_epilog
= 1;
2012 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
2013 if (v
== TOK_alloca
)
2014 func_bound_add_epilog
= 1;
2017 if (v
== TOK_longjmp
) /* undo rename to __longjmp14 */
2018 sv
->sym
->asm_label
= TOK___bound_longjmp
;
2023 /* Add bounds for local symbols from S to E (via ->prev) */
2024 static void add_local_bounds(Sym
*s
, Sym
*e
)
2026 for (; s
!= e
; s
= s
->prev
) {
2027 if (!s
->v
|| (s
->r
& VT_VALMASK
) != VT_LOCAL
)
2029 /* Add arrays/structs/unions because we always take address */
2030 if ((s
->type
.t
& VT_ARRAY
)
2031 || (s
->type
.t
& VT_BTYPE
) == VT_STRUCT
2032 || s
->a
.addrtaken
) {
2033 /* add local bound info */
2034 int align
, size
= type_size(&s
->type
, &align
);
2035 addr_t
*bounds_ptr
= section_ptr_add(lbounds_section
,
2036 2 * sizeof(addr_t
));
2037 bounds_ptr
[0] = s
->c
;
2038 bounds_ptr
[1] = size
;
2044 /* Wrapper around sym_pop, that potentially also registers local bounds. */
2045 static void pop_local_syms(Sym
**ptop
, Sym
*b
, int keep
, int ellipsis
)
2047 #ifdef CONFIG_TCC_BCHECK
2048 if (tcc_state
->do_bounds_check
&& !ellipsis
&& !keep
)
2049 add_local_bounds(*ptop
, b
);
2051 if (tcc_state
->do_debug
)
2052 tcc_add_debug_info (tcc_state
, !local_scope
, *ptop
, b
);
2053 sym_pop(ptop
, b
, keep
);
2056 static void incr_bf_adr(int o
)
2058 vtop
->type
= char_pointer_type
;
2062 vtop
->type
.t
= VT_BYTE
| VT_UNSIGNED
;
2066 /* single-byte load mode for packed or otherwise unaligned bitfields */
2067 static void load_packed_bf(CType
*type
, int bit_pos
, int bit_size
)
2070 save_reg_upstack(vtop
->r
, 1);
2071 vpush64(type
->t
& VT_BTYPE
, 0); // B X
2072 bits
= 0, o
= bit_pos
>> 3, bit_pos
&= 7;
2081 vpushi(bit_pos
), gen_op(TOK_SHR
), bit_pos
= 0; // X B Y
2083 vpushi((1 << n
) - 1), gen_op('&');
2086 vpushi(bits
), gen_op(TOK_SHL
);
2089 bits
+= n
, bit_size
-= n
, o
= 1;
2092 if (!(type
->t
& VT_UNSIGNED
)) {
2093 n
= ((type
->t
& VT_BTYPE
) == VT_LLONG
? 64 : 32) - bits
;
2094 vpushi(n
), gen_op(TOK_SHL
);
2095 vpushi(n
), gen_op(TOK_SAR
);
2099 /* single-byte store mode for packed or otherwise unaligned bitfields */
2100 static void store_packed_bf(int bit_pos
, int bit_size
)
2102 int bits
, n
, o
, m
, c
;
2104 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2106 save_reg_upstack(vtop
->r
, 1);
2107 bits
= 0, o
= bit_pos
>> 3, bit_pos
&= 7;
2109 incr_bf_adr(o
); // X B
2111 c
? vdup() : gv_dup(); // B V X
2114 vpushi(bits
), gen_op(TOK_SHR
);
2116 vpushi(bit_pos
), gen_op(TOK_SHL
);
2121 m
= ((1 << n
) - 1) << bit_pos
;
2122 vpushi(m
), gen_op('&'); // X B V1
2123 vpushv(vtop
-1); // X B V1 B
2124 vpushi(m
& 0x80 ? ~m
& 0x7f : ~m
);
2125 gen_op('&'); // X B V1 B1
2126 gen_op('|'); // X B V2
2128 vdup(), vtop
[-1] = vtop
[-2]; // X B B V2
2129 vstore(), vpop(); // X B
2130 bits
+= n
, bit_size
-= n
, bit_pos
= 0, o
= 1;
2135 static int adjust_bf(SValue
*sv
, int bit_pos
, int bit_size
)
2138 if (0 == sv
->type
.ref
)
2140 t
= sv
->type
.ref
->auxtype
;
2141 if (t
!= -1 && t
!= VT_STRUCT
) {
2142 sv
->type
.t
= (sv
->type
.t
& ~(VT_BTYPE
| VT_LONG
)) | t
;
2148 /* store vtop a register belonging to class 'rc'. lvalues are
2149 converted to values. Cannot be used if cannot be converted to
2150 register value (such as structures). */
2151 ST_FUNC
int gv(int rc
)
2153 int r
, r2
, r_ok
, r2_ok
, rc2
, bt
;
2154 int bit_pos
, bit_size
, size
, align
;
2156 /* NOTE: get_reg can modify vstack[] */
2157 if (vtop
->type
.t
& VT_BITFIELD
) {
2160 bit_pos
= BIT_POS(vtop
->type
.t
);
2161 bit_size
= BIT_SIZE(vtop
->type
.t
);
2162 /* remove bit field info to avoid loops */
2163 vtop
->type
.t
&= ~VT_STRUCT_MASK
;
2166 type
.t
= vtop
->type
.t
& VT_UNSIGNED
;
2167 if ((vtop
->type
.t
& VT_BTYPE
) == VT_BOOL
)
2168 type
.t
|= VT_UNSIGNED
;
2170 r
= adjust_bf(vtop
, bit_pos
, bit_size
);
2172 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
)
2177 if (r
== VT_STRUCT
) {
2178 load_packed_bf(&type
, bit_pos
, bit_size
);
2180 int bits
= (type
.t
& VT_BTYPE
) == VT_LLONG
? 64 : 32;
2181 /* cast to int to propagate signedness in following ops */
2183 /* generate shifts */
2184 vpushi(bits
- (bit_pos
+ bit_size
));
2186 vpushi(bits
- bit_size
);
2187 /* NOTE: transformed to SHR if unsigned */
2192 if (is_float(vtop
->type
.t
) &&
2193 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2194 /* CPUs usually cannot use float constants, so we store them
2195 generically in data segment */
2196 init_params p
= { data_section
};
2197 unsigned long offset
;
2198 size
= type_size(&vtop
->type
, &align
);
2200 size
= 0, align
= 1;
2201 offset
= section_add(p
.sec
, size
, align
);
2202 vpush_ref(&vtop
->type
, p
.sec
, offset
, size
);
2204 init_putv(&p
, &vtop
->type
, offset
);
2207 #ifdef CONFIG_TCC_BCHECK
2208 if (vtop
->r
& VT_MUSTBOUND
)
2212 bt
= vtop
->type
.t
& VT_BTYPE
;
2214 #ifdef TCC_TARGET_RISCV64
2216 if (bt
== VT_LDOUBLE
&& rc
== RC_FLOAT
)
2219 rc2
= RC2_TYPE(bt
, rc
);
2221 /* need to reload if:
2223 - lvalue (need to dereference pointer)
2224 - already a register, but not in the right class */
2225 r
= vtop
->r
& VT_VALMASK
;
2226 r_ok
= !(vtop
->r
& VT_LVAL
) && (r
< VT_CONST
) && (reg_classes
[r
] & rc
);
2227 r2_ok
= !rc2
|| ((vtop
->r2
< VT_CONST
) && (reg_classes
[vtop
->r2
] & rc2
));
2229 if (!r_ok
|| !r2_ok
) {
2233 int load_type
= (bt
== VT_QFLOAT
) ? VT_DOUBLE
: VT_PTRDIFF_T
;
2234 int original_type
= vtop
->type
.t
;
2236 /* two register type load :
2237 expand to two words temporarily */
2238 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2240 unsigned long long ll
= vtop
->c
.i
;
2241 vtop
->c
.i
= ll
; /* first word */
2243 vtop
->r
= r
; /* save register value */
2244 vpushi(ll
>> 32); /* second word */
2245 } else if (vtop
->r
& VT_LVAL
) {
2246 /* We do not want to modifier the long long pointer here.
2247 So we save any other instances down the stack */
2248 save_reg_upstack(vtop
->r
, 1);
2249 /* load from memory */
2250 vtop
->type
.t
= load_type
;
2253 vtop
[-1].r
= r
; /* save register value */
2254 /* increment pointer to get second word */
2255 vtop
->type
.t
= VT_PTRDIFF_T
;
2260 vtop
->type
.t
= load_type
;
2262 /* move registers */
2265 if (r2_ok
&& vtop
->r2
< VT_CONST
)
2268 vtop
[-1].r
= r
; /* save register value */
2269 vtop
->r
= vtop
[-1].r2
;
2271 /* Allocate second register. Here we rely on the fact that
2272 get_reg() tries first to free r2 of an SValue. */
2276 /* write second register */
2279 vtop
->type
.t
= original_type
;
2281 if (vtop
->r
== VT_CMP
)
2283 /* one register type load */
2288 #ifdef TCC_TARGET_C67
2289 /* uses register pairs for doubles */
2290 if (bt
== VT_DOUBLE
)
2297 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2298 ST_FUNC
void gv2(int rc1
, int rc2
)
2300 /* generate more generic register first. But VT_JMP or VT_CMP
2301 values must be generated first in all cases to avoid possible
2303 if (vtop
->r
!= VT_CMP
&& rc1
<= rc2
) {
2308 /* test if reload is needed for first register */
2309 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
2319 /* test if reload is needed for first register */
2320 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
2327 /* expand 64bit on stack in two ints */
2328 ST_FUNC
void lexpand(void)
2331 u
= vtop
->type
.t
& (VT_DEFSIGN
| VT_UNSIGNED
);
2332 v
= vtop
->r
& (VT_VALMASK
| VT_LVAL
);
2333 if (v
== VT_CONST
) {
2336 } else if (v
== (VT_LVAL
|VT_CONST
) || v
== (VT_LVAL
|VT_LOCAL
)) {
2342 vtop
[0].r
= vtop
[-1].r2
;
2343 vtop
[0].r2
= vtop
[-1].r2
= VT_CONST
;
2345 vtop
[0].type
.t
= vtop
[-1].type
.t
= VT_INT
| u
;
2350 /* build a long long from two ints */
2351 static void lbuild(int t
)
2353 gv2(RC_INT
, RC_INT
);
2354 vtop
[-1].r2
= vtop
[0].r
;
2355 vtop
[-1].type
.t
= t
;
2360 /* convert stack entry to register and duplicate its value in another
2362 static void gv_dup(void)
2368 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2369 if (t
& VT_BITFIELD
) {
2379 /* stack: H L L1 H1 */
2389 /* duplicate value */
2399 /* generate CPU independent (unsigned) long long operations */
2400 static void gen_opl(int op
)
2402 int t
, a
, b
, op1
, c
, i
;
2404 unsigned short reg_iret
= REG_IRET
;
2405 unsigned short reg_lret
= REG_IRE2
;
2411 func
= TOK___divdi3
;
2414 func
= TOK___udivdi3
;
2417 func
= TOK___moddi3
;
2420 func
= TOK___umoddi3
;
2427 /* call generic long long function */
2428 vpush_helper_func(func
);
2433 vtop
->r2
= reg_lret
;
2441 //pv("gen_opl A",0,2);
2447 /* stack: L1 H1 L2 H2 */
2452 vtop
[-2] = vtop
[-3];
2455 /* stack: H1 H2 L1 L2 */
2456 //pv("gen_opl B",0,4);
2462 /* stack: H1 H2 L1 L2 ML MH */
2465 /* stack: ML MH H1 H2 L1 L2 */
2469 /* stack: ML MH H1 L2 H2 L1 */
2474 /* stack: ML MH M1 M2 */
2477 } else if (op
== '+' || op
== '-') {
2478 /* XXX: add non carry method too (for MIPS or alpha) */
2484 /* stack: H1 H2 (L1 op L2) */
2487 gen_op(op1
+ 1); /* TOK_xxxC2 */
2490 /* stack: H1 H2 (L1 op L2) */
2493 /* stack: (L1 op L2) H1 H2 */
2495 /* stack: (L1 op L2) (H1 op H2) */
2503 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
2504 t
= vtop
[-1].type
.t
;
2508 /* stack: L H shift */
2510 /* constant: simpler */
2511 /* NOTE: all comments are for SHL. the other cases are
2512 done by swapping words */
2523 if (op
!= TOK_SAR
) {
2556 /* XXX: should provide a faster fallback on x86 ? */
2559 func
= TOK___ashrdi3
;
2562 func
= TOK___lshrdi3
;
2565 func
= TOK___ashldi3
;
2571 /* compare operations */
2577 /* stack: L1 H1 L2 H2 */
2579 vtop
[-1] = vtop
[-2];
2581 /* stack: L1 L2 H1 H2 */
2585 /* when values are equal, we need to compare low words. since
2586 the jump is inverted, we invert the test too. */
2589 else if (op1
== TOK_GT
)
2591 else if (op1
== TOK_ULT
)
2593 else if (op1
== TOK_UGT
)
2603 /* generate non equal test */
2605 vset_VT_CMP(TOK_NE
);
2609 /* compare low. Always unsigned */
2613 else if (op1
== TOK_LE
)
2615 else if (op1
== TOK_GT
)
2617 else if (op1
== TOK_GE
)
2620 #if 0//def TCC_TARGET_I386
2621 if (op
== TOK_NE
) { gsym(b
); break; }
2622 if (op
== TOK_EQ
) { gsym(a
); break; }
2631 static uint64_t gen_opic_sdiv(uint64_t a
, uint64_t b
)
2633 uint64_t x
= (a
>> 63 ? -a
: a
) / (b
>> 63 ? -b
: b
);
2634 return (a
^ b
) >> 63 ? -x
: x
;
2637 static int gen_opic_lt(uint64_t a
, uint64_t b
)
2639 return (a
^ (uint64_t)1 << 63) < (b
^ (uint64_t)1 << 63);
2642 /* handle integer constant optimizations and various machine
2644 static void gen_opic(int op
)
2646 SValue
*v1
= vtop
- 1;
2648 int t1
= v1
->type
.t
& VT_BTYPE
;
2649 int t2
= v2
->type
.t
& VT_BTYPE
;
2650 int c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2651 int c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2652 uint64_t l1
= c1
? v1
->c
.i
: 0;
2653 uint64_t l2
= c2
? v2
->c
.i
: 0;
2654 int shm
= (t1
== VT_LLONG
) ? 63 : 31;
2656 if (t1
!= VT_LLONG
&& (PTR_SIZE
!= 8 || t1
!= VT_PTR
))
2657 l1
= ((uint32_t)l1
|
2658 (v1
->type
.t
& VT_UNSIGNED
? 0 : -(l1
& 0x80000000)));
2659 if (t2
!= VT_LLONG
&& (PTR_SIZE
!= 8 || t2
!= VT_PTR
))
2660 l2
= ((uint32_t)l2
|
2661 (v2
->type
.t
& VT_UNSIGNED
? 0 : -(l2
& 0x80000000)));
2665 case '+': l1
+= l2
; break;
2666 case '-': l1
-= l2
; break;
2667 case '&': l1
&= l2
; break;
2668 case '^': l1
^= l2
; break;
2669 case '|': l1
|= l2
; break;
2670 case '*': l1
*= l2
; break;
2677 /* if division by zero, generate explicit division */
2679 if (const_wanted
&& !(nocode_wanted
& unevalmask
))
2680 tcc_error("division by zero in constant");
2684 default: l1
= gen_opic_sdiv(l1
, l2
); break;
2685 case '%': l1
= l1
- l2
* gen_opic_sdiv(l1
, l2
); break;
2686 case TOK_UDIV
: l1
= l1
/ l2
; break;
2687 case TOK_UMOD
: l1
= l1
% l2
; break;
2690 case TOK_SHL
: l1
<<= (l2
& shm
); break;
2691 case TOK_SHR
: l1
>>= (l2
& shm
); break;
2693 l1
= (l1
>> 63) ? ~(~l1
>> (l2
& shm
)) : l1
>> (l2
& shm
);
2696 case TOK_ULT
: l1
= l1
< l2
; break;
2697 case TOK_UGE
: l1
= l1
>= l2
; break;
2698 case TOK_EQ
: l1
= l1
== l2
; break;
2699 case TOK_NE
: l1
= l1
!= l2
; break;
2700 case TOK_ULE
: l1
= l1
<= l2
; break;
2701 case TOK_UGT
: l1
= l1
> l2
; break;
2702 case TOK_LT
: l1
= gen_opic_lt(l1
, l2
); break;
2703 case TOK_GE
: l1
= !gen_opic_lt(l1
, l2
); break;
2704 case TOK_LE
: l1
= !gen_opic_lt(l2
, l1
); break;
2705 case TOK_GT
: l1
= gen_opic_lt(l2
, l1
); break;
2707 case TOK_LAND
: l1
= l1
&& l2
; break;
2708 case TOK_LOR
: l1
= l1
|| l2
; break;
2712 if (t1
!= VT_LLONG
&& (PTR_SIZE
!= 8 || t1
!= VT_PTR
))
2713 l1
= ((uint32_t)l1
|
2714 (v1
->type
.t
& VT_UNSIGNED
? 0 : -(l1
& 0x80000000)));
2718 /* if commutative ops, put c2 as constant */
2719 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
2720 op
== '|' || op
== '*' || op
== TOK_EQ
|| op
== TOK_NE
)) {
2722 c2
= c1
; //c = c1, c1 = c2, c2 = c;
2723 l2
= l1
; //l = l1, l1 = l2, l2 = l;
2725 if (!const_wanted
&&
2727 (op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
)) ||
2728 (l1
== -1 && op
== TOK_SAR
))) {
2729 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
2731 } else if (!const_wanted
&&
2732 c2
&& ((l2
== 0 && (op
== '&' || op
== '*')) ||
2734 (l2
== -1 || (l2
== 0xFFFFFFFF && t2
!= VT_LLONG
))) ||
2735 (l2
== 1 && (op
== '%' || op
== TOK_UMOD
)))) {
2736 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
2741 } else if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
2744 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
2745 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
2748 (l2
== -1 || (l2
== 0xFFFFFFFF && t2
!= VT_LLONG
))))) {
2749 /* filter out NOP operations like x*1, x-0, x&-1... */
2751 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
2752 /* try to use shifts instead of muls or divs */
2753 if (l2
> 0 && (l2
& (l2
- 1)) == 0) {
2762 else if (op
== TOK_PDIV
)
2768 } else if (c2
&& (op
== '+' || op
== '-') &&
2769 (((vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == (VT_CONST
| VT_SYM
))
2770 || (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
)) == VT_LOCAL
)) {
2771 /* symbol + constant case */
2775 /* The backends can't always deal with addends to symbols
2776 larger than +-1<<31. Don't construct such. */
2783 /* call low level op generator */
2784 if (t1
== VT_LLONG
|| t2
== VT_LLONG
||
2785 (PTR_SIZE
== 8 && (t1
== VT_PTR
|| t2
== VT_PTR
)))
2793 #if defined TCC_TARGET_X86_64 || defined TCC_TARGET_I386
2794 # define gen_negf gen_opf
2796 /* XXX: implement in gen_opf() for other backends too */
2797 void gen_negf(int op
)
2799 /* In IEEE negate(x) isn't subtract(0,x). Without NaNs it's
2800 subtract(-0, x), but with them it's really a sign flip
2801 operation. We implement this with bit manipulation and have
2802 to do some type reinterpretation for this, which TCC can do
2805 int align
, size
, bt
;
2807 size
= type_size(&vtop
->type
, &align
);
2808 bt
= vtop
->type
.t
& VT_BTYPE
;
2809 save_reg(gv(RC_TYPE(bt
)));
2811 incr_bf_adr(size
- 1);
2813 vpushi(0x80); /* flip sign */
2820 /* generate a floating point operation with constant propagation */
2821 static void gen_opif(int op
)
2825 #if defined _MSC_VER && defined __x86_64__
2826 /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
2836 /* currently, we cannot do computations with forward symbols */
2837 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2838 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
2840 if (v1
->type
.t
== VT_FLOAT
) {
2843 } else if (v1
->type
.t
== VT_DOUBLE
) {
2850 /* NOTE: we only do constant propagation if finite number (not
2851 NaN or infinity) (ANSI spec) */
2852 if (!(ieee_finite(f1
) || !ieee_finite(f2
)) && !const_wanted
)
2855 case '+': f1
+= f2
; break;
2856 case '-': f1
-= f2
; break;
2857 case '*': f1
*= f2
; break;
2860 union { float f
; unsigned u
; } x1
, x2
, y
;
2861 /* If not in initializer we need to potentially generate
2862 FP exceptions at runtime, otherwise we want to fold. */
2865 /* the run-time result of 0.0/0.0 on x87, also of other compilers
2866 when used to compile the f1 /= f2 below, would be -nan */
2867 x1
.f
= f1
, x2
.f
= f2
;
2869 y
.u
= 0x7fc00000; /* nan */
2871 y
.u
= 0x7f800000; /* infinity */
2872 y
.u
|= (x1
.u
^ x2
.u
) & 0x80000000; /* set sign */
2881 /* XXX: also handles tests ? */
2887 /* XXX: overflow test ? */
2888 if (v1
->type
.t
== VT_FLOAT
) {
2890 } else if (v1
->type
.t
== VT_DOUBLE
) {
2897 if (op
== TOK_NEG
) {
2905 /* print a type. If 'varstr' is not NULL, then the variable is also
2906 printed in the type */
2908 /* XXX: add array and function pointers */
2909 static void type_to_str(char *buf
, int buf_size
,
2910 CType
*type
, const char *varstr
)
2922 pstrcat(buf
, buf_size
, "extern ");
2924 pstrcat(buf
, buf_size
, "static ");
2926 pstrcat(buf
, buf_size
, "typedef ");
2928 pstrcat(buf
, buf_size
, "inline ");
2929 if (t
& VT_VOLATILE
)
2930 pstrcat(buf
, buf_size
, "volatile ");
2931 if (t
& VT_CONSTANT
)
2932 pstrcat(buf
, buf_size
, "const ");
2934 if (((t
& VT_DEFSIGN
) && bt
== VT_BYTE
)
2935 || ((t
& VT_UNSIGNED
)
2936 && (bt
== VT_SHORT
|| bt
== VT_INT
|| bt
== VT_LLONG
)
2939 pstrcat(buf
, buf_size
, (t
& VT_UNSIGNED
) ? "unsigned " : "signed ");
2941 buf_size
-= strlen(buf
);
2977 tstr
= "long double";
2979 pstrcat(buf
, buf_size
, tstr
);
2986 pstrcat(buf
, buf_size
, tstr
);
2987 v
= type
->ref
->v
& ~SYM_STRUCT
;
2988 if (v
>= SYM_FIRST_ANOM
)
2989 pstrcat(buf
, buf_size
, "<anonymous>");
2991 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
2996 if (varstr
&& '*' == *varstr
) {
2997 pstrcat(buf1
, sizeof(buf1
), "(");
2998 pstrcat(buf1
, sizeof(buf1
), varstr
);
2999 pstrcat(buf1
, sizeof(buf1
), ")");
3001 pstrcat(buf1
, buf_size
, "(");
3003 while (sa
!= NULL
) {
3005 type_to_str(buf2
, sizeof(buf2
), &sa
->type
, NULL
);
3006 pstrcat(buf1
, sizeof(buf1
), buf2
);
3009 pstrcat(buf1
, sizeof(buf1
), ", ");
3011 if (s
->f
.func_type
== FUNC_ELLIPSIS
)
3012 pstrcat(buf1
, sizeof(buf1
), ", ...");
3013 pstrcat(buf1
, sizeof(buf1
), ")");
3014 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
3019 if (varstr
&& '*' == *varstr
)
3020 snprintf(buf1
, sizeof(buf1
), "(%s)[%d]", varstr
, s
->c
);
3022 snprintf(buf1
, sizeof(buf1
), "%s[%d]", varstr
? varstr
: "", s
->c
);
3023 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
3026 pstrcpy(buf1
, sizeof(buf1
), "*");
3027 if (t
& VT_CONSTANT
)
3028 pstrcat(buf1
, buf_size
, "const ");
3029 if (t
& VT_VOLATILE
)
3030 pstrcat(buf1
, buf_size
, "volatile ");
3032 pstrcat(buf1
, sizeof(buf1
), varstr
);
3033 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
3037 pstrcat(buf
, buf_size
, " ");
3038 pstrcat(buf
, buf_size
, varstr
);
3043 static void type_incompatibility_error(CType
* st
, CType
* dt
, const char* fmt
)
3045 char buf1
[256], buf2
[256];
3046 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3047 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3048 tcc_error(fmt
, buf1
, buf2
);
3051 static void type_incompatibility_warning(CType
* st
, CType
* dt
, const char* fmt
)
3053 char buf1
[256], buf2
[256];
3054 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3055 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3056 tcc_warning(fmt
, buf1
, buf2
);
3059 static int pointed_size(CType
*type
)
3062 return type_size(pointed_type(type
), &align
);
3065 static void vla_runtime_pointed_size(CType
*type
)
3068 vla_runtime_type_size(pointed_type(type
), &align
);
3071 static inline int is_null_pointer(SValue
*p
)
3073 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
3075 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& (uint32_t)p
->c
.i
== 0) ||
3076 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.i
== 0) ||
3077 ((p
->type
.t
& VT_BTYPE
) == VT_PTR
&&
3078 (PTR_SIZE
== 4 ? (uint32_t)p
->c
.i
== 0 : p
->c
.i
== 0) &&
3079 ((pointed_type(&p
->type
)->t
& VT_BTYPE
) == VT_VOID
) &&
3080 0 == (pointed_type(&p
->type
)->t
& (VT_CONSTANT
| VT_VOLATILE
))
3084 /* compare function types. OLD functions match any new functions */
3085 static int is_compatible_func(CType
*type1
, CType
*type2
)
3091 if (s1
->f
.func_call
!= s2
->f
.func_call
)
3093 if (s1
->f
.func_type
!= s2
->f
.func_type
3094 && s1
->f
.func_type
!= FUNC_OLD
3095 && s2
->f
.func_type
!= FUNC_OLD
)
3098 if (!is_compatible_unqualified_types(&s1
->type
, &s2
->type
))
3100 if (s1
->f
.func_type
== FUNC_OLD
|| s2
->f
.func_type
== FUNC_OLD
)
3111 /* return true if type1 and type2 are the same. If unqualified is
3112 true, qualifiers on the types are ignored.
3114 static int compare_types(CType
*type1
, CType
*type2
, int unqualified
)
3118 t1
= type1
->t
& VT_TYPE
;
3119 t2
= type2
->t
& VT_TYPE
;
3121 /* strip qualifiers before comparing */
3122 t1
&= ~(VT_CONSTANT
| VT_VOLATILE
);
3123 t2
&= ~(VT_CONSTANT
| VT_VOLATILE
);
3126 /* Default Vs explicit signedness only matters for char */
3127 if ((t1
& VT_BTYPE
) != VT_BYTE
) {
3131 /* XXX: bitfields ? */
3136 && !(type1
->ref
->c
< 0
3137 || type2
->ref
->c
< 0
3138 || type1
->ref
->c
== type2
->ref
->c
))
3141 /* test more complicated cases */
3142 bt1
= t1
& VT_BTYPE
;
3143 if (bt1
== VT_PTR
) {
3144 type1
= pointed_type(type1
);
3145 type2
= pointed_type(type2
);
3146 return is_compatible_types(type1
, type2
);
3147 } else if (bt1
== VT_STRUCT
) {
3148 return (type1
->ref
== type2
->ref
);
3149 } else if (bt1
== VT_FUNC
) {
3150 return is_compatible_func(type1
, type2
);
3151 } else if (IS_ENUM(type1
->t
) && IS_ENUM(type2
->t
)) {
3152 /* If both are enums then they must be the same, if only one is then
3153 t1 and t2 must be equal, which was checked above already. */
3154 return type1
->ref
== type2
->ref
;
3160 /* Check if OP1 and OP2 can be "combined" with operation OP, the combined
3161 type is stored in DEST if non-null (except for pointer plus/minus) . */
3162 static int combine_types(CType
*dest
, SValue
*op1
, SValue
*op2
, int op
)
3164 CType
*type1
= &op1
->type
, *type2
= &op2
->type
, type
;
3165 int t1
= type1
->t
, t2
= type2
->t
, bt1
= t1
& VT_BTYPE
, bt2
= t2
& VT_BTYPE
;
3171 if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
3172 ret
= op
== '?' ? 1 : 0;
3173 /* NOTE: as an extension, we accept void on only one side */
3175 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3176 if (op
== '+') ; /* Handled in caller */
3177 /* http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6 */
3178 /* If one is a null ptr constant the result type is the other. */
3179 else if (is_null_pointer (op2
)) type
= *type1
;
3180 else if (is_null_pointer (op1
)) type
= *type2
;
3181 else if (bt1
!= bt2
) {
3182 /* accept comparison or cond-expr between pointer and integer
3184 if ((op
== '?' || TOK_ISCOND(op
))
3185 && (is_integer_btype(bt1
) || is_integer_btype(bt2
)))
3186 tcc_warning("pointer/integer mismatch in %s",
3187 op
== '?' ? "conditional expression" : "comparison");
3188 else if (op
!= '-' || !is_integer_btype(bt2
))
3190 type
= *(bt1
== VT_PTR
? type1
: type2
);
3192 CType
*pt1
= pointed_type(type1
);
3193 CType
*pt2
= pointed_type(type2
);
3194 int pbt1
= pt1
->t
& VT_BTYPE
;
3195 int pbt2
= pt2
->t
& VT_BTYPE
;
3196 int newquals
, copied
= 0;
3197 if (pbt1
!= VT_VOID
&& pbt2
!= VT_VOID
3198 && !compare_types(pt1
, pt2
, 1/*unqualif*/)) {
3199 if (op
!= '?' && !TOK_ISCOND(op
))
3202 type_incompatibility_warning(type1
, type2
,
3204 ? "pointer type mismatch in conditional expression ('%s' and '%s')"
3205 : "pointer type mismatch in comparison('%s' and '%s')");
3208 /* pointers to void get preferred, otherwise the
3209 pointed to types minus qualifs should be compatible */
3210 type
= *((pbt1
== VT_VOID
) ? type1
: type2
);
3211 /* combine qualifs */
3212 newquals
= ((pt1
->t
| pt2
->t
) & (VT_CONSTANT
| VT_VOLATILE
));
3213 if ((~pointed_type(&type
)->t
& (VT_CONSTANT
| VT_VOLATILE
))
3216 /* copy the pointer target symbol */
3217 type
.ref
= sym_push(SYM_FIELD
, &type
.ref
->type
,
3220 pointed_type(&type
)->t
|= newquals
;
3222 /* pointers to incomplete arrays get converted to
3223 pointers to completed ones if possible */
3224 if (pt1
->t
& VT_ARRAY
3225 && pt2
->t
& VT_ARRAY
3226 && pointed_type(&type
)->ref
->c
< 0
3227 && (pt1
->ref
->c
> 0 || pt2
->ref
->c
> 0))
3230 type
.ref
= sym_push(SYM_FIELD
, &type
.ref
->type
,
3232 pointed_type(&type
)->ref
=
3233 sym_push(SYM_FIELD
, &pointed_type(&type
)->ref
->type
,
3234 0, pointed_type(&type
)->ref
->c
);
3235 pointed_type(&type
)->ref
->c
=
3236 0 < pt1
->ref
->c
? pt1
->ref
->c
: pt2
->ref
->c
;
3242 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
3243 if (op
!= '?' || !compare_types(type1
, type2
, 1))
3246 } else if (is_float(bt1
) || is_float(bt2
)) {
3247 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3248 type
.t
= VT_LDOUBLE
;
3249 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3254 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3255 /* cast to biggest op */
3256 type
.t
= VT_LLONG
| VT_LONG
;
3257 if (bt1
== VT_LLONG
)
3259 if (bt2
== VT_LLONG
)
3261 /* convert to unsigned if it does not fit in a long long */
3262 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3263 (t2
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_LLONG
| VT_UNSIGNED
))
3264 type
.t
|= VT_UNSIGNED
;
3266 /* integer operations */
3267 type
.t
= VT_INT
| (VT_LONG
& (t1
| t2
));
3268 /* convert to unsigned if it does not fit in an integer */
3269 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_INT
| VT_UNSIGNED
) ||
3270 (t2
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (VT_INT
| VT_UNSIGNED
))
3271 type
.t
|= VT_UNSIGNED
;
3278 /* generic gen_op: handles types problems */
3279 ST_FUNC
void gen_op(int op
)
3281 int u
, t1
, t2
, bt1
, bt2
, t
;
3282 CType type1
, combtype
;
3285 t1
= vtop
[-1].type
.t
;
3286 t2
= vtop
[0].type
.t
;
3287 bt1
= t1
& VT_BTYPE
;
3288 bt2
= t2
& VT_BTYPE
;
3290 if (bt1
== VT_FUNC
|| bt2
== VT_FUNC
) {
3291 if (bt2
== VT_FUNC
) {
3292 mk_pointer(&vtop
->type
);
3295 if (bt1
== VT_FUNC
) {
3297 mk_pointer(&vtop
->type
);
3302 } else if (!combine_types(&combtype
, vtop
- 1, vtop
, op
)) {
3303 tcc_error_noabort("invalid operand types for binary operation");
3305 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3306 /* at least one operand is a pointer */
3307 /* relational op: must be both pointers */
3310 /* if both pointers, then it must be the '-' op */
3311 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
3313 tcc_error("cannot use pointers here");
3314 if (vtop
[-1].type
.t
& VT_VLA
) {
3315 vla_runtime_pointed_size(&vtop
[-1].type
);
3317 vpushi(pointed_size(&vtop
[-1].type
));
3321 vtop
->type
.t
= VT_PTRDIFF_T
;
3325 /* exactly one pointer : must be '+' or '-'. */
3326 if (op
!= '-' && op
!= '+')
3327 tcc_error("cannot use pointers here");
3328 /* Put pointer as first operand */
3329 if (bt2
== VT_PTR
) {
3331 t
= t1
, t1
= t2
, t2
= t
;
3334 if ((vtop
[0].type
.t
& VT_BTYPE
) == VT_LLONG
)
3335 /* XXX: truncate here because gen_opl can't handle ptr + long long */
3338 type1
= vtop
[-1].type
;
3339 if (vtop
[-1].type
.t
& VT_VLA
)
3340 vla_runtime_pointed_size(&vtop
[-1].type
);
3342 u
= pointed_size(&vtop
[-1].type
);
3344 tcc_error("unknown array element size");
3348 /* XXX: cast to int ? (long long case) */
3353 #ifdef CONFIG_TCC_BCHECK
3354 if (tcc_state
->do_bounds_check
&& !const_wanted
) {
3355 /* if bounded pointers, we generate a special code to
3362 gen_bounded_ptr_add();
3368 type1
.t
&= ~VT_ARRAY
;
3369 /* put again type if gen_opic() swaped operands */
3373 /* floats can only be used for a few operations */
3374 if (is_float(combtype
.t
)
3375 && op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/'
3377 tcc_error("invalid operands for binary operation");
3378 else if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
) {
3379 t
= bt1
== VT_LLONG
? VT_LLONG
: VT_INT
;
3380 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
| VT_BITFIELD
)) == (t
| VT_UNSIGNED
))
3382 t
|= (VT_LONG
& t1
);
3386 t
= t2
= combtype
.t
;
3387 /* XXX: currently, some unsigned operations are explicit, so
3388 we modify them here */
3389 if (t
& VT_UNSIGNED
) {
3396 else if (op
== TOK_LT
)
3398 else if (op
== TOK_GT
)
3400 else if (op
== TOK_LE
)
3402 else if (op
== TOK_GE
)
3408 /* special case for shifts and long long: we keep the shift as
3410 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3417 if (TOK_ISCOND(op
)) {
3418 /* relational op: the result is an int */
3419 vtop
->type
.t
= VT_INT
;
3424 // Make sure that we have converted to an rvalue:
3425 if (vtop
->r
& VT_LVAL
)
3426 gv(is_float(vtop
->type
.t
& VT_BTYPE
) ? RC_FLOAT
: RC_INT
);
3429 #if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 || defined TCC_TARGET_ARM
3430 #define gen_cvt_itof1 gen_cvt_itof
3432 /* generic itof for unsigned long long case */
3433 static void gen_cvt_itof1(int t
)
3435 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3436 (VT_LLONG
| VT_UNSIGNED
)) {
3439 vpush_helper_func(TOK___floatundisf
);
3440 #if LDOUBLE_SIZE != 8
3441 else if (t
== VT_LDOUBLE
)
3442 vpush_helper_func(TOK___floatundixf
);
3445 vpush_helper_func(TOK___floatundidf
);
3456 #if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
3457 #define gen_cvt_ftoi1 gen_cvt_ftoi
3459 /* generic ftoi for unsigned long long case */
3460 static void gen_cvt_ftoi1(int t
)
3463 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3464 /* not handled natively */
3465 st
= vtop
->type
.t
& VT_BTYPE
;
3467 vpush_helper_func(TOK___fixunssfdi
);
3468 #if LDOUBLE_SIZE != 8
3469 else if (st
== VT_LDOUBLE
)
3470 vpush_helper_func(TOK___fixunsxfdi
);
3473 vpush_helper_func(TOK___fixunsdfdi
);
3484 /* special delayed cast for char/short */
3485 static void force_charshort_cast(void)
3487 int sbt
= BFGET(vtop
->r
, VT_MUSTCAST
) == 2 ? VT_LLONG
: VT_INT
;
3488 int dbt
= vtop
->type
.t
;
3489 vtop
->r
&= ~VT_MUSTCAST
;
3491 gen_cast_s(dbt
== VT_BOOL
? VT_BYTE
|VT_UNSIGNED
: dbt
);
3495 static void gen_cast_s(int t
)
3503 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
3504 static void gen_cast(CType
*type
)
3506 int sbt
, dbt
, sf
, df
, c
;
3507 int dbt_bt
, sbt_bt
, ds
, ss
, bits
, trunc
;
3509 /* special delayed cast for char/short */
3510 if (vtop
->r
& VT_MUSTCAST
)
3511 force_charshort_cast();
3513 /* bitfields first get cast to ints */
3514 if (vtop
->type
.t
& VT_BITFIELD
)
3517 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3518 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
3526 dbt_bt
= dbt
& VT_BTYPE
;
3527 sbt_bt
= sbt
& VT_BTYPE
;
3529 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3530 #if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
3531 c
&= (dbt
!= VT_LDOUBLE
) | !!nocode_wanted
;
3534 /* constant case: we can do it now */
3535 /* XXX: in ISOC, cannot do it if error in convert */
3536 if (sbt
== VT_FLOAT
)
3537 vtop
->c
.ld
= vtop
->c
.f
;
3538 else if (sbt
== VT_DOUBLE
)
3539 vtop
->c
.ld
= vtop
->c
.d
;
3542 if (sbt_bt
== VT_LLONG
) {
3543 if ((sbt
& VT_UNSIGNED
) || !(vtop
->c
.i
>> 63))
3544 vtop
->c
.ld
= vtop
->c
.i
;
3546 vtop
->c
.ld
= -(long double)-vtop
->c
.i
;
3548 if ((sbt
& VT_UNSIGNED
) || !(vtop
->c
.i
>> 31))
3549 vtop
->c
.ld
= (uint32_t)vtop
->c
.i
;
3551 vtop
->c
.ld
= -(long double)-(uint32_t)vtop
->c
.i
;
3554 if (dbt
== VT_FLOAT
)
3555 vtop
->c
.f
= (float)vtop
->c
.ld
;
3556 else if (dbt
== VT_DOUBLE
)
3557 vtop
->c
.d
= (double)vtop
->c
.ld
;
3558 } else if (sf
&& dbt
== VT_BOOL
) {
3559 vtop
->c
.i
= (vtop
->c
.ld
!= 0);
3562 vtop
->c
.i
= vtop
->c
.ld
;
3563 else if (sbt_bt
== VT_LLONG
|| (PTR_SIZE
== 8 && sbt
== VT_PTR
))
3565 else if (sbt
& VT_UNSIGNED
)
3566 vtop
->c
.i
= (uint32_t)vtop
->c
.i
;
3568 vtop
->c
.i
= ((uint32_t)vtop
->c
.i
| -(vtop
->c
.i
& 0x80000000));
3570 if (dbt_bt
== VT_LLONG
|| (PTR_SIZE
== 8 && dbt
== VT_PTR
))
3572 else if (dbt
== VT_BOOL
)
3573 vtop
->c
.i
= (vtop
->c
.i
!= 0);
3575 uint32_t m
= dbt_bt
== VT_BYTE
? 0xff :
3576 dbt_bt
== VT_SHORT
? 0xffff :
3579 if (!(dbt
& VT_UNSIGNED
))
3580 vtop
->c
.i
|= -(vtop
->c
.i
& ((m
>> 1) + 1));
3585 } else if (dbt
== VT_BOOL
3586 && (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
))
3587 == (VT_CONST
| VT_SYM
)) {
3588 /* addresses are considered non-zero (see tcctest.c:sinit23) */
3594 /* cannot generate code for global or static initializers */
3595 if (STATIC_DATA_WANTED
)
3598 /* non constant case: generate code */
3599 if (dbt
== VT_BOOL
) {
3600 gen_test_zero(TOK_NE
);
3606 /* convert from fp to fp */
3609 /* convert int to fp */
3612 /* convert fp to int */
3614 if (dbt_bt
!= VT_LLONG
&& dbt_bt
!= VT_INT
)
3617 goto again
; /* may need char/short cast */
3622 ds
= btype_size(dbt_bt
);
3623 ss
= btype_size(sbt_bt
);
3624 if (ds
== 0 || ss
== 0) {
3625 if (dbt_bt
== VT_VOID
)
3627 cast_error(&vtop
->type
, type
);
3629 if (IS_ENUM(type
->t
) && type
->ref
->c
< 0)
3630 tcc_error("cast to incomplete type");
3632 /* same size and no sign conversion needed */
3633 if (ds
== ss
&& ds
>= 4)
3635 if (dbt_bt
== VT_PTR
|| sbt_bt
== VT_PTR
) {
3636 tcc_warning("cast between pointer and integer of different size");
3637 if (sbt_bt
== VT_PTR
) {
3638 /* put integer type to allow logical operations below */
3639 vtop
->type
.t
= (PTR_SIZE
== 8 ? VT_LLONG
: VT_INT
);
3643 /* processor allows { int a = 0, b = *(char*)&a; }
3644 That means that if we cast to less width, we can just
3645 change the type and read it still later. */
3646 #define ALLOW_SUBTYPE_ACCESS 1
3648 if (ALLOW_SUBTYPE_ACCESS
&& (vtop
->r
& VT_LVAL
)) {
3649 /* value still in memory */
3653 if (ds
<= 4 && !(dbt
== (VT_SHORT
| VT_UNSIGNED
) && sbt
== VT_BYTE
)) {
3655 goto done
; /* no 64bit envolved */
3663 /* generate high word */
3664 if (sbt
& VT_UNSIGNED
) {
3673 } else if (ss
== 8) {
3674 /* from long long: just take low order word */
3682 /* need to convert from 32bit to 64bit */
3683 if (sbt
& VT_UNSIGNED
) {
3684 #if defined(TCC_TARGET_RISCV64)
3685 /* RISC-V keeps 32bit vals in registers sign-extended.
3686 So here we need a zero-extension. */
3695 ss
= ds
, ds
= 4, dbt
= sbt
;
3696 } else if (ss
== 8) {
3697 /* RISC-V keeps 32bit vals in registers sign-extended.
3698 So here we need a sign-extension for signed types and
3699 zero-extension. for unsigned types. */
3700 #if !defined(TCC_TARGET_RISCV64)
3701 trunc
= 32; /* zero upper 32 bits for non RISC-V targets */
3710 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM64
3716 bits
= (ss
- ds
) * 8;
3717 /* for unsigned, gen_op will convert SAR to SHR */
3718 vtop
->type
.t
= (ss
== 8 ? VT_LLONG
: VT_INT
) | (dbt
& VT_UNSIGNED
);
3721 vpushi(bits
- trunc
);
3728 vtop
->type
.t
&= ~ ( VT_CONSTANT
| VT_VOLATILE
| VT_ARRAY
);
3731 /* return type size as known at compile time. Put alignment at 'a' */
3732 ST_FUNC
int type_size(CType
*type
, int *a
)
3737 bt
= type
->t
& VT_BTYPE
;
3738 if (bt
== VT_STRUCT
) {
3743 } else if (bt
== VT_PTR
) {
3744 if (type
->t
& VT_ARRAY
) {
3748 ts
= type_size(&s
->type
, a
);
3750 if (ts
< 0 && s
->c
< 0)
3758 } else if (IS_ENUM(type
->t
) && type
->ref
->c
< 0) {
3759 return -1; /* incomplete enum */
3760 } else if (bt
== VT_LDOUBLE
) {
3762 return LDOUBLE_SIZE
;
3763 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3764 #ifdef TCC_TARGET_I386
3765 #ifdef TCC_TARGET_PE
3770 #elif defined(TCC_TARGET_ARM)
3780 } else if (bt
== VT_INT
|| bt
== VT_FLOAT
) {
3783 } else if (bt
== VT_SHORT
) {
3786 } else if (bt
== VT_QLONG
|| bt
== VT_QFLOAT
) {
3790 /* char, void, function, _Bool */
3796 /* push type size as known at runtime time on top of value stack. Put
3798 ST_FUNC
void vla_runtime_type_size(CType
*type
, int *a
)
3800 if (type
->t
& VT_VLA
) {
3801 type_size(&type
->ref
->type
, a
);
3802 vset(&int_type
, VT_LOCAL
|VT_LVAL
, type
->ref
->c
);
3804 vpushi(type_size(type
, a
));
3808 /* return the pointed type of t */
3809 static inline CType
*pointed_type(CType
*type
)
3811 return &type
->ref
->type
;
3814 /* modify type so that its it is a pointer to type. */
3815 ST_FUNC
void mk_pointer(CType
*type
)
3818 s
= sym_push(SYM_FIELD
, type
, 0, -1);
3819 type
->t
= VT_PTR
| (type
->t
& VT_STORAGE
);
3823 /* return true if type1 and type2 are exactly the same (including
3826 static int is_compatible_types(CType
*type1
, CType
*type2
)
3828 return compare_types(type1
,type2
,0);
3831 /* return true if type1 and type2 are the same (ignoring qualifiers).
3833 static int is_compatible_unqualified_types(CType
*type1
, CType
*type2
)
3835 return compare_types(type1
,type2
,1);
3838 static void cast_error(CType
*st
, CType
*dt
)
3840 type_incompatibility_error(st
, dt
, "cannot convert '%s' to '%s'");
3843 /* verify type compatibility to store vtop in 'dt' type */
3844 static void verify_assign_cast(CType
*dt
)
3846 CType
*st
, *type1
, *type2
;
3847 int dbt
, sbt
, qualwarn
, lvl
;
3849 st
= &vtop
->type
; /* source type */
3850 dbt
= dt
->t
& VT_BTYPE
;
3851 sbt
= st
->t
& VT_BTYPE
;
3852 if (dt
->t
& VT_CONSTANT
)
3853 tcc_warning("assignment of read-only location");
3857 tcc_error("assignment to void expression");
3860 /* special cases for pointers */
3861 /* '0' can also be a pointer */
3862 if (is_null_pointer(vtop
))
3864 /* accept implicit pointer to integer cast with warning */
3865 if (is_integer_btype(sbt
)) {
3866 tcc_warning("assignment makes pointer from integer without a cast");
3869 type1
= pointed_type(dt
);
3871 type2
= pointed_type(st
);
3872 else if (sbt
== VT_FUNC
)
3873 type2
= st
; /* a function is implicitly a function pointer */
3876 if (is_compatible_types(type1
, type2
))
3878 for (qualwarn
= lvl
= 0;; ++lvl
) {
3879 if (((type2
->t
& VT_CONSTANT
) && !(type1
->t
& VT_CONSTANT
)) ||
3880 ((type2
->t
& VT_VOLATILE
) && !(type1
->t
& VT_VOLATILE
)))
3882 dbt
= type1
->t
& (VT_BTYPE
|VT_LONG
);
3883 sbt
= type2
->t
& (VT_BTYPE
|VT_LONG
);
3884 if (dbt
!= VT_PTR
|| sbt
!= VT_PTR
)
3886 type1
= pointed_type(type1
);
3887 type2
= pointed_type(type2
);
3889 if (!is_compatible_unqualified_types(type1
, type2
)) {
3890 if ((dbt
== VT_VOID
|| sbt
== VT_VOID
) && lvl
== 0) {
3891 /* void * can match anything */
3892 } else if (dbt
== sbt
3893 && is_integer_btype(sbt
& VT_BTYPE
)
3894 && IS_ENUM(type1
->t
) + IS_ENUM(type2
->t
)
3895 + !!((type1
->t
^ type2
->t
) & VT_UNSIGNED
) < 2) {
3896 /* Like GCC don't warn by default for merely changes
3897 in pointer target signedness. Do warn for different
3898 base types, though, in particular for unsigned enums
3899 and signed int targets. */
3901 tcc_warning("assignment from incompatible pointer type");
3906 tcc_warning("assignment discards qualifiers from pointer target type");
3912 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
3913 tcc_warning("assignment makes integer from pointer without a cast");
3914 } else if (sbt
== VT_STRUCT
) {
3915 goto case_VT_STRUCT
;
3917 /* XXX: more tests */
3921 if (!is_compatible_unqualified_types(dt
, st
)) {
3929 static void gen_assign_cast(CType
*dt
)
3931 verify_assign_cast(dt
);
3935 /* store vtop in lvalue pushed on stack */
3936 ST_FUNC
void vstore(void)
3938 int sbt
, dbt
, ft
, r
, size
, align
, bit_size
, bit_pos
, delayed_cast
;
3940 ft
= vtop
[-1].type
.t
;
3941 sbt
= vtop
->type
.t
& VT_BTYPE
;
3942 dbt
= ft
& VT_BTYPE
;
3944 verify_assign_cast(&vtop
[-1].type
);
3946 if (sbt
== VT_STRUCT
) {
3947 /* if structure, only generate pointer */
3948 /* structure assignment : generate memcpy */
3949 /* XXX: optimize if small size */
3950 size
= type_size(&vtop
->type
, &align
);
3954 #ifdef CONFIG_TCC_BCHECK
3955 if (vtop
->r
& VT_MUSTBOUND
)
3956 gbound(); /* check would be wrong after gaddrof() */
3958 vtop
->type
.t
= VT_PTR
;
3961 /* address of memcpy() */
3964 vpush_helper_func(TOK_memmove8
);
3965 else if(!(align
& 3))
3966 vpush_helper_func(TOK_memmove4
);
3969 /* Use memmove, rather than memcpy, as dest and src may be same: */
3970 vpush_helper_func(TOK_memmove
);
3975 #ifdef CONFIG_TCC_BCHECK
3976 if (vtop
->r
& VT_MUSTBOUND
)
3979 vtop
->type
.t
= VT_PTR
;
3984 /* leave source on stack */
3986 } else if (ft
& VT_BITFIELD
) {
3987 /* bitfield store handling */
3989 /* save lvalue as expression result (example: s.b = s.a = n;) */
3990 vdup(), vtop
[-1] = vtop
[-2];
3992 bit_pos
= BIT_POS(ft
);
3993 bit_size
= BIT_SIZE(ft
);
3994 /* remove bit field info to avoid loops */
3995 vtop
[-1].type
.t
= ft
& ~VT_STRUCT_MASK
;
3997 if (dbt
== VT_BOOL
) {
3998 gen_cast(&vtop
[-1].type
);
3999 vtop
[-1].type
.t
= (vtop
[-1].type
.t
& ~VT_BTYPE
) | (VT_BYTE
| VT_UNSIGNED
);
4001 r
= adjust_bf(vtop
- 1, bit_pos
, bit_size
);
4002 if (dbt
!= VT_BOOL
) {
4003 gen_cast(&vtop
[-1].type
);
4004 dbt
= vtop
[-1].type
.t
& VT_BTYPE
;
4006 if (r
== VT_STRUCT
) {
4007 store_packed_bf(bit_pos
, bit_size
);
4009 unsigned long long mask
= (1ULL << bit_size
) - 1;
4010 if (dbt
!= VT_BOOL
) {
4012 if (dbt
== VT_LLONG
)
4015 vpushi((unsigned)mask
);
4022 /* duplicate destination */
4025 /* load destination, mask and or with source */
4026 if (dbt
== VT_LLONG
)
4027 vpushll(~(mask
<< bit_pos
));
4029 vpushi(~((unsigned)mask
<< bit_pos
));
4034 /* ... and discard */
4037 } else if (dbt
== VT_VOID
) {
4040 /* optimize char/short casts */
4042 if ((dbt
== VT_BYTE
|| dbt
== VT_SHORT
)
4043 && is_integer_btype(sbt
)
4045 if ((vtop
->r
& VT_MUSTCAST
)
4046 && btype_size(dbt
) > btype_size(sbt
)
4048 force_charshort_cast();
4051 gen_cast(&vtop
[-1].type
);
4054 #ifdef CONFIG_TCC_BCHECK
4055 /* bound check case */
4056 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4062 gv(RC_TYPE(dbt
)); /* generate value */
4065 vtop
->r
|= BFVAL(VT_MUSTCAST
, (sbt
== VT_LLONG
) + 1);
4066 //tcc_warning("deley cast %x -> %x", sbt, dbt);
4067 vtop
->type
.t
= ft
& VT_TYPE
;
4070 /* if lvalue was saved on stack, must read it */
4071 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4073 r
= get_reg(RC_INT
);
4074 sv
.type
.t
= VT_PTRDIFF_T
;
4075 sv
.r
= VT_LOCAL
| VT_LVAL
;
4076 sv
.c
.i
= vtop
[-1].c
.i
;
4078 vtop
[-1].r
= r
| VT_LVAL
;
4081 r
= vtop
->r
& VT_VALMASK
;
4082 /* two word case handling :
4083 store second register at word + 4 (or +8 for x86-64) */
4084 if (USING_TWO_WORDS(dbt
)) {
4085 int load_type
= (dbt
== VT_QFLOAT
) ? VT_DOUBLE
: VT_PTRDIFF_T
;
4086 vtop
[-1].type
.t
= load_type
;
4089 /* convert to int to increment easily */
4090 vtop
->type
.t
= VT_PTRDIFF_T
;
4096 vtop
[-1].type
.t
= load_type
;
4097 /* XXX: it works because r2 is spilled last ! */
4098 store(vtop
->r2
, vtop
- 1);
4104 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4108 /* post defines POST/PRE add. c is the token ++ or -- */
4109 ST_FUNC
void inc(int post
, int c
)
4112 vdup(); /* save lvalue */
4114 gv_dup(); /* duplicate value */
4119 vpushi(c
- TOK_MID
);
4121 vstore(); /* store value */
4123 vpop(); /* if post op, return saved value */
4126 ST_FUNC
void parse_mult_str (CString
*astr
, const char *msg
)
4128 /* read the string */
4132 while (tok
== TOK_STR
) {
4133 /* XXX: add \0 handling too ? */
4134 cstr_cat(astr
, tokc
.str
.data
, -1);
4137 cstr_ccat(astr
, '\0');
4140 /* If I is >= 1 and a power of two, returns log2(i)+1.
4141 If I is 0 returns 0. */
4142 ST_FUNC
int exact_log2p1(int i
)
4147 for (ret
= 1; i
>= 1 << 8; ret
+= 8)
4158 /* Parse __attribute__((...)) GNUC extension. */
4159 static void parse_attribute(AttributeDef
*ad
)
4165 if (tok
!= TOK_ATTRIBUTE1
&& tok
!= TOK_ATTRIBUTE2
)
4170 while (tok
!= ')') {
4171 if (tok
< TOK_IDENT
)
4172 expect("attribute name");
4184 tcc_warning("implicit declaration of function '%s'",
4185 get_tok_str(tok
, &tokc
));
4186 s
= external_global_sym(tok
, &func_old_type
);
4187 } else if ((s
->type
.t
& VT_BTYPE
) != VT_FUNC
)
4188 tcc_error("'%s' is not declared as function", get_tok_str(tok
, &tokc
));
4189 ad
->cleanup_func
= s
;
4194 case TOK_CONSTRUCTOR1
:
4195 case TOK_CONSTRUCTOR2
:
4196 ad
->f
.func_ctor
= 1;
4198 case TOK_DESTRUCTOR1
:
4199 case TOK_DESTRUCTOR2
:
4200 ad
->f
.func_dtor
= 1;
4202 case TOK_ALWAYS_INLINE1
:
4203 case TOK_ALWAYS_INLINE2
:
4204 ad
->f
.func_alwinl
= 1;
4209 parse_mult_str(&astr
, "section name");
4210 ad
->section
= find_section(tcc_state
, (char *)astr
.data
);
4217 parse_mult_str(&astr
, "alias(\"target\")");
4218 ad
->alias_target
= /* save string as token, for later */
4219 tok_alloc((char*)astr
.data
, astr
.size
-1)->tok
;
4223 case TOK_VISIBILITY1
:
4224 case TOK_VISIBILITY2
:
4226 parse_mult_str(&astr
,
4227 "visibility(\"default|hidden|internal|protected\")");
4228 if (!strcmp (astr
.data
, "default"))
4229 ad
->a
.visibility
= STV_DEFAULT
;
4230 else if (!strcmp (astr
.data
, "hidden"))
4231 ad
->a
.visibility
= STV_HIDDEN
;
4232 else if (!strcmp (astr
.data
, "internal"))
4233 ad
->a
.visibility
= STV_INTERNAL
;
4234 else if (!strcmp (astr
.data
, "protected"))
4235 ad
->a
.visibility
= STV_PROTECTED
;
4237 expect("visibility(\"default|hidden|internal|protected\")");
4246 if (n
<= 0 || (n
& (n
- 1)) != 0)
4247 tcc_error("alignment must be a positive power of two");
4252 ad
->a
.aligned
= exact_log2p1(n
);
4253 if (n
!= 1 << (ad
->a
.aligned
- 1))
4254 tcc_error("alignment of %d is larger than implemented", n
);
4266 /* currently, no need to handle it because tcc does not
4267 track unused objects */
4271 ad
->f
.func_noreturn
= 1;
4276 ad
->f
.func_call
= FUNC_CDECL
;
4281 ad
->f
.func_call
= FUNC_STDCALL
;
4283 #ifdef TCC_TARGET_I386
4293 ad
->f
.func_call
= FUNC_FASTCALL1
+ n
- 1;
4299 ad
->f
.func_call
= FUNC_FASTCALLW
;
4306 ad
->attr_mode
= VT_LLONG
+ 1;
4309 ad
->attr_mode
= VT_BYTE
+ 1;
4312 ad
->attr_mode
= VT_SHORT
+ 1;
4316 ad
->attr_mode
= VT_INT
+ 1;
4319 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok
, NULL
));
4326 ad
->a
.dllexport
= 1;
4328 case TOK_NODECORATE
:
4329 ad
->a
.nodecorate
= 1;
4332 ad
->a
.dllimport
= 1;
4335 if (tcc_state
->warn_unsupported
)
4336 tcc_warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4337 /* skip parameters */
4339 int parenthesis
= 0;
4343 else if (tok
== ')')
4346 } while (parenthesis
&& tok
!= -1);
4359 static Sym
* find_field (CType
*type
, int v
, int *cumofs
)
4363 while ((s
= s
->next
) != NULL
) {
4364 if ((s
->v
& SYM_FIELD
) &&
4365 (s
->type
.t
& VT_BTYPE
) == VT_STRUCT
&&
4366 (s
->v
& ~SYM_FIELD
) >= SYM_FIRST_ANOM
) {
4367 Sym
*ret
= find_field (&s
->type
, v
, cumofs
);
4379 static void check_fields (CType
*type
, int check
)
4383 while ((s
= s
->next
) != NULL
) {
4384 int v
= s
->v
& ~SYM_FIELD
;
4385 if (v
< SYM_FIRST_ANOM
) {
4386 TokenSym
*ts
= table_ident
[v
- TOK_IDENT
];
4387 if (check
&& (ts
->tok
& SYM_FIELD
))
4388 tcc_error("duplicate member '%s'", get_tok_str(v
, NULL
));
4389 ts
->tok
^= SYM_FIELD
;
4390 } else if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
)
4391 check_fields (&s
->type
, check
);
4395 static void struct_layout(CType
*type
, AttributeDef
*ad
)
4397 int size
, align
, maxalign
, offset
, c
, bit_pos
, bit_size
;
4398 int packed
, a
, bt
, prevbt
, prev_bit_size
;
4399 int pcc
= !tcc_state
->ms_bitfields
;
4400 int pragma_pack
= *tcc_state
->pack_stack_ptr
;
4407 prevbt
= VT_STRUCT
; /* make it never match */
4412 for (f
= type
->ref
->next
; f
; f
= f
->next
) {
4413 if (f
->type
.t
& VT_BITFIELD
)
4414 bit_size
= BIT_SIZE(f
->type
.t
);
4417 size
= type_size(&f
->type
, &align
);
4418 a
= f
->a
.aligned
? 1 << (f
->a
.aligned
- 1) : 0;
4421 if (pcc
&& bit_size
== 0) {
4422 /* in pcc mode, packing does not affect zero-width bitfields */
4425 /* in pcc mode, attribute packed overrides if set. */
4426 if (pcc
&& (f
->a
.packed
|| ad
->a
.packed
))
4429 /* pragma pack overrides align if lesser and packs bitfields always */
4432 if (pragma_pack
< align
)
4433 align
= pragma_pack
;
4434 /* in pcc mode pragma pack also overrides individual align */
4435 if (pcc
&& pragma_pack
< a
)
4439 /* some individual align was specified */
4443 if (type
->ref
->type
.t
== VT_UNION
) {
4444 if (pcc
&& bit_size
>= 0)
4445 size
= (bit_size
+ 7) >> 3;
4450 } else if (bit_size
< 0) {
4452 c
+= (bit_pos
+ 7) >> 3;
4453 c
= (c
+ align
- 1) & -align
;
4462 /* A bit-field. Layout is more complicated. There are two
4463 options: PCC (GCC) compatible and MS compatible */
4465 /* In PCC layout a bit-field is placed adjacent to the
4466 preceding bit-fields, except if:
4468 - an individual alignment was given
4469 - it would overflow its base type container and
4470 there is no packing */
4471 if (bit_size
== 0) {
4473 c
= (c
+ ((bit_pos
+ 7) >> 3) + align
- 1) & -align
;
4475 } else if (f
->a
.aligned
) {
4477 } else if (!packed
) {
4479 int ofs
= ((c
* 8 + bit_pos
) % a8
+ bit_size
+ a8
- 1) / a8
;
4480 if (ofs
> size
/ align
)
4484 /* in pcc mode, long long bitfields have type int if they fit */
4485 if (size
== 8 && bit_size
<= 32)
4486 f
->type
.t
= (f
->type
.t
& ~VT_BTYPE
) | VT_INT
, size
= 4;
4488 while (bit_pos
>= align
* 8)
4489 c
+= align
, bit_pos
-= align
* 8;
4492 /* In PCC layout named bit-fields influence the alignment
4493 of the containing struct using the base types alignment,
4494 except for packed fields (which here have correct align). */
4495 if (f
->v
& SYM_FIRST_ANOM
4496 // && bit_size // ??? gcc on ARM/rpi does that
4501 bt
= f
->type
.t
& VT_BTYPE
;
4502 if ((bit_pos
+ bit_size
> size
* 8)
4503 || (bit_size
> 0) == (bt
!= prevbt
)
4505 c
= (c
+ align
- 1) & -align
;
4508 /* In MS bitfield mode a bit-field run always uses
4509 at least as many bits as the underlying type.
4510 To start a new run it's also required that this
4511 or the last bit-field had non-zero width. */
4512 if (bit_size
|| prev_bit_size
)
4515 /* In MS layout the records alignment is normally
4516 influenced by the field, except for a zero-width
4517 field at the start of a run (but by further zero-width
4518 fields it is again). */
4519 if (bit_size
== 0 && prevbt
!= bt
)
4522 prev_bit_size
= bit_size
;
4525 f
->type
.t
= (f
->type
.t
& ~(0x3f << VT_STRUCT_SHIFT
))
4526 | (bit_pos
<< VT_STRUCT_SHIFT
);
4527 bit_pos
+= bit_size
;
4529 if (align
> maxalign
)
4533 printf("set field %s offset %-2d size %-2d align %-2d",
4534 get_tok_str(f
->v
& ~SYM_FIELD
, NULL
), offset
, size
, align
);
4535 if (f
->type
.t
& VT_BITFIELD
) {
4536 printf(" pos %-2d bits %-2d",
4549 c
+= (bit_pos
+ 7) >> 3;
4551 /* store size and alignment */
4552 a
= bt
= ad
->a
.aligned
? 1 << (ad
->a
.aligned
- 1) : 1;
4556 if (pragma_pack
&& pragma_pack
< maxalign
&& 0 == pcc
) {
4557 /* can happen if individual align for some member was given. In
4558 this case MSVC ignores maxalign when aligning the size */
4563 c
= (c
+ a
- 1) & -a
;
4567 printf("struct size %-2d align %-2d\n\n", c
, a
), fflush(stdout
);
4570 /* check whether we can access bitfields by their type */
4571 for (f
= type
->ref
->next
; f
; f
= f
->next
) {
4575 if (0 == (f
->type
.t
& VT_BITFIELD
))
4579 bit_size
= BIT_SIZE(f
->type
.t
);
4582 bit_pos
= BIT_POS(f
->type
.t
);
4583 size
= type_size(&f
->type
, &align
);
4584 if (bit_pos
+ bit_size
<= size
* 8 && f
->c
+ size
<= c
)
4587 /* try to access the field using a different type */
4588 c0
= -1, s
= align
= 1;
4591 px
= f
->c
* 8 + bit_pos
;
4592 cx
= (px
>> 3) & -align
;
4593 px
= px
- (cx
<< 3);
4596 s
= (px
+ bit_size
+ 7) >> 3;
4606 s
= type_size(&t
, &align
);
4610 if (px
+ bit_size
<= s
* 8 && cx
+ s
<= c
) {
4611 /* update offset and bit position */
4614 f
->type
.t
= (f
->type
.t
& ~(0x3f << VT_STRUCT_SHIFT
))
4615 | (bit_pos
<< VT_STRUCT_SHIFT
);
4619 printf("FIX field %s offset %-2d size %-2d align %-2d "
4620 "pos %-2d bits %-2d\n",
4621 get_tok_str(f
->v
& ~SYM_FIELD
, NULL
),
4622 cx
, s
, align
, px
, bit_size
);
4625 /* fall back to load/store single-byte wise */
4626 f
->auxtype
= VT_STRUCT
;
4628 printf("FIX field %s : load byte-wise\n",
4629 get_tok_str(f
->v
& ~SYM_FIELD
, NULL
));
4635 /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
4636 static void struct_decl(CType
*type
, int u
)
4638 int v
, c
, size
, align
, flexible
;
4639 int bit_size
, bsize
, bt
;
4641 AttributeDef ad
, ad1
;
4644 memset(&ad
, 0, sizeof ad
);
4646 parse_attribute(&ad
);
4650 /* struct already defined ? return it */
4652 expect("struct/union/enum name");
4654 if (s
&& (s
->sym_scope
== local_scope
|| tok
!= '{')) {
4657 if (u
== VT_ENUM
&& IS_ENUM(s
->type
.t
))
4659 tcc_error("redefinition of '%s'", get_tok_str(v
, NULL
));
4664 /* Record the original enum/struct/union token. */
4665 type1
.t
= u
== VT_ENUM
? u
| VT_INT
| VT_UNSIGNED
: u
;
4667 /* we put an undefined size for struct/union */
4668 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
4669 s
->r
= 0; /* default alignment is zero as gcc */
4671 type
->t
= s
->type
.t
;
4677 tcc_error("struct/union/enum already defined");
4679 /* cannot be empty */
4680 /* non empty enums are not allowed */
4683 long long ll
= 0, pl
= 0, nl
= 0;
4686 /* enum symbols have static storage */
4687 t
.t
= VT_INT
|VT_STATIC
|VT_ENUM_VAL
;
4691 expect("identifier");
4693 if (ss
&& !local_stack
)
4694 tcc_error("redefinition of enumerator '%s'",
4695 get_tok_str(v
, NULL
));
4699 ll
= expr_const64();
4701 ss
= sym_push(v
, &t
, VT_CONST
, 0);
4703 *ps
= ss
, ps
= &ss
->next
;
4712 /* NOTE: we accept a trailing comma */
4717 /* set integral type of the enum */
4720 if (pl
!= (unsigned)pl
)
4721 t
.t
= (LONG_SIZE
==8 ? VT_LLONG
|VT_LONG
: VT_LLONG
);
4723 } else if (pl
!= (int)pl
|| nl
!= (int)nl
)
4724 t
.t
= (LONG_SIZE
==8 ? VT_LLONG
|VT_LONG
: VT_LLONG
);
4725 s
->type
.t
= type
->t
= t
.t
| VT_ENUM
;
4727 /* set type for enum members */
4728 for (ss
= s
->next
; ss
; ss
= ss
->next
) {
4730 if (ll
== (int)ll
) /* default is int if it fits */
4732 if (t
.t
& VT_UNSIGNED
) {
4733 ss
->type
.t
|= VT_UNSIGNED
;
4734 if (ll
== (unsigned)ll
)
4737 ss
->type
.t
= (ss
->type
.t
& ~VT_BTYPE
)
4738 | (LONG_SIZE
==8 ? VT_LLONG
|VT_LONG
: VT_LLONG
);
4743 while (tok
!= '}') {
4744 if (!parse_btype(&btype
, &ad1
)) {
4750 tcc_error("flexible array member '%s' not at the end of struct",
4751 get_tok_str(v
, NULL
));
4757 type_decl(&type1
, &ad1
, &v
, TYPE_DIRECT
);
4759 if ((type1
.t
& VT_BTYPE
) != VT_STRUCT
)
4760 expect("identifier");
4762 int v
= btype
.ref
->v
;
4763 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
4764 if (tcc_state
->ms_extensions
== 0)
4765 expect("identifier");
4769 if (type_size(&type1
, &align
) < 0) {
4770 if ((u
== VT_STRUCT
) && (type1
.t
& VT_ARRAY
) && c
)
4773 tcc_error("field '%s' has incomplete type",
4774 get_tok_str(v
, NULL
));
4776 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
4777 (type1
.t
& VT_BTYPE
) == VT_VOID
||
4778 (type1
.t
& VT_STORAGE
))
4779 tcc_error("invalid type for '%s'",
4780 get_tok_str(v
, NULL
));
4784 bit_size
= expr_const();
4785 /* XXX: handle v = 0 case for messages */
4787 tcc_error("negative width in bit-field '%s'",
4788 get_tok_str(v
, NULL
));
4789 if (v
&& bit_size
== 0)
4790 tcc_error("zero width for bit-field '%s'",
4791 get_tok_str(v
, NULL
));
4792 parse_attribute(&ad1
);
4794 size
= type_size(&type1
, &align
);
4795 if (bit_size
>= 0) {
4796 bt
= type1
.t
& VT_BTYPE
;
4802 tcc_error("bitfields must have scalar type");
4804 if (bit_size
> bsize
) {
4805 tcc_error("width of '%s' exceeds its type",
4806 get_tok_str(v
, NULL
));
4807 } else if (bit_size
== bsize
4808 && !ad
.a
.packed
&& !ad1
.a
.packed
) {
4809 /* no need for bit fields */
4811 } else if (bit_size
== 64) {
4812 tcc_error("field width 64 not implemented");
4814 type1
.t
= (type1
.t
& ~VT_STRUCT_MASK
)
4816 | (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4819 if (v
!= 0 || (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
4820 /* Remember we've seen a real field to check
4821 for placement of flexible array member. */
4824 /* If member is a struct or bit-field, enforce
4825 placing into the struct (as anonymous). */
4827 ((type1
.t
& VT_BTYPE
) == VT_STRUCT
||
4832 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, 0);
4837 if (tok
== ';' || tok
== TOK_EOF
)
4844 parse_attribute(&ad
);
4845 if (ad
.cleanup_func
) {
4846 tcc_warning("attribute '__cleanup__' ignored on type");
4848 check_fields(type
, 1);
4849 check_fields(type
, 0);
4850 struct_layout(type
, &ad
);
4855 static void sym_to_attr(AttributeDef
*ad
, Sym
*s
)
4857 merge_symattr(&ad
->a
, &s
->a
);
4858 merge_funcattr(&ad
->f
, &s
->f
);
4861 /* Add type qualifiers to a type. If the type is an array then the qualifiers
4862 are added to the element type, copied because it could be a typedef. */
4863 static void parse_btype_qualify(CType
*type
, int qualifiers
)
4865 while (type
->t
& VT_ARRAY
) {
4866 type
->ref
= sym_push(SYM_FIELD
, &type
->ref
->type
, 0, type
->ref
->c
);
4867 type
= &type
->ref
->type
;
4869 type
->t
|= qualifiers
;
4872 /* return 0 if no type declaration. otherwise, return the basic type
4875 static int parse_btype(CType
*type
, AttributeDef
*ad
)
4877 int t
, u
, bt
, st
, type_found
, typespec_found
, g
, n
;
4881 memset(ad
, 0, sizeof(AttributeDef
));
4891 /* currently, we really ignore extension */
4901 if (u
== VT_SHORT
|| u
== VT_LONG
) {
4902 if (st
!= -1 || (bt
!= -1 && bt
!= VT_INT
))
4903 tmbt
: tcc_error("too many basic types");
4906 if (bt
!= -1 || (st
!= -1 && u
!= VT_INT
))
4911 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | u
;
4928 memset(&ad1
, 0, sizeof(AttributeDef
));
4929 if (parse_btype(&type1
, &ad1
)) {
4930 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
4932 n
= 1 << (ad1
.a
.aligned
- 1);
4934 type_size(&type1
, &n
);
4937 if (n
<= 0 || (n
& (n
- 1)) != 0)
4938 tcc_error("alignment must be a positive power of two");
4941 ad
->a
.aligned
= exact_log2p1(n
);
4945 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4946 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | VT_LDOUBLE
;
4947 } else if ((t
& (VT_BTYPE
|VT_LONG
)) == VT_LONG
) {
4948 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | VT_LLONG
;
4955 #ifdef TCC_TARGET_ARM64
4957 /* GCC's __uint128_t appears in some Linux header files. Make it a
4958 synonym for long double to get the size and alignment right. */
4969 if ((t
& (VT_BTYPE
|VT_LONG
)) == VT_LONG
) {
4970 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | VT_LDOUBLE
;
4978 struct_decl(&type1
, VT_ENUM
);
4981 type
->ref
= type1
.ref
;
4984 struct_decl(&type1
, VT_STRUCT
);
4987 struct_decl(&type1
, VT_UNION
);
4990 /* type modifiers */
4995 parse_btype_qualify(type
, VT_CONSTANT
);
5003 parse_btype_qualify(type
, VT_VOLATILE
);
5010 if ((t
& (VT_DEFSIGN
|VT_UNSIGNED
)) == (VT_DEFSIGN
|VT_UNSIGNED
))
5011 tcc_error("signed and unsigned modifier");
5024 if ((t
& (VT_DEFSIGN
|VT_UNSIGNED
)) == VT_DEFSIGN
)
5025 tcc_error("signed and unsigned modifier");
5026 t
|= VT_DEFSIGN
| VT_UNSIGNED
;
5042 if (t
& (VT_EXTERN
|VT_STATIC
|VT_TYPEDEF
) & ~g
)
5043 tcc_error("multiple storage classes");
5055 ad
->f
.func_noreturn
= 1;
5057 /* GNUC attribute */
5058 case TOK_ATTRIBUTE1
:
5059 case TOK_ATTRIBUTE2
:
5060 parse_attribute(ad
);
5061 if (ad
->attr_mode
) {
5062 u
= ad
->attr_mode
-1;
5063 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | u
;
5071 parse_expr_type(&type1
);
5072 /* remove all storage modifiers except typedef */
5073 type1
.t
&= ~(VT_STORAGE
&~VT_TYPEDEF
);
5075 sym_to_attr(ad
, type1
.ref
);
5081 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
5085 if (tok
== ':' && !in_generic
) {
5086 /* ignore if it's a label */
5091 t
&= ~(VT_BTYPE
|VT_LONG
);
5092 u
= t
& ~(VT_CONSTANT
| VT_VOLATILE
), t
^= u
;
5093 type
->t
= (s
->type
.t
& ~VT_TYPEDEF
) | u
;
5094 type
->ref
= s
->type
.ref
;
5096 parse_btype_qualify(type
, t
);
5098 /* get attributes from typedef */
5107 if (tcc_state
->char_is_unsigned
) {
5108 if ((t
& (VT_DEFSIGN
|VT_BTYPE
)) == VT_BYTE
)
5111 /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
5112 bt
= t
& (VT_BTYPE
|VT_LONG
);
5114 t
|= LONG_SIZE
== 8 ? VT_LLONG
: VT_INT
;
5115 #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
5116 if (bt
== VT_LDOUBLE
)
5117 t
= (t
& ~(VT_BTYPE
|VT_LONG
)) | (VT_DOUBLE
|VT_LONG
);
5123 /* convert a function parameter type (array to pointer and function to
5124 function pointer) */
5125 static inline void convert_parameter_type(CType
*pt
)
5127 /* remove const and volatile qualifiers (XXX: const could be used
5128 to indicate a const function parameter */
5129 pt
->t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
5130 /* array must be transformed to pointer according to ANSI C */
5132 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
5137 ST_FUNC
void parse_asm_str(CString
*astr
)
5140 parse_mult_str(astr
, "string constant");
5143 /* Parse an asm label and return the token */
5144 static int asm_label_instr(void)
5150 parse_asm_str(&astr
);
5153 printf("asm_alias: \"%s\"\n", (char *)astr
.data
);
5155 v
= tok_alloc(astr
.data
, astr
.size
- 1)->tok
;
5160 static int post_type(CType
*type
, AttributeDef
*ad
, int storage
, int td
)
5162 int n
, l
, t1
, arg_size
, align
, unused_align
;
5163 Sym
**plast
, *s
, *first
;
5168 /* function type, or recursive declarator (return if so) */
5170 if (td
&& !(td
& TYPE_ABSTRACT
))
5174 else if (parse_btype(&pt
, &ad1
))
5177 merge_attr (ad
, &ad1
);
5186 /* read param name and compute offset */
5187 if (l
!= FUNC_OLD
) {
5188 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
5190 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
5191 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
5192 tcc_error("parameter declared as void");
5196 expect("identifier");
5197 pt
.t
= VT_VOID
; /* invalid type */
5201 convert_parameter_type(&pt
);
5202 arg_size
+= (type_size(&pt
, &align
) + PTR_SIZE
- 1) / PTR_SIZE
;
5203 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
5209 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
5214 if (l
== FUNC_NEW
&& !parse_btype(&pt
, &ad1
))
5215 tcc_error("invalid type");
5218 /* if no parameters, then old type prototype */
5221 /* NOTE: const is ignored in returned type as it has a special
5222 meaning in gcc / C++ */
5223 type
->t
&= ~VT_CONSTANT
;
5224 /* some ancient pre-K&R C allows a function to return an array
5225 and the array brackets to be put after the arguments, such
5226 that "int c()[]" means something like "int[] c()" */
5229 skip(']'); /* only handle simple "[]" */
5232 /* we push a anonymous symbol which will contain the function prototype */
5233 ad
->f
.func_args
= arg_size
;
5234 ad
->f
.func_type
= l
;
5235 s
= sym_push(SYM_FIELD
, type
, 0, 0);
5241 } else if (tok
== '[') {
5242 int saved_nocode_wanted
= nocode_wanted
;
5243 /* array definition */
5246 /* XXX The optional type-quals and static should only be accepted
5247 in parameter decls. The '*' as well, and then even only
5248 in prototypes (not function defs). */
5250 case TOK_RESTRICT1
: case TOK_RESTRICT2
: case TOK_RESTRICT3
:
5265 if (!local_stack
|| (storage
& VT_STATIC
))
5266 vpushi(expr_const());
5268 /* VLAs (which can only happen with local_stack && !VT_STATIC)
5269 length must always be evaluated, even under nocode_wanted,
5270 so that its size slot is initialized (e.g. under sizeof
5275 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
5278 tcc_error("invalid array size");
5280 if (!is_integer_btype(vtop
->type
.t
& VT_BTYPE
))
5281 tcc_error("size of variable length array should be an integer");
5287 /* parse next post type */
5288 post_type(type
, ad
, storage
, 0);
5290 if ((type
->t
& VT_BTYPE
) == VT_FUNC
)
5291 tcc_error("declaration of an array of functions");
5292 if ((type
->t
& VT_BTYPE
) == VT_VOID
5293 || type_size(type
, &unused_align
) < 0)
5294 tcc_error("declaration of an array of incomplete type elements");
5296 t1
|= type
->t
& VT_VLA
;
5300 tcc_error("need explicit inner array size in VLAs");
5301 loc
-= type_size(&int_type
, &align
);
5305 vla_runtime_type_size(type
, &align
);
5307 vset(&int_type
, VT_LOCAL
|VT_LVAL
, n
);
5313 nocode_wanted
= saved_nocode_wanted
;
5315 /* we push an anonymous symbol which will contain the array
5317 s
= sym_push(SYM_FIELD
, type
, 0, n
);
5318 type
->t
= (t1
? VT_VLA
: VT_ARRAY
) | VT_PTR
;
5324 /* Parse a type declarator (except basic type), and return the type
5325 in 'type'. 'td' is a bitmask indicating which kind of type decl is
5326 expected. 'type' should contain the basic type. 'ad' is the
5327 attribute definition of the basic type. It can be modified by
5328 type_decl(). If this (possibly abstract) declarator is a pointer chain
5329 it returns the innermost pointed to type (equals *type, but is a different
5330 pointer), otherwise returns type itself, that's used for recursive calls. */
5331 static CType
*type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
5334 int qualifiers
, storage
;
5336 /* recursive type, remove storage bits first, apply them later again */
5337 storage
= type
->t
& VT_STORAGE
;
5338 type
->t
&= ~VT_STORAGE
;
5341 while (tok
== '*') {
5349 qualifiers
|= VT_CONSTANT
;
5354 qualifiers
|= VT_VOLATILE
;
5360 /* XXX: clarify attribute handling */
5361 case TOK_ATTRIBUTE1
:
5362 case TOK_ATTRIBUTE2
:
5363 parse_attribute(ad
);
5367 type
->t
|= qualifiers
;
5369 /* innermost pointed to type is the one for the first derivation */
5370 ret
= pointed_type(type
);
5374 /* This is possibly a parameter type list for abstract declarators
5375 ('int ()'), use post_type for testing this. */
5376 if (!post_type(type
, ad
, 0, td
)) {
5377 /* It's not, so it's a nested declarator, and the post operations
5378 apply to the innermost pointed to type (if any). */
5379 /* XXX: this is not correct to modify 'ad' at this point, but
5380 the syntax is not clear */
5381 parse_attribute(ad
);
5382 post
= type_decl(type
, ad
, v
, td
);
5386 } else if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
5387 /* type identifier */
5392 if (!(td
& TYPE_ABSTRACT
))
5393 expect("identifier");
5396 post_type(post
, ad
, storage
, 0);
5397 parse_attribute(ad
);
5402 /* indirection with full error checking and bound check */
5403 ST_FUNC
void indir(void)
5405 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
) {
5406 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
5410 if (vtop
->r
& VT_LVAL
)
5412 vtop
->type
= *pointed_type(&vtop
->type
);
5413 /* Arrays and functions are never lvalues */
5414 if (!(vtop
->type
.t
& (VT_ARRAY
| VT_VLA
))
5415 && (vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
5417 /* if bound checking, the referenced pointer must be checked */
5418 #ifdef CONFIG_TCC_BCHECK
5419 if (tcc_state
->do_bounds_check
)
5420 vtop
->r
|= VT_MUSTBOUND
;
5425 /* pass a parameter to a function and do type checking and casting */
5426 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
5431 func_type
= func
->f
.func_type
;
5432 if (func_type
== FUNC_OLD
||
5433 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
5434 /* default casting : only need to convert float to double */
5435 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
5436 gen_cast_s(VT_DOUBLE
);
5437 } else if (vtop
->type
.t
& VT_BITFIELD
) {
5438 type
.t
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5439 type
.ref
= vtop
->type
.ref
;
5441 } else if (vtop
->r
& VT_MUSTCAST
) {
5442 force_charshort_cast();
5444 } else if (arg
== NULL
) {
5445 tcc_error("too many arguments to function");
5448 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
5449 gen_assign_cast(&type
);
5453 /* parse an expression and return its type without any side effect. */
5454 static void expr_type(CType
*type
, void (*expr_fn
)(void))
5463 /* parse an expression of the form '(type)' or '(expr)' and return its
5465 static void parse_expr_type(CType
*type
)
5471 if (parse_btype(type
, &ad
)) {
5472 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
5474 expr_type(type
, gexpr
);
5479 static void parse_type(CType
*type
)
5484 if (!parse_btype(type
, &ad
)) {
5487 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
5490 static void parse_builtin_params(int nc
, const char *args
)
5499 while ((c
= *args
++)) {
5514 type
.t
= VT_CONSTANT
;
5520 type
.t
= VT_CONSTANT
;
5522 type
.t
|= char_type
.t
;
5534 gen_assign_cast(&type
);
5541 ST_FUNC
void unary(void)
5543 int n
, t
, align
, size
, r
, sizeof_caller
;
5548 /* generate line number info */
5549 if (tcc_state
->do_debug
)
5550 tcc_debug_line(tcc_state
);
5552 sizeof_caller
= in_sizeof
;
5555 /* XXX: GCC 2.95.3 does not generate a table although it should be
5563 #ifdef TCC_TARGET_PE
5564 t
= VT_SHORT
|VT_UNSIGNED
;
5572 vsetc(&type
, VT_CONST
, &tokc
);
5576 t
= VT_INT
| VT_UNSIGNED
;
5582 t
= VT_LLONG
| VT_UNSIGNED
;
5594 t
= (LONG_SIZE
== 8 ? VT_LLONG
: VT_INT
) | VT_LONG
;
5597 t
= (LONG_SIZE
== 8 ? VT_LLONG
: VT_INT
) | VT_LONG
| VT_UNSIGNED
;
5599 case TOK___FUNCTION__
:
5601 goto tok_identifier
;
5607 /* special function name identifier */
5608 len
= strlen(funcname
) + 1;
5609 /* generate char[len] type */
5614 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
5615 if (!NODATA_WANTED
) {
5616 ptr
= section_ptr_add(data_section
, len
);
5617 memcpy(ptr
, funcname
, len
);
5623 #ifdef TCC_TARGET_PE
5624 t
= VT_SHORT
| VT_UNSIGNED
;
5630 /* string parsing */
5632 if (tcc_state
->char_is_unsigned
)
5633 t
= VT_BYTE
| VT_UNSIGNED
;
5635 if (tcc_state
->warn_write_strings
)
5640 memset(&ad
, 0, sizeof(AttributeDef
));
5641 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
5646 if (parse_btype(&type
, &ad
)) {
5647 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
5649 /* check ISOC99 compound literal */
5651 /* data is allocated locally by default */
5656 /* all except arrays are lvalues */
5657 if (!(type
.t
& VT_ARRAY
))
5659 memset(&ad
, 0, sizeof(AttributeDef
));
5660 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
5662 if (sizeof_caller
) {
5669 } else if (tok
== '{') {
5670 int saved_nocode_wanted
= nocode_wanted
;
5671 if (const_wanted
&& !(nocode_wanted
& unevalmask
))
5673 if (0 == local_scope
)
5674 tcc_error("statement expression outside of function");
5675 /* save all registers */
5677 /* statement expression : we do not accept break/continue
5678 inside as GCC does. We do retain the nocode_wanted state,
5679 as statement expressions can't ever be entered from the
5680 outside, so any reactivation of code emission (from labels
5681 or loop heads) can be disabled again after the end of it. */
5683 nocode_wanted
= saved_nocode_wanted
;
5698 /* functions names must be treated as function pointers,
5699 except for unary '&' and sizeof. Since we consider that
5700 functions are not lvalues, we only have to handle it
5701 there and in function calls. */
5702 /* arrays can also be used although they are not lvalues */
5703 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
5704 !(vtop
->type
.t
& VT_ARRAY
))
5707 vtop
->sym
->a
.addrtaken
= 1;
5708 mk_pointer(&vtop
->type
);
5714 gen_test_zero(TOK_EQ
);
5725 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
5726 tcc_error("pointer not accepted for unary plus");
5727 /* In order to force cast, we add zero, except for floating point
5728 where we really need an noop (otherwise -0.0 will be transformed
5730 if (!is_float(vtop
->type
.t
)) {
5742 expr_type(&type
, unary
); /* Perform a in_sizeof = 0; */
5744 if (vtop
[1].r
& VT_SYM
)
5745 s
= vtop
[1].sym
; /* hack: accessing previous vtop */
5746 size
= type_size(&type
, &align
);
5747 if (s
&& s
->a
.aligned
)
5748 align
= 1 << (s
->a
.aligned
- 1);
5749 if (t
== TOK_SIZEOF
) {
5750 if (!(type
.t
& VT_VLA
)) {
5752 tcc_error("sizeof applied to an incomplete type");
5755 vla_runtime_type_size(&type
, &align
);
5760 vtop
->type
.t
|= VT_UNSIGNED
;
5763 case TOK_builtin_expect
:
5764 /* __builtin_expect is a no-op for now */
5765 parse_builtin_params(0, "ee");
5768 case TOK_builtin_types_compatible_p
:
5769 parse_builtin_params(0, "tt");
5770 vtop
[-1].type
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
5771 vtop
[0].type
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
5772 n
= is_compatible_types(&vtop
[-1].type
, &vtop
[0].type
);
5776 case TOK_builtin_choose_expr
:
5803 case TOK_builtin_constant_p
:
5804 parse_builtin_params(1, "e");
5805 n
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
&&
5806 !((vtop
->r
& VT_SYM
) && vtop
->sym
->a
.addrtaken
);
5810 case TOK_builtin_frame_address
:
5811 case TOK_builtin_return_address
:
5817 if (tok
!= TOK_CINT
) {
5818 tcc_error("%s only takes positive integers",
5819 tok1
== TOK_builtin_return_address
?
5820 "__builtin_return_address" :
5821 "__builtin_frame_address");
5823 level
= (uint32_t)tokc
.i
;
5828 vset(&type
, VT_LOCAL
, 0); /* local frame */
5830 #ifdef TCC_TARGET_RISCV64
5834 mk_pointer(&vtop
->type
);
5835 indir(); /* -> parent frame */
5837 if (tok1
== TOK_builtin_return_address
) {
5838 // assume return address is just above frame pointer on stack
5839 #ifdef TCC_TARGET_ARM
5842 #elif defined TCC_TARGET_RISCV64
5849 mk_pointer(&vtop
->type
);
5854 #ifdef TCC_TARGET_RISCV64
5855 case TOK_builtin_va_start
:
5856 parse_builtin_params(0, "ee");
5857 r
= vtop
->r
& VT_VALMASK
;
5861 tcc_error("__builtin_va_start expects a local variable");
5866 #ifdef TCC_TARGET_X86_64
5867 #ifdef TCC_TARGET_PE
5868 case TOK_builtin_va_start
:
5869 parse_builtin_params(0, "ee");
5870 r
= vtop
->r
& VT_VALMASK
;
5874 tcc_error("__builtin_va_start expects a local variable");
5876 vtop
->type
= char_pointer_type
;
5881 case TOK_builtin_va_arg_types
:
5882 parse_builtin_params(0, "t");
5883 vpushi(classify_x86_64_va_arg(&vtop
->type
));
5890 #ifdef TCC_TARGET_ARM64
5891 case TOK_builtin_va_start
: {
5892 parse_builtin_params(0, "ee");
5896 vtop
->type
.t
= VT_VOID
;
5899 case TOK_builtin_va_arg
: {
5900 parse_builtin_params(0, "et");
5908 case TOK___arm64_clear_cache
: {
5909 parse_builtin_params(0, "ee");
5912 vtop
->type
.t
= VT_VOID
;
5917 /* pre operations */
5928 if (is_float(vtop
->type
.t
)) {
5938 goto tok_identifier
;
5940 /* allow to take the address of a label */
5941 if (tok
< TOK_UIDENT
)
5942 expect("label identifier");
5943 s
= label_find(tok
);
5945 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
5947 if (s
->r
== LABEL_DECLARED
)
5948 s
->r
= LABEL_FORWARD
;
5951 s
->type
.t
= VT_VOID
;
5952 mk_pointer(&s
->type
);
5953 s
->type
.t
|= VT_STATIC
;
5955 vpushsym(&s
->type
, s
);
5961 CType controlling_type
;
5962 int has_default
= 0;
5965 TokenString
*str
= NULL
;
5966 int saved_const_wanted
= const_wanted
;
5971 expr_type(&controlling_type
, expr_eq
);
5972 controlling_type
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
| VT_ARRAY
);
5973 if ((controlling_type
.t
& VT_BTYPE
) == VT_FUNC
)
5974 mk_pointer(&controlling_type
);
5975 const_wanted
= saved_const_wanted
;
5979 if (tok
== TOK_DEFAULT
) {
5981 tcc_error("too many 'default'");
5987 AttributeDef ad_tmp
;
5992 parse_btype(&cur_type
, &ad_tmp
);
5995 type_decl(&cur_type
, &ad_tmp
, &itmp
, TYPE_ABSTRACT
);
5996 if (compare_types(&controlling_type
, &cur_type
, 0)) {
5998 tcc_error("type match twice");
6008 skip_or_save_block(&str
);
6010 skip_or_save_block(NULL
);
6017 type_to_str(buf
, sizeof buf
, &controlling_type
, NULL
);
6018 tcc_error("type '%s' does not match any association", buf
);
6020 begin_macro(str
, 1);
6029 // special qnan , snan and infinity values
6034 vtop
->type
.t
= VT_FLOAT
;
6039 goto special_math_val
;
6042 goto special_math_val
;
6049 expect("identifier");
6051 if (!s
|| IS_ASM_SYM(s
)) {
6052 const char *name
= get_tok_str(t
, NULL
);
6054 tcc_error("'%s' undeclared", name
);
6055 /* for simple function calls, we tolerate undeclared
6056 external reference to int() function */
6057 if (tcc_state
->warn_implicit_function_declaration
6058 #ifdef TCC_TARGET_PE
6059 /* people must be warned about using undeclared WINAPI functions
6060 (which usually start with uppercase letter) */
6061 || (name
[0] >= 'A' && name
[0] <= 'Z')
6064 tcc_warning("implicit declaration of function '%s'", name
);
6065 s
= external_global_sym(t
, &func_old_type
);
6069 /* A symbol that has a register is a local register variable,
6070 which starts out as VT_LOCAL value. */
6071 if ((r
& VT_VALMASK
) < VT_CONST
)
6072 r
= (r
& ~VT_VALMASK
) | VT_LOCAL
;
6074 vset(&s
->type
, r
, s
->c
);
6075 /* Point to s as backpointer (even without r&VT_SYM).
6076 Will be used by at least the x86 inline asm parser for
6082 } else if (r
== VT_CONST
&& IS_ENUM_VAL(s
->type
.t
)) {
6083 vtop
->c
.i
= s
->enum_val
;
6088 /* post operations */
6090 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
6093 } else if (tok
== '.' || tok
== TOK_ARROW
|| tok
== TOK_CDOUBLE
) {
6094 int qualifiers
, cumofs
= 0;
6096 if (tok
== TOK_ARROW
)
6098 qualifiers
= vtop
->type
.t
& (VT_CONSTANT
| VT_VOLATILE
);
6101 /* expect pointer on structure */
6102 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
6103 expect("struct or union");
6104 if (tok
== TOK_CDOUBLE
)
6105 expect("field name");
6107 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
6108 expect("field name");
6109 s
= find_field(&vtop
->type
, tok
, &cumofs
);
6111 tcc_error("field not found: %s", get_tok_str(tok
& ~SYM_FIELD
, &tokc
));
6112 /* add field offset to pointer */
6113 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
6114 vpushi(cumofs
+ s
->c
);
6116 /* change type to field type, and set to lvalue */
6117 vtop
->type
= s
->type
;
6118 vtop
->type
.t
|= qualifiers
;
6119 /* an array is never an lvalue */
6120 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6122 #ifdef CONFIG_TCC_BCHECK
6123 /* if bound checking, the referenced pointer must be checked */
6124 if (tcc_state
->do_bounds_check
)
6125 vtop
->r
|= VT_MUSTBOUND
;
6129 } else if (tok
== '[') {
6135 } else if (tok
== '(') {
6138 int nb_args
, ret_nregs
, ret_align
, regsize
, variadic
;
6141 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
6142 /* pointer test (no array accepted) */
6143 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
6144 vtop
->type
= *pointed_type(&vtop
->type
);
6145 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
6149 expect("function pointer");
6152 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
6154 /* get return type */
6157 sa
= s
->next
; /* first parameter */
6158 nb_args
= regsize
= 0;
6160 /* compute first implicit argument if a structure is returned */
6161 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
6162 variadic
= (s
->f
.func_type
== FUNC_ELLIPSIS
);
6163 ret_nregs
= gfunc_sret(&s
->type
, variadic
, &ret
.type
,
6164 &ret_align
, ®size
);
6165 if (ret_nregs
<= 0) {
6166 /* get some space for the returned structure */
6167 size
= type_size(&s
->type
, &align
);
6168 #ifdef TCC_TARGET_ARM64
6169 /* On arm64, a small struct is return in registers.
6170 It is much easier to write it to memory if we know
6171 that we are allowed to write some extra bytes, so
6172 round the allocated space up to a power of 2: */
6174 while (size
& (size
- 1))
6175 size
= (size
| (size
- 1)) + 1;
6177 loc
= (loc
- size
) & -align
;
6179 ret
.r
= VT_LOCAL
| VT_LVAL
;
6180 /* pass it as 'int' to avoid structure arg passing
6182 vseti(VT_LOCAL
, loc
);
6183 #ifdef CONFIG_TCC_BCHECK
6184 if (tcc_state
->do_bounds_check
)
6198 if (ret_nregs
> 0) {
6199 /* return in register */
6201 PUT_R_RET(&ret
, ret
.type
.t
);
6206 gfunc_param_typed(s
, sa
);
6216 tcc_error("too few arguments to function");
6218 gfunc_call(nb_args
);
6220 if (ret_nregs
< 0) {
6221 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
6222 #ifdef TCC_TARGET_RISCV64
6223 arch_transfer_ret_regs(1);
6227 for (r
= ret
.r
+ ret_nregs
+ !ret_nregs
; r
-- > ret
.r
;) {
6228 vsetc(&ret
.type
, r
, &ret
.c
);
6229 vtop
->r2
= ret
.r2
; /* Loop only happens when r2 is VT_CONST */
6232 /* handle packed struct return */
6233 if (((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) && ret_nregs
) {
6236 size
= type_size(&s
->type
, &align
);
6237 /* We're writing whole regs often, make sure there's enough
6238 space. Assume register size is power of 2. */
6239 if (regsize
> align
)
6241 loc
= (loc
- size
) & -align
;
6245 vset(&ret
.type
, VT_LOCAL
| VT_LVAL
, addr
+ offset
);
6249 if (--ret_nregs
== 0)
6253 vset(&s
->type
, VT_LOCAL
| VT_LVAL
, addr
);
6256 /* Promote char/short return values. This is matters only
6257 for calling function that were not compiled by TCC and
6258 only on some architectures. For those where it doesn't
6259 matter we expect things to be already promoted to int,
6261 t
= s
->type
.t
& VT_BTYPE
;
6262 if (t
== VT_BYTE
|| t
== VT_SHORT
|| t
== VT_BOOL
) {
6264 vtop
->r
|= BFVAL(VT_MUSTCAST
, 1);
6266 vtop
->type
.t
= VT_INT
;
6270 if (s
->f
.func_noreturn
)
6278 #ifndef precedence_parser /* original top-down parser */
6280 static void expr_prod(void)
6285 while ((t
= tok
) == '*' || t
== '/' || t
== '%') {
6292 static void expr_sum(void)
6297 while ((t
= tok
) == '+' || t
== '-') {
6304 static void expr_shift(void)
6309 while ((t
= tok
) == TOK_SHL
|| t
== TOK_SAR
) {
6316 static void expr_cmp(void)
6321 while (((t
= tok
) >= TOK_ULE
&& t
<= TOK_GT
) ||
6322 t
== TOK_ULT
|| t
== TOK_UGE
) {
6329 static void expr_cmpeq(void)
6334 while ((t
= tok
) == TOK_EQ
|| t
== TOK_NE
) {
6341 static void expr_and(void)
6344 while (tok
== '&') {
6351 static void expr_xor(void)
6354 while (tok
== '^') {
6361 static void expr_or(void)
6364 while (tok
== '|') {
6371 static void expr_landor(int op
);
6373 static void expr_land(void)
6376 if (tok
== TOK_LAND
)
6380 static void expr_lor(void)
6387 # define expr_landor_next(op) op == TOK_LAND ? expr_or() : expr_land()
6388 #else /* defined precedence_parser */
6389 # define expr_landor_next(op) unary(), expr_infix(precedence(op) + 1)
6390 # define expr_lor() unary(), expr_infix(1)
6392 static int precedence(int tok
)
6395 case TOK_LOR
: return 1;
6396 case TOK_LAND
: return 2;
6400 case TOK_EQ
: case TOK_NE
: return 6;
6401 relat
: case TOK_ULT
: case TOK_UGE
: return 7;
6402 case TOK_SHL
: case TOK_SAR
: return 8;
6403 case '+': case '-': return 9;
6404 case '*': case '/': case '%': return 10;
6406 if (tok
>= TOK_ULE
&& tok
<= TOK_GT
)
6411 static unsigned char prec
[256];
6412 static void init_prec(void)
6415 for (i
= 0; i
< 256; i
++)
6416 prec
[i
] = precedence(i
);
6418 #define precedence(i) ((unsigned)i < 256 ? prec[i] : 0)
6420 static void expr_landor(int op
);
6422 static void expr_infix(int p
)
6425 while ((p2
= precedence(t
)) >= p
) {
6426 if (t
== TOK_LOR
|| t
== TOK_LAND
) {
6431 if (precedence(tok
) > p2
)
6440 /* Assuming vtop is a value used in a conditional context
6441 (i.e. compared with zero) return 0 if it's false, 1 if
6442 true and -1 if it can't be statically determined. */
6443 static int condition_3way(void)
6446 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
&&
6447 (!(vtop
->r
& VT_SYM
) || !vtop
->sym
->a
.weak
)) {
6449 gen_cast_s(VT_BOOL
);
6456 static void expr_landor(int op
)
6458 int t
= 0, cc
= 1, f
= 0, i
= op
== TOK_LAND
, c
;
6460 c
= f
? i
: condition_3way();
6462 save_regs(1), cc
= 0;
6464 nocode_wanted
++, f
= 1;
6472 expr_landor_next(op
);
6484 static int is_cond_bool(SValue
*sv
)
6486 if ((sv
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
6487 && (sv
->type
.t
& VT_BTYPE
) == VT_INT
)
6488 return (unsigned)sv
->c
.i
< 2;
6489 if (sv
->r
== VT_CMP
)
6494 static void expr_cond(void)
6496 int tt
, u
, r1
, r2
, rc
, t1
, t2
, islv
, c
, g
;
6504 c
= condition_3way();
6505 g
= (tok
== ':' && gnu_ext
);
6515 /* needed to avoid having different registers saved in
6522 ncw_prev
= nocode_wanted
;
6528 if (c
< 0 && vtop
->r
== VT_CMP
) {
6535 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
6536 mk_pointer(&vtop
->type
);
6537 sv
= *vtop
; /* save value to handle it later */
6538 vtop
--; /* no vpop so that FP stack is not flushed */
6548 nocode_wanted
= ncw_prev
;
6554 if (c
< 0 && is_cond_bool(vtop
) && is_cond_bool(&sv
)) {
6555 if (sv
.r
== VT_CMP
) {
6566 nocode_wanted
= ncw_prev
;
6567 // tcc_warning("two conditions expr_cond");
6571 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
6572 mk_pointer(&vtop
->type
);
6574 /* cast operands to correct type according to ISOC rules */
6575 if (!combine_types(&type
, &sv
, vtop
, '?'))
6576 type_incompatibility_error(&sv
.type
, &vtop
->type
,
6577 "type mismatch in conditional expression (have '%s' and '%s')");
6578 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
6579 that `(expr ? a : b).mem` does not error with "lvalue expected" */
6580 islv
= (vtop
->r
& VT_LVAL
) && (sv
.r
& VT_LVAL
) && VT_STRUCT
== (type
.t
& VT_BTYPE
);
6582 /* now we convert second operand */
6586 mk_pointer(&vtop
->type
);
6588 } else if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
6592 rc
= RC_TYPE(type
.t
);
6593 /* for long longs, we use fixed registers to avoid having
6594 to handle a complicated move */
6595 if (USING_TWO_WORDS(type
.t
))
6596 rc
= RC_RET(type
.t
);
6604 nocode_wanted
= ncw_prev
;
6606 /* this is horrible, but we must also convert first
6612 mk_pointer(&vtop
->type
);
6614 } else if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
6620 move_reg(r2
, r1
, islv
? VT_PTR
: type
.t
);
6630 static void expr_eq(void)
6635 if ((t
= tok
) == '=' || TOK_ASSIGN(t
)) {
6643 gen_op(TOK_ASSIGN_OP(t
));
6649 ST_FUNC
void gexpr(void)
6660 /* parse a constant expression and return value in vtop. */
6661 static void expr_const1(void)
6664 nocode_wanted
+= unevalmask
+ 1;
6666 nocode_wanted
-= unevalmask
+ 1;
6670 /* parse an integer constant and return its value. */
6671 static inline int64_t expr_const64(void)
6675 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
6676 expect("constant expression");
6682 /* parse an integer constant and return its value.
6683 Complain if it doesn't fit 32bit (signed or unsigned). */
6684 ST_FUNC
int expr_const(void)
6687 int64_t wc
= expr_const64();
6689 if (c
!= wc
&& (unsigned)c
!= wc
)
6690 tcc_error("constant exceeds 32 bit");
6694 /* ------------------------------------------------------------------------- */
6695 /* return from function */
6697 #ifndef TCC_TARGET_ARM64
6698 static void gfunc_return(CType
*func_type
)
6700 if ((func_type
->t
& VT_BTYPE
) == VT_STRUCT
) {
6701 CType type
, ret_type
;
6702 int ret_align
, ret_nregs
, regsize
;
6703 ret_nregs
= gfunc_sret(func_type
, func_var
, &ret_type
,
6704 &ret_align
, ®size
);
6705 if (ret_nregs
< 0) {
6706 #ifdef TCC_TARGET_RISCV64
6707 arch_transfer_ret_regs(0);
6709 } else if (0 == ret_nregs
) {
6710 /* if returning structure, must copy it to implicit
6711 first pointer arg location */
6714 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
6717 /* copy structure value to pointer */
6720 /* returning structure packed into registers */
6721 int size
, addr
, align
, rc
;
6722 size
= type_size(func_type
,&align
);
6723 if ((vtop
->r
!= (VT_LOCAL
| VT_LVAL
) ||
6724 (vtop
->c
.i
& (ret_align
-1)))
6725 && (align
& (ret_align
-1))) {
6726 loc
= (loc
- size
) & -ret_align
;
6729 vset(&type
, VT_LOCAL
| VT_LVAL
, addr
);
6733 vset(&ret_type
, VT_LOCAL
| VT_LVAL
, addr
);
6735 vtop
->type
= ret_type
;
6736 rc
= RC_RET(ret_type
.t
);
6744 if (--ret_nregs
== 0)
6746 /* We assume that when a structure is returned in multiple
6747 registers, their classes are consecutive values of the
6750 vtop
->c
.i
+= regsize
;
6755 gv(RC_RET(func_type
->t
));
6757 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6761 static void check_func_return(void)
6763 if ((func_vt
.t
& VT_BTYPE
) == VT_VOID
)
6765 if (!strcmp (funcname
, "main")
6766 && (func_vt
.t
& VT_BTYPE
) == VT_INT
) {
6767 /* main returns 0 by default */
6769 gen_assign_cast(&func_vt
);
6770 gfunc_return(&func_vt
);
6772 tcc_warning("function might return no value: '%s'", funcname
);
6776 /* ------------------------------------------------------------------------- */
6779 static int case_cmpi(const void *pa
, const void *pb
)
6781 int64_t a
= (*(struct case_t
**) pa
)->v1
;
6782 int64_t b
= (*(struct case_t
**) pb
)->v1
;
6783 return a
< b
? -1 : a
> b
;
6786 static int case_cmpu(const void *pa
, const void *pb
)
6788 uint64_t a
= (uint64_t)(*(struct case_t
**) pa
)->v1
;
6789 uint64_t b
= (uint64_t)(*(struct case_t
**) pb
)->v1
;
6790 return a
< b
? -1 : a
> b
;
6793 static void gtst_addr(int t
, int a
)
6795 gsym_addr(gvtst(0, t
), a
);
6798 static void gcase(struct case_t
**base
, int len
, int *bsym
)
6802 int ll
= (vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
;
6819 gtst_addr(0, p
->sym
); /* v1 <= x <= v2 */
6821 gcase(base
, len
/2, bsym
);
6825 base
+= e
; len
-= e
;
6835 if (p
->v1
== p
->v2
) {
6837 gtst_addr(0, p
->sym
);
6847 gtst_addr(0, p
->sym
);
6851 *bsym
= gjmp(*bsym
);
6854 /* ------------------------------------------------------------------------- */
6855 /* __attribute__((cleanup(fn))) */
6857 static void try_call_scope_cleanup(Sym
*stop
)
6859 Sym
*cls
= cur_scope
->cl
.s
;
6861 for (; cls
!= stop
; cls
= cls
->ncl
) {
6862 Sym
*fs
= cls
->next
;
6863 Sym
*vs
= cls
->prev_tok
;
6865 vpushsym(&fs
->type
, fs
);
6866 vset(&vs
->type
, vs
->r
, vs
->c
);
6868 mk_pointer(&vtop
->type
);
6874 static void try_call_cleanup_goto(Sym
*cleanupstate
)
6879 if (!cur_scope
->cl
.s
)
6882 /* search NCA of both cleanup chains given parents and initial depth */
6883 ocd
= cleanupstate
? cleanupstate
->v
& ~SYM_FIELD
: 0;
6884 for (ccd
= cur_scope
->cl
.n
, oc
= cleanupstate
; ocd
> ccd
; --ocd
, oc
= oc
->ncl
)
6886 for (cc
= cur_scope
->cl
.s
; ccd
> ocd
; --ccd
, cc
= cc
->ncl
)
6888 for (; cc
!= oc
; cc
= cc
->ncl
, oc
= oc
->ncl
, --ccd
)
6891 try_call_scope_cleanup(cc
);
6894 /* call 'func' for each __attribute__((cleanup(func))) */
6895 static void block_cleanup(struct scope
*o
)
6899 for (pg
= &pending_gotos
; (g
= *pg
) && g
->c
> o
->cl
.n
;) {
6900 if (g
->prev_tok
->r
& LABEL_FORWARD
) {
6905 try_call_scope_cleanup(o
->cl
.s
);
6906 pcl
->jnext
= gjmp(0);
6908 goto remove_pending
;
6918 try_call_scope_cleanup(o
->cl
.s
);
6921 /* ------------------------------------------------------------------------- */
6924 static void vla_restore(int loc
)
6927 gen_vla_sp_restore(loc
);
6930 static void vla_leave(struct scope
*o
)
6932 if (o
->vla
.num
< cur_scope
->vla
.num
)
6933 vla_restore(o
->vla
.loc
);
6936 /* ------------------------------------------------------------------------- */
6939 void new_scope(struct scope
*o
)
6941 /* copy and link previous scope */
6943 o
->prev
= cur_scope
;
6946 /* record local declaration stack position */
6947 o
->lstk
= local_stack
;
6948 o
->llstk
= local_label_stack
;
6952 if (tcc_state
->do_debug
)
6953 tcc_debug_stabn(N_LBRAC
, ind
- func_ind
);
6956 void prev_scope(struct scope
*o
, int is_expr
)
6960 if (o
->cl
.s
!= o
->prev
->cl
.s
)
6961 block_cleanup(o
->prev
);
6963 /* pop locally defined labels */
6964 label_pop(&local_label_stack
, o
->llstk
, is_expr
);
6966 /* In the is_expr case (a statement expression is finished here),
6967 vtop might refer to symbols on the local_stack. Either via the
6968 type or via vtop->sym. We can't pop those nor any that in turn
6969 might be referred to. To make it easier we don't roll back
6970 any symbols in that case; some upper level call to block() will
6971 do that. We do have to remove such symbols from the lookup
6972 tables, though. sym_pop will do that. */
6974 /* pop locally defined symbols */
6975 pop_local_syms(&local_stack
, o
->lstk
, is_expr
, 0);
6976 cur_scope
= o
->prev
;
6979 if (tcc_state
->do_debug
)
6980 tcc_debug_stabn(N_RBRAC
, ind
- func_ind
);
6983 /* leave a scope via break/continue(/goto) */
6984 void leave_scope(struct scope
*o
)
6988 try_call_scope_cleanup(o
->cl
.s
);
6992 /* ------------------------------------------------------------------------- */
6993 /* call block from 'for do while' loops */
6995 static void lblock(int *bsym
, int *csym
)
6997 struct scope
*lo
= loop_scope
, *co
= cur_scope
;
6998 int *b
= co
->bsym
, *c
= co
->csym
;
7012 static void block(int is_expr
)
7014 int a
, b
, c
, d
, e
, t
;
7019 /* default return value is (void) */
7021 vtop
->type
.t
= VT_VOID
;
7026 /* If the token carries a value, next() might destroy it. Only with
7027 invalid code such as f(){"123"4;} */
7028 if (TOK_HAS_VALUE(t
))
7038 if (tok
== TOK_ELSE
) {
7043 gsym(d
); /* patch else jmp */
7048 } else if (t
== TOK_WHILE
) {
7060 } else if (t
== '{') {
7063 /* handle local labels declarations */
7064 while (tok
== TOK_LABEL
) {
7067 if (tok
< TOK_UIDENT
)
7068 expect("label identifier");
7069 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
7071 } while (tok
== ',');
7075 while (tok
!= '}') {
7084 prev_scope(&o
, is_expr
);
7087 else if (!nocode_wanted
)
7088 check_func_return();
7090 } else if (t
== TOK_RETURN
) {
7091 b
= (func_vt
.t
& VT_BTYPE
) != VT_VOID
;
7095 gen_assign_cast(&func_vt
);
7097 if (vtop
->type
.t
!= VT_VOID
)
7098 tcc_warning("void function returns a value");
7102 tcc_warning("'return' with no value");
7105 leave_scope(root_scope
);
7107 gfunc_return(&func_vt
);
7109 /* jump unless last stmt in top-level block */
7110 if (tok
!= '}' || local_scope
!= 1)
7114 } else if (t
== TOK_BREAK
) {
7116 if (!cur_scope
->bsym
)
7117 tcc_error("cannot break");
7118 if (cur_switch
&& cur_scope
->bsym
== cur_switch
->bsym
)
7119 leave_scope(cur_switch
->scope
);
7121 leave_scope(loop_scope
);
7122 *cur_scope
->bsym
= gjmp(*cur_scope
->bsym
);
7125 } else if (t
== TOK_CONTINUE
) {
7127 if (!cur_scope
->csym
)
7128 tcc_error("cannot continue");
7129 leave_scope(loop_scope
);
7130 *cur_scope
->csym
= gjmp(*cur_scope
->csym
);
7133 } else if (t
== TOK_FOR
) {
7138 /* c99 for-loop init decl? */
7139 if (!decl0(VT_LOCAL
, 1, NULL
)) {
7140 /* no, regular for-loop init expr */
7168 } else if (t
== TOK_DO
) {
7182 } else if (t
== TOK_SWITCH
) {
7183 struct switch_t
*sw
;
7185 sw
= tcc_mallocz(sizeof *sw
);
7187 sw
->scope
= cur_scope
;
7188 sw
->prev
= cur_switch
;
7194 sw
->sv
= *vtop
--; /* save switch value */
7197 b
= gjmp(0); /* jump to first case */
7199 a
= gjmp(a
); /* add implicit break */
7203 if (sw
->sv
.type
.t
& VT_UNSIGNED
)
7204 qsort(sw
->p
, sw
->n
, sizeof(void*), case_cmpu
);
7206 qsort(sw
->p
, sw
->n
, sizeof(void*), case_cmpi
);
7208 for (b
= 1; b
< sw
->n
; b
++)
7209 if (sw
->sv
.type
.t
& VT_UNSIGNED
7210 ? (uint64_t)sw
->p
[b
- 1]->v2
>= (uint64_t)sw
->p
[b
]->v1
7211 : sw
->p
[b
- 1]->v2
>= sw
->p
[b
]->v1
)
7212 tcc_error("duplicate case value");
7216 d
= 0, gcase(sw
->p
, sw
->n
, &d
);
7219 gsym_addr(d
, sw
->def_sym
);
7225 dynarray_reset(&sw
->p
, &sw
->n
);
7226 cur_switch
= sw
->prev
;
7229 } else if (t
== TOK_CASE
) {
7230 struct case_t
*cr
= tcc_malloc(sizeof(struct case_t
));
7233 cr
->v1
= cr
->v2
= expr_const64();
7234 if (gnu_ext
&& tok
== TOK_DOTS
) {
7236 cr
->v2
= expr_const64();
7237 if ((!(cur_switch
->sv
.type
.t
& VT_UNSIGNED
) && cr
->v2
< cr
->v1
)
7238 || (cur_switch
->sv
.type
.t
& VT_UNSIGNED
&& (uint64_t)cr
->v2
< (uint64_t)cr
->v1
))
7239 tcc_warning("empty case range");
7242 dynarray_add(&cur_switch
->p
, &cur_switch
->n
, cr
);
7245 goto block_after_label
;
7247 } else if (t
== TOK_DEFAULT
) {
7250 if (cur_switch
->def_sym
)
7251 tcc_error("too many 'default'");
7252 cur_switch
->def_sym
= gind();
7255 goto block_after_label
;
7257 } else if (t
== TOK_GOTO
) {
7258 vla_restore(root_scope
->vla
.loc
);
7259 if (tok
== '*' && gnu_ext
) {
7263 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
7267 } else if (tok
>= TOK_UIDENT
) {
7268 s
= label_find(tok
);
7269 /* put forward definition if needed */
7271 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7272 else if (s
->r
== LABEL_DECLARED
)
7273 s
->r
= LABEL_FORWARD
;
7275 if (s
->r
& LABEL_FORWARD
) {
7276 /* start new goto chain for cleanups, linked via label->next */
7277 if (cur_scope
->cl
.s
&& !nocode_wanted
) {
7278 sym_push2(&pending_gotos
, SYM_FIELD
, 0, cur_scope
->cl
.n
);
7279 pending_gotos
->prev_tok
= s
;
7280 s
= sym_push2(&s
->next
, SYM_FIELD
, 0, 0);
7281 pending_gotos
->next
= s
;
7283 s
->jnext
= gjmp(s
->jnext
);
7285 try_call_cleanup_goto(s
->cleanupstate
);
7286 gjmp_addr(s
->jnext
);
7291 expect("label identifier");
7295 } else if (t
== TOK_ASM1
|| t
== TOK_ASM2
|| t
== TOK_ASM3
) {
7299 if (tok
== ':' && t
>= TOK_UIDENT
) {
7304 if (s
->r
== LABEL_DEFINED
)
7305 tcc_error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
7306 s
->r
= LABEL_DEFINED
;
7308 Sym
*pcl
; /* pending cleanup goto */
7309 for (pcl
= s
->next
; pcl
; pcl
= pcl
->prev
)
7311 sym_pop(&s
->next
, NULL
, 0);
7315 s
= label_push(&global_label_stack
, t
, LABEL_DEFINED
);
7318 s
->cleanupstate
= cur_scope
->cl
.s
;
7321 vla_restore(cur_scope
->vla
.loc
);
7322 /* we accept this, but it is a mistake */
7324 tcc_warning("deprecated use of label at end of compound statement");
7330 /* expression case */
7347 /* This skips over a stream of tokens containing balanced {} and ()
7348 pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started
7349 with a '{'). If STR then allocates and stores the skipped tokens
7350 in *STR. This doesn't check if () and {} are nested correctly,
7351 i.e. "({)}" is accepted. */
7352 static void skip_or_save_block(TokenString
**str
)
7354 int braces
= tok
== '{';
7357 *str
= tok_str_alloc();
7359 while ((level
> 0 || (tok
!= '}' && tok
!= ',' && tok
!= ';' && tok
!= ')'))) {
7361 if (tok
== TOK_EOF
) {
7362 if (str
|| level
> 0)
7363 tcc_error("unexpected end of file");
7368 tok_str_add_tok(*str
);
7371 if (t
== '{' || t
== '(') {
7373 } else if (t
== '}' || t
== ')') {
7375 if (level
== 0 && braces
&& t
== '}')
7380 tok_str_add(*str
, -1);
7381 tok_str_add(*str
, 0);
7385 #define EXPR_CONST 1
7388 static void parse_init_elem(int expr_type
)
7390 int saved_global_expr
;
7393 /* compound literals must be allocated globally in this case */
7394 saved_global_expr
= global_expr
;
7397 global_expr
= saved_global_expr
;
7398 /* NOTE: symbols are accepted, as well as lvalue for anon symbols
7399 (compound literals). */
7400 if (((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
7401 && ((vtop
->r
& (VT_SYM
|VT_LVAL
)) != (VT_SYM
|VT_LVAL
)
7402 || vtop
->sym
->v
< SYM_FIRST_ANOM
))
7403 #ifdef TCC_TARGET_PE
7404 || ((vtop
->r
& VT_SYM
) && vtop
->sym
->a
.dllimport
)
7407 tcc_error("initializer element is not constant");
7416 static void init_assert(init_params
*p
, int offset
)
7418 if (p
->sec
? !NODATA_WANTED
&& offset
> p
->sec
->data_offset
7419 : !nocode_wanted
&& offset
> p
->local_offset
)
7420 tcc_internal_error("initializer overflow");
7423 #define init_assert(sec, offset)
7426 /* put zeros for variable based init */
7427 static void init_putz(init_params
*p
, unsigned long c
, int size
)
7429 init_assert(p
, c
+ size
);
7431 /* nothing to do because globals are already set to zero */
7433 vpush_helper_func(TOK_memset
);
7435 #ifdef TCC_TARGET_ARM
7447 #define DIF_SIZE_ONLY 2
7448 #define DIF_HAVE_ELEM 4
7451 /* delete relocations for specified range c ... c + size. Unfortunatly
7452 in very special cases, relocations may occur unordered */
7453 static void decl_design_delrels(Section
*sec
, int c
, int size
)
7455 ElfW_Rel
*rel
, *rel2
, *rel_end
;
7456 if (!sec
|| !sec
->reloc
)
7458 rel
= rel2
= (ElfW_Rel
*)sec
->reloc
->data
;
7459 rel_end
= (ElfW_Rel
*)(sec
->reloc
->data
+ sec
->reloc
->data_offset
);
7460 while (rel
< rel_end
) {
7461 if (rel
->r_offset
>= c
&& rel
->r_offset
< c
+ size
) {
7462 sec
->reloc
->data_offset
-= sizeof *rel
;
7465 memcpy(rel2
, rel
, sizeof *rel
);
7472 static void decl_design_flex(init_params
*p
, Sym
*ref
, int index
)
7474 if (ref
== p
->flex_array_ref
) {
7475 if (index
>= ref
->c
)
7477 } else if (ref
->c
< 0)
7478 tcc_error("flexible array has zero size in this context");
7481 /* t is the array or struct type. c is the array or struct
7482 address. cur_field is the pointer to the current
7483 field, for arrays the 'c' member contains the current start
7484 index. 'flags' is as in decl_initializer.
7485 'al' contains the already initialized length of the
7486 current container (starting at c). This returns the new length of that. */
7487 static int decl_designator(init_params
*p
, CType
*type
, unsigned long c
,
7488 Sym
**cur_field
, int flags
, int al
)
7491 int index
, index_last
, align
, l
, nb_elems
, elem_size
;
7492 unsigned long corig
= c
;
7497 if (flags
& DIF_HAVE_ELEM
)
7500 if (gnu_ext
&& tok
>= TOK_UIDENT
) {
7507 /* NOTE: we only support ranges for last designator */
7508 while (nb_elems
== 1 && (tok
== '[' || tok
== '.')) {
7510 if (!(type
->t
& VT_ARRAY
))
7511 expect("array type");
7513 index
= index_last
= expr_const();
7514 if (tok
== TOK_DOTS
&& gnu_ext
) {
7516 index_last
= expr_const();
7520 decl_design_flex(p
, s
, index_last
);
7521 if (index
< 0 || index_last
>= s
->c
|| index_last
< index
)
7522 tcc_error("index exceeds array bounds or range is empty");
7524 (*cur_field
)->c
= index_last
;
7525 type
= pointed_type(type
);
7526 elem_size
= type_size(type
, &align
);
7527 c
+= index
* elem_size
;
7528 nb_elems
= index_last
- index
+ 1;
7535 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
7536 expect("struct/union type");
7538 f
= find_field(type
, l
, &cumofs
);
7551 } else if (!gnu_ext
) {
7556 if (type
->t
& VT_ARRAY
) {
7557 index
= (*cur_field
)->c
;
7559 decl_design_flex(p
, s
, index
);
7561 tcc_error("too many initializers");
7562 type
= pointed_type(type
);
7563 elem_size
= type_size(type
, &align
);
7564 c
+= index
* elem_size
;
7567 while (f
&& (f
->v
& SYM_FIRST_ANOM
) && (f
->type
.t
& VT_BITFIELD
))
7568 *cur_field
= f
= f
->next
;
7570 tcc_error("too many initializers");
7576 if (!elem_size
) /* for structs */
7577 elem_size
= type_size(type
, &align
);
7579 /* Using designators the same element can be initialized more
7580 than once. In that case we need to delete possibly already
7581 existing relocations. */
7582 if (!(flags
& DIF_SIZE_ONLY
) && c
- corig
< al
) {
7583 decl_design_delrels(p
->sec
, c
, elem_size
* nb_elems
);
7584 flags
&= ~DIF_CLEAR
; /* mark stack dirty too */
7587 decl_initializer(p
, type
, c
, flags
& ~DIF_FIRST
);
7589 if (!(flags
& DIF_SIZE_ONLY
) && nb_elems
> 1) {
7593 if (p
->sec
|| (type
->t
& VT_ARRAY
)) {
7594 /* make init_putv/vstore believe it were a struct */
7596 t1
.t
= VT_STRUCT
, t1
.ref
= &aref
;
7600 vpush_ref(type
, p
->sec
, c
, elem_size
);
7602 vset(type
, VT_LOCAL
|VT_LVAL
, c
);
7603 for (i
= 1; i
< nb_elems
; i
++) {
7605 init_putv(p
, type
, c
+ elem_size
* i
);
7610 c
+= nb_elems
* elem_size
;
7616 /* store a value or an expression directly in global data or in local array */
7617 static void init_putv(init_params
*p
, CType
*type
, unsigned long c
)
7623 Section
*sec
= p
->sec
;
7626 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
7628 size
= type_size(type
, &align
);
7629 if (type
->t
& VT_BITFIELD
)
7630 size
= (BIT_POS(type
->t
) + BIT_SIZE(type
->t
) + 7) / 8;
7631 init_assert(p
, c
+ size
);
7634 /* XXX: not portable */
7635 /* XXX: generate error if incorrect relocation */
7636 gen_assign_cast(&dtype
);
7637 bt
= type
->t
& VT_BTYPE
;
7639 if ((vtop
->r
& VT_SYM
)
7642 && (bt
!= (PTR_SIZE
== 8 ? VT_LLONG
: VT_INT
)
7643 || (type
->t
& VT_BITFIELD
))
7644 && !((vtop
->r
& VT_CONST
) && vtop
->sym
->v
>= SYM_FIRST_ANOM
)
7646 tcc_error("initializer element is not computable at load time");
7648 if (NODATA_WANTED
) {
7653 ptr
= sec
->data
+ c
;
7655 /* XXX: make code faster ? */
7656 if ((vtop
->r
& (VT_SYM
|VT_CONST
)) == (VT_SYM
|VT_CONST
) &&
7657 vtop
->sym
->v
>= SYM_FIRST_ANOM
&&
7658 /* XXX This rejects compound literals like
7659 '(void *){ptr}'. The problem is that '&sym' is
7660 represented the same way, which would be ruled out
7661 by the SYM_FIRST_ANOM check above, but also '"string"'
7662 in 'char *p = "string"' is represented the same
7663 with the type being VT_PTR and the symbol being an
7664 anonymous one. That is, there's no difference in vtop
7665 between '(void *){x}' and '&(void *){x}'. Ignore
7666 pointer typed entities here. Hopefully no real code
7667 will ever use compound literals with scalar type. */
7668 (vtop
->type
.t
& VT_BTYPE
) != VT_PTR
) {
7669 /* These come from compound literals, memcpy stuff over. */
7673 esym
= elfsym(vtop
->sym
);
7674 ssec
= tcc_state
->sections
[esym
->st_shndx
];
7675 memmove (ptr
, ssec
->data
+ esym
->st_value
+ (int)vtop
->c
.i
, size
);
7677 /* We need to copy over all memory contents, and that
7678 includes relocations. Use the fact that relocs are
7679 created it order, so look from the end of relocs
7680 until we hit one before the copied region. */
7681 int num_relocs
= ssec
->reloc
->data_offset
/ sizeof(*rel
);
7682 rel
= (ElfW_Rel
*)(ssec
->reloc
->data
+ ssec
->reloc
->data_offset
);
7683 while (num_relocs
--) {
7685 if (rel
->r_offset
>= esym
->st_value
+ size
)
7687 if (rel
->r_offset
< esym
->st_value
)
7689 put_elf_reloca(symtab_section
, sec
,
7690 c
+ rel
->r_offset
- esym
->st_value
,
7691 ELFW(R_TYPE
)(rel
->r_info
),
7692 ELFW(R_SYM
)(rel
->r_info
),
7702 if (type
->t
& VT_BITFIELD
) {
7703 int bit_pos
, bit_size
, bits
, n
;
7704 unsigned char *p
, v
, m
;
7705 bit_pos
= BIT_POS(vtop
->type
.t
);
7706 bit_size
= BIT_SIZE(vtop
->type
.t
);
7707 p
= (unsigned char*)ptr
+ (bit_pos
>> 3);
7708 bit_pos
&= 7, bits
= 0;
7713 v
= vtop
->c
.i
>> bits
<< bit_pos
;
7714 m
= ((1 << n
) - 1) << bit_pos
;
7715 *p
= (*p
& ~m
) | (v
& m
);
7716 bits
+= n
, bit_size
-= n
, bit_pos
= 0, ++p
;
7720 /* XXX: when cross-compiling we assume that each type has the
7721 same representation on host and target, which is likely to
7722 be wrong in the case of long double */
7724 vtop
->c
.i
= vtop
->c
.i
!= 0;
7726 *(char *)ptr
= vtop
->c
.i
;
7729 *(short *)ptr
= vtop
->c
.i
;
7732 *(float*)ptr
= vtop
->c
.f
;
7735 *(double *)ptr
= vtop
->c
.d
;
7738 #if defined TCC_IS_NATIVE_387
7739 if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
7740 memcpy(ptr
, &vtop
->c
.ld
, 10);
7742 else if (sizeof (long double) == sizeof (double))
7743 __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr
) : "m" (vtop
->c
.ld
));
7745 else if (vtop
->c
.ld
== 0.0)
7749 if (sizeof(long double) == LDOUBLE_SIZE
)
7750 *(long double*)ptr
= vtop
->c
.ld
;
7751 else if (sizeof(double) == LDOUBLE_SIZE
)
7752 *(double *)ptr
= (double)vtop
->c
.ld
;
7754 tcc_error("can't cross compile long double constants");
7758 *(long long *)ptr
= vtop
->c
.i
;
7765 addr_t val
= vtop
->c
.i
;
7767 if (vtop
->r
& VT_SYM
)
7768 greloca(sec
, vtop
->sym
, c
, R_DATA_PTR
, val
);
7770 *(addr_t
*)ptr
= val
;
7772 if (vtop
->r
& VT_SYM
)
7773 greloc(sec
, vtop
->sym
, c
, R_DATA_PTR
);
7774 *(addr_t
*)ptr
= val
;
7780 int val
= vtop
->c
.i
;
7782 if (vtop
->r
& VT_SYM
)
7783 greloca(sec
, vtop
->sym
, c
, R_DATA_PTR
, val
);
7787 if (vtop
->r
& VT_SYM
)
7788 greloc(sec
, vtop
->sym
, c
, R_DATA_PTR
);
7797 vset(&dtype
, VT_LOCAL
|VT_LVAL
, c
);
7804 /* 't' contains the type and storage info. 'c' is the offset of the
7805 object in section 'sec'. If 'sec' is NULL, it means stack based
7806 allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi
7807 dimension implicit array init handling). 'flags & DIF_SIZE_ONLY' is true if
7808 size only evaluation is wanted (only for arrays). */
7809 static void decl_initializer(init_params
*p
, CType
*type
, unsigned long c
, int flags
)
7811 int len
, n
, no_oblock
, i
;
7817 /* generate line number info */
7818 if (!p
->sec
&& tcc_state
->do_debug
)
7819 tcc_debug_line(tcc_state
);
7821 if (!(flags
& DIF_HAVE_ELEM
) && tok
!= '{' &&
7822 /* In case of strings we have special handling for arrays, so
7823 don't consume them as initializer value (which would commit them
7824 to some anonymous symbol). */
7825 tok
!= TOK_LSTR
&& tok
!= TOK_STR
&&
7826 !(flags
& DIF_SIZE_ONLY
)) {
7827 parse_init_elem(!p
->sec
? EXPR_ANY
: EXPR_CONST
);
7828 flags
|= DIF_HAVE_ELEM
;
7831 if ((flags
& DIF_HAVE_ELEM
) &&
7832 !(type
->t
& VT_ARRAY
) &&
7833 /* Use i_c_parameter_t, to strip toplevel qualifiers.
7834 The source type might have VT_CONSTANT set, which is
7835 of course assignable to non-const elements. */
7836 is_compatible_unqualified_types(type
, &vtop
->type
)) {
7839 } else if (type
->t
& VT_ARRAY
) {
7841 if (((flags
& DIF_FIRST
) && tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
7849 t1
= pointed_type(type
);
7850 size1
= type_size(t1
, &align1
);
7852 /* only parse strings here if correct type (otherwise: handle
7853 them as ((w)char *) expressions */
7854 if ((tok
== TOK_LSTR
&&
7855 #ifdef TCC_TARGET_PE
7856 (t1
->t
& VT_BTYPE
) == VT_SHORT
&& (t1
->t
& VT_UNSIGNED
)
7858 (t1
->t
& VT_BTYPE
) == VT_INT
7860 ) || (tok
== TOK_STR
&& (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
7862 cstr_reset(&initstr
);
7863 if (size1
!= (tok
== TOK_STR
? 1 : sizeof(nwchar_t
)))
7864 tcc_error("unhandled string literal merging");
7865 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
7867 initstr
.size
-= size1
;
7869 len
+= tokc
.str
.size
;
7871 len
+= tokc
.str
.size
/ sizeof(nwchar_t
);
7873 cstr_cat(&initstr
, tokc
.str
.data
, tokc
.str
.size
);
7876 if (tok
!= ')' && tok
!= '}' && tok
!= ',' && tok
!= ';'
7877 && tok
!= TOK_EOF
) {
7878 /* Not a lone literal but part of a bigger expression. */
7879 unget_tok(size1
== 1 ? TOK_STR
: TOK_LSTR
);
7880 tokc
.str
.size
= initstr
.size
;
7881 tokc
.str
.data
= initstr
.data
;
7885 if (!(flags
& DIF_SIZE_ONLY
)) {
7890 tcc_warning("initializer-string for array is too long");
7891 /* in order to go faster for common case (char
7892 string in global variable, we handle it
7894 if (p
->sec
&& size1
== 1) {
7895 init_assert(p
, c
+ nb
);
7897 memcpy(p
->sec
->data
+ c
, initstr
.data
, nb
);
7901 /* only add trailing zero if enough storage (no
7902 warning in this case since it is standard) */
7903 if (flags
& DIF_CLEAR
)
7906 init_putz(p
, c
+ i
* size1
, (n
- i
) * size1
);
7910 } else if (size1
== 1)
7911 ch
= ((unsigned char *)initstr
.data
)[i
];
7913 ch
= ((nwchar_t
*)initstr
.data
)[i
];
7915 init_putv(p
, t1
, c
+ i
* size1
);
7919 decl_design_flex(p
, s
, len
);
7928 /* zero memory once in advance */
7929 if (!(flags
& (DIF_CLEAR
| DIF_SIZE_ONLY
))) {
7930 init_putz(p
, c
, n
*size1
);
7935 while (tok
!= '}' || (flags
& DIF_HAVE_ELEM
)) {
7936 len
= decl_designator(p
, type
, c
, &f
, flags
, len
);
7937 flags
&= ~DIF_HAVE_ELEM
;
7938 if (type
->t
& VT_ARRAY
) {
7940 /* special test for multi dimensional arrays (may not
7941 be strictly correct if designators are used at the
7943 if (no_oblock
&& len
>= n
*size1
)
7946 if (s
->type
.t
== VT_UNION
)
7950 if (no_oblock
&& f
== NULL
)
7961 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
) {
7963 if ((flags
& DIF_FIRST
) || tok
== '{') {
7972 } else if (tok
== '{') {
7973 if (flags
& DIF_HAVE_ELEM
)
7976 decl_initializer(p
, type
, c
, flags
& ~DIF_HAVE_ELEM
);
7978 } else if ((flags
& DIF_SIZE_ONLY
)) {
7979 /* If we supported only ISO C we wouldn't have to accept calling
7980 this on anything than an array if DIF_SIZE_ONLY (and even then
7981 only on the outermost level, so no recursion would be needed),
7982 because initializing a flex array member isn't supported.
7983 But GNU C supports it, so we need to recurse even into
7984 subfields of structs and arrays when DIF_SIZE_ONLY is set. */
7985 /* just skip expression */
7986 skip_or_save_block(NULL
);
7988 if (!(flags
& DIF_HAVE_ELEM
)) {
7989 /* This should happen only when we haven't parsed
7990 the init element above for fear of committing a
7991 string constant to memory too early. */
7992 if (tok
!= TOK_STR
&& tok
!= TOK_LSTR
)
7993 expect("string constant");
7994 parse_init_elem(!p
->sec
? EXPR_ANY
: EXPR_CONST
);
7997 if (!p
->sec
&& (flags
& DIF_CLEAR
) /* container was already zero'd */
7998 && (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
8000 && btype_size(type
->t
& VT_BTYPE
) /* not for fp constants */
8004 init_putv(p
, type
, c
);
8008 /* parse an initializer for type 't' if 'has_init' is non zero, and
8009 allocate space in local or global data space ('r' is either
8010 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
8011 variable 'v' of scope 'scope' is declared before initializers
8012 are parsed. If 'v' is zero, then a reference to the new object
8013 is put in the value stack. If 'has_init' is 2, a special parsing
8014 is done to handle string constants. */
8015 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
8016 int has_init
, int v
, int scope
)
8018 int size
, align
, addr
;
8019 TokenString
*init_str
= NULL
;
8022 Sym
*flexible_array
;
8024 int saved_nocode_wanted
= nocode_wanted
;
8025 #ifdef CONFIG_TCC_BCHECK
8026 int bcheck
= tcc_state
->do_bounds_check
&& !NODATA_WANTED
;
8028 init_params p
= {0};
8030 /* Always allocate static or global variables */
8031 if (v
&& (r
& VT_VALMASK
) == VT_CONST
)
8032 nocode_wanted
|= 0x80000000;
8034 flexible_array
= NULL
;
8035 size
= type_size(type
, &align
);
8037 /* exactly one flexible array may be initialized, either the
8038 toplevel array or the last member of the toplevel struct */
8041 /* If the base type itself was an array type of unspecified size
8042 (like in 'typedef int arr[]; arr x = {1};') then we will
8043 overwrite the unknown size by the real one for this decl.
8044 We need to unshare the ref symbol holding that size. */
8045 type
->ref
= sym_push(SYM_FIELD
, &type
->ref
->type
, 0, type
->ref
->c
);
8046 p
.flex_array_ref
= type
->ref
;
8048 } else if (has_init
&& (type
->t
& VT_BTYPE
) == VT_STRUCT
) {
8049 Sym
*field
= type
->ref
->next
;
8052 field
= field
->next
;
8053 if (field
->type
.t
& VT_ARRAY
&& field
->type
.ref
->c
< 0) {
8054 flexible_array
= field
;
8055 p
.flex_array_ref
= field
->type
.ref
;
8062 /* If unknown size, do a dry-run 1st pass */
8064 tcc_error("unknown type size");
8065 if (has_init
== 2) {
8066 /* only get strings */
8067 init_str
= tok_str_alloc();
8068 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8069 tok_str_add_tok(init_str
);
8072 tok_str_add(init_str
, -1);
8073 tok_str_add(init_str
, 0);
8075 skip_or_save_block(&init_str
);
8079 begin_macro(init_str
, 1);
8081 decl_initializer(&p
, type
, 0, DIF_FIRST
| DIF_SIZE_ONLY
);
8082 /* prepare second initializer parsing */
8083 macro_ptr
= init_str
->str
;
8086 /* if still unknown size, error */
8087 size
= type_size(type
, &align
);
8089 tcc_error("unknown type size");
8091 /* If there's a flex member and it was used in the initializer
8093 if (flexible_array
&& flexible_array
->type
.ref
->c
> 0)
8094 size
+= flexible_array
->type
.ref
->c
8095 * pointed_size(&flexible_array
->type
);
8098 /* take into account specified alignment if bigger */
8099 if (ad
->a
.aligned
) {
8100 int speca
= 1 << (ad
->a
.aligned
- 1);
8103 } else if (ad
->a
.packed
) {
8107 if (!v
&& NODATA_WANTED
)
8108 size
= 0, align
= 1;
8110 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
8112 #ifdef CONFIG_TCC_BCHECK
8114 /* add padding between stack variables for bound checking */
8118 loc
= (loc
- size
) & -align
;
8120 p
.local_offset
= addr
+ size
;
8121 #ifdef CONFIG_TCC_BCHECK
8123 /* add padding between stack variables for bound checking */
8128 /* local variable */
8129 #ifdef CONFIG_TCC_ASM
8130 if (ad
->asm_label
) {
8131 int reg
= asm_parse_regvar(ad
->asm_label
);
8133 r
= (r
& ~VT_VALMASK
) | reg
;
8136 sym
= sym_push(v
, type
, r
, addr
);
8137 if (ad
->cleanup_func
) {
8138 Sym
*cls
= sym_push2(&all_cleanups
,
8139 SYM_FIELD
| ++cur_scope
->cl
.n
, 0, 0);
8140 cls
->prev_tok
= sym
;
8141 cls
->next
= ad
->cleanup_func
;
8142 cls
->ncl
= cur_scope
->cl
.s
;
8143 cur_scope
->cl
.s
= cls
;
8148 /* push local reference */
8149 vset(type
, r
, addr
);
8152 if (v
&& scope
== VT_CONST
) {
8153 /* see if the symbol was already defined */
8156 patch_storage(sym
, ad
, type
);
8157 /* we accept several definitions of the same global variable. */
8158 if (!has_init
&& sym
->c
&& elfsym(sym
)->st_shndx
!= SHN_UNDEF
)
8163 /* allocate symbol in corresponding section */
8166 if (type
->t
& VT_CONSTANT
)
8167 sec
= data_ro_section
;
8170 else if (tcc_state
->nocommon
)
8175 addr
= section_add(sec
, size
, align
);
8176 #ifdef CONFIG_TCC_BCHECK
8177 /* add padding if bound check */
8179 section_add(sec
, 1, 1);
8182 addr
= align
; /* SHN_COMMON is special, symbol value is align */
8183 sec
= common_section
;
8188 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
8189 patch_storage(sym
, ad
, NULL
);
8191 /* update symbol definition */
8192 put_extern_sym(sym
, sec
, addr
, size
);
8194 /* push global reference */
8195 vpush_ref(type
, sec
, addr
, size
);
8200 #ifdef CONFIG_TCC_BCHECK
8201 /* handles bounds now because the symbol must be defined
8202 before for the relocation */
8206 greloca(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_PTR
, 0);
8207 /* then add global bound info */
8208 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(addr_t
));
8209 bounds_ptr
[0] = 0; /* relocated */
8210 bounds_ptr
[1] = size
;
8215 if (type
->t
& VT_VLA
) {
8221 /* save current stack pointer */
8222 if (root_scope
->vla
.loc
== 0) {
8223 struct scope
*v
= cur_scope
;
8224 gen_vla_sp_save(loc
-= PTR_SIZE
);
8225 do v
->vla
.loc
= loc
; while ((v
= v
->prev
));
8228 vla_runtime_type_size(type
, &a
);
8229 gen_vla_alloc(type
, a
);
8230 #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
8231 /* on _WIN64, because of the function args scratch area, the
8232 result of alloca differs from RSP and is returned in RAX. */
8233 gen_vla_result(addr
), addr
= (loc
-= PTR_SIZE
);
8235 gen_vla_sp_save(addr
);
8236 cur_scope
->vla
.loc
= addr
;
8237 cur_scope
->vla
.num
++;
8238 } else if (has_init
) {
8240 decl_initializer(&p
, type
, addr
, DIF_FIRST
);
8241 /* patch flexible array member size back to -1, */
8242 /* for possible subsequent similar declarations */
8244 flexible_array
->type
.ref
->c
= -1;
8248 /* restore parse state if needed */
8254 nocode_wanted
= saved_nocode_wanted
;
8257 /* parse a function defined by symbol 'sym' and generate its code in
8258 'cur_text_section' */
8259 static void gen_function(Sym
*sym
)
8261 struct scope f
= { 0 };
8262 cur_scope
= root_scope
= &f
;
8264 ind
= cur_text_section
->data_offset
;
8265 if (sym
->a
.aligned
) {
8266 size_t newoff
= section_add(cur_text_section
, 0,
8267 1 << (sym
->a
.aligned
- 1));
8268 gen_fill_nops(newoff
- ind
);
8270 /* NOTE: we patch the symbol size later */
8271 put_extern_sym(sym
, cur_text_section
, ind
, 0);
8272 if (sym
->type
.ref
->f
.func_ctor
)
8273 add_array (tcc_state
, ".init_array", sym
->c
);
8274 if (sym
->type
.ref
->f
.func_dtor
)
8275 add_array (tcc_state
, ".fini_array", sym
->c
);
8277 funcname
= get_tok_str(sym
->v
, NULL
);
8279 func_vt
= sym
->type
.ref
->type
;
8280 func_var
= sym
->type
.ref
->f
.func_type
== FUNC_ELLIPSIS
;
8282 /* put debug symbol */
8283 tcc_debug_funcstart(tcc_state
, sym
);
8284 /* push a dummy symbol to enable local sym storage */
8285 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
8286 local_scope
= 1; /* for function parameters */
8290 clear_temp_local_var_list();
8294 /* reset local stack */
8295 pop_local_syms(&local_stack
, NULL
, 0, func_var
);
8297 cur_text_section
->data_offset
= ind
;
8299 label_pop(&global_label_stack
, NULL
, 0);
8300 sym_pop(&all_cleanups
, NULL
, 0);
8301 /* patch symbol size */
8302 elfsym(sym
)->st_size
= ind
- func_ind
;
8303 /* end of function */
8304 tcc_debug_funcend(tcc_state
, ind
- func_ind
);
8305 /* It's better to crash than to generate wrong code */
8306 cur_text_section
= NULL
;
8307 funcname
= ""; /* for safety */
8308 func_vt
.t
= VT_VOID
; /* for safety */
8309 func_var
= 0; /* for safety */
8310 ind
= 0; /* for safety */
8311 nocode_wanted
= 0x80000000;
8313 /* do this after funcend debug info */
8317 static void gen_inline_functions(TCCState
*s
)
8320 int inline_generated
, i
;
8321 struct InlineFunc
*fn
;
8323 tcc_open_bf(s
, ":inline:", 0);
8324 /* iterate while inline function are referenced */
8326 inline_generated
= 0;
8327 for (i
= 0; i
< s
->nb_inline_fns
; ++i
) {
8328 fn
= s
->inline_fns
[i
];
8330 if (sym
&& (sym
->c
|| !(sym
->type
.t
& VT_INLINE
))) {
8331 /* the function was used or forced (and then not internal):
8332 generate its code and convert it to a normal function */
8334 tcc_debug_putfile(s
, fn
->filename
);
8335 begin_macro(fn
->func_str
, 1);
8337 cur_text_section
= text_section
;
8341 inline_generated
= 1;
8344 } while (inline_generated
);
8348 static void free_inline_functions(TCCState
*s
)
8351 /* free tokens of unused inline functions */
8352 for (i
= 0; i
< s
->nb_inline_fns
; ++i
) {
8353 struct InlineFunc
*fn
= s
->inline_fns
[i
];
8355 tok_str_free(fn
->func_str
);
8357 dynarray_reset(&s
->inline_fns
, &s
->nb_inline_fns
);
8360 /* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
8361 if parsing old style parameter decl list (and FUNC_SYM is set then) */
8362 static int decl0(int l
, int is_for_loop_init
, Sym
*func_sym
)
8364 int v
, has_init
, r
, oldint
;
8367 AttributeDef ad
, adbase
;
8370 if (tok
== TOK_STATIC_ASSERT
) {
8380 tcc_error("_Static_assert fail");
8382 goto static_assert_out
;
8386 parse_mult_str(&error_str
, "string constant");
8388 tcc_error("%s", (char *)error_str
.data
);
8389 cstr_free(&error_str
);
8397 if (!parse_btype(&btype
, &adbase
)) {
8398 if (is_for_loop_init
)
8400 /* skip redundant ';' if not in old parameter decl scope */
8401 if (tok
== ';' && l
!= VT_CMP
) {
8407 if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
8408 /* global asm block */
8412 if (tok
>= TOK_UIDENT
) {
8413 /* special test for old K&R protos without explicit int
8414 type. Only accepted when defining global data */
8419 expect("declaration");
8425 if ((btype
.t
& VT_BTYPE
) == VT_STRUCT
) {
8427 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
)
8428 tcc_warning("unnamed struct/union that defines no instances");
8432 if (IS_ENUM(btype
.t
)) {
8438 while (1) { /* iterate thru each declaration */
8441 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8445 type_to_str(buf
, sizeof(buf
), &type
, get_tok_str(v
, NULL
));
8446 printf("type = '%s'\n", buf
);
8449 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8450 if ((type
.t
& VT_STATIC
) && (l
== VT_LOCAL
))
8451 tcc_error("function without file scope cannot be static");
8452 /* if old style function prototype, we accept a
8455 if (sym
->f
.func_type
== FUNC_OLD
&& l
== VT_CONST
)
8456 decl0(VT_CMP
, 0, sym
);
8457 #ifdef TCC_TARGET_MACHO
8458 if (sym
->f
.func_alwinl
8459 && ((type
.t
& (VT_EXTERN
| VT_INLINE
))
8460 == (VT_EXTERN
| VT_INLINE
))) {
8461 /* always_inline functions must be handled as if they
8462 don't generate multiple global defs, even if extern
8463 inline, i.e. GNU inline semantics for those. Rewrite
8464 them into static inline. */
8465 type
.t
&= ~VT_EXTERN
;
8466 type
.t
|= VT_STATIC
;
8469 /* always compile 'extern inline' */
8470 if (type
.t
& VT_EXTERN
)
8471 type
.t
&= ~VT_INLINE
;
8473 } else if (oldint
) {
8474 tcc_warning("type defaults to int");
8477 if (gnu_ext
&& (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
8478 ad
.asm_label
= asm_label_instr();
8479 /* parse one last attribute list, after asm label */
8480 parse_attribute(&ad
);
8482 /* gcc does not allow __asm__("label") with function definition,
8489 #ifdef TCC_TARGET_PE
8490 if (ad
.a
.dllimport
|| ad
.a
.dllexport
) {
8491 if (type
.t
& VT_STATIC
)
8492 tcc_error("cannot have dll linkage with static");
8493 if (type
.t
& VT_TYPEDEF
) {
8494 tcc_warning("'%s' attribute ignored for typedef",
8495 ad
.a
.dllimport
? (ad
.a
.dllimport
= 0, "dllimport") :
8496 (ad
.a
.dllexport
= 0, "dllexport"));
8497 } else if (ad
.a
.dllimport
) {
8498 if ((type
.t
& VT_BTYPE
) == VT_FUNC
)
8501 type
.t
|= VT_EXTERN
;
8507 tcc_error("cannot use local functions");
8508 if ((type
.t
& VT_BTYPE
) != VT_FUNC
)
8509 expect("function definition");
8511 /* reject abstract declarators in function definition
8512 make old style params without decl have int type */
8514 while ((sym
= sym
->next
) != NULL
) {
8515 if (!(sym
->v
& ~SYM_FIELD
))
8516 expect("identifier");
8517 if (sym
->type
.t
== VT_VOID
)
8518 sym
->type
= int_type
;
8521 /* apply post-declaraton attributes */
8522 merge_funcattr(&type
.ref
->f
, &ad
.f
);
8524 /* put function symbol */
8525 type
.t
&= ~VT_EXTERN
;
8526 sym
= external_sym(v
, &type
, 0, &ad
);
8528 /* static inline functions are just recorded as a kind
8529 of macro. Their code will be emitted at the end of
8530 the compilation unit only if they are used */
8531 if (sym
->type
.t
& VT_INLINE
) {
8532 struct InlineFunc
*fn
;
8533 fn
= tcc_malloc(sizeof *fn
+ strlen(file
->filename
));
8534 strcpy(fn
->filename
, file
->filename
);
8536 skip_or_save_block(&fn
->func_str
);
8537 dynarray_add(&tcc_state
->inline_fns
,
8538 &tcc_state
->nb_inline_fns
, fn
);
8540 /* compute text section */
8541 cur_text_section
= ad
.section
;
8542 if (!cur_text_section
)
8543 cur_text_section
= text_section
;
8549 /* find parameter in function parameter list */
8550 for (sym
= func_sym
->next
; sym
; sym
= sym
->next
)
8551 if ((sym
->v
& ~SYM_FIELD
) == v
)
8553 tcc_error("declaration for parameter '%s' but no such parameter",
8554 get_tok_str(v
, NULL
));
8556 if (type
.t
& VT_STORAGE
) /* 'register' is okay */
8557 tcc_error("storage class specified for '%s'",
8558 get_tok_str(v
, NULL
));
8559 if (sym
->type
.t
!= VT_VOID
)
8560 tcc_error("redefinition of parameter '%s'",
8561 get_tok_str(v
, NULL
));
8562 convert_parameter_type(&type
);
8564 } else if (type
.t
& VT_TYPEDEF
) {
8565 /* save typedefed type */
8566 /* XXX: test storage specifiers ? */
8568 if (sym
&& sym
->sym_scope
== local_scope
) {
8569 if (!is_compatible_types(&sym
->type
, &type
)
8570 || !(sym
->type
.t
& VT_TYPEDEF
))
8571 tcc_error("incompatible redefinition of '%s'",
8572 get_tok_str(v
, NULL
));
8575 sym
= sym_push(v
, &type
, 0, 0);
8579 if (tcc_state
->do_debug
)
8580 tcc_debug_typedef (tcc_state
, sym
);
8581 } else if ((type
.t
& VT_BTYPE
) == VT_VOID
8582 && !(type
.t
& VT_EXTERN
)) {
8583 tcc_error("declaration of void object");
8586 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8587 /* external function definition */
8588 /* specific case for func_call attribute */
8590 } else if (!(type
.t
& VT_ARRAY
)) {
8591 /* not lvalue if array */
8594 has_init
= (tok
== '=');
8595 if (has_init
&& (type
.t
& VT_VLA
))
8596 tcc_error("variable length array cannot be initialized");
8597 if (((type
.t
& VT_EXTERN
) && (!has_init
|| l
!= VT_CONST
))
8598 || (type
.t
& VT_BTYPE
) == VT_FUNC
8599 /* as with GCC, uninitialized global arrays with no size
8600 are considered extern: */
8601 || ((type
.t
& VT_ARRAY
) && !has_init
8602 && l
== VT_CONST
&& type
.ref
->c
< 0)
8604 /* external variable or function */
8605 type
.t
|= VT_EXTERN
;
8606 sym
= external_sym(v
, &type
, r
, &ad
);
8607 if (ad
.alias_target
) {
8608 /* Aliases need to be emitted when their target
8609 symbol is emitted, even if perhaps unreferenced.
8610 We only support the case where the base is
8611 already defined, otherwise we would need
8612 deferring to emit the aliases until the end of
8613 the compile unit. */
8614 Sym
*alias_target
= sym_find(ad
.alias_target
);
8615 ElfSym
*esym
= elfsym(alias_target
);
8617 tcc_error("unsupported forward __alias__ attribute");
8618 put_extern_sym2(sym
, esym
->st_shndx
,
8619 esym
->st_value
, esym
->st_size
, 1);
8622 if (type
.t
& VT_STATIC
)
8628 else if (l
== VT_CONST
)
8629 /* uninitialized global variables may be overridden */
8630 type
.t
|= VT_EXTERN
;
8631 decl_initializer_alloc(&type
, &ad
, r
, has_init
, v
, l
);
8635 if (is_for_loop_init
)
8647 static void decl(int l
)
8652 /* ------------------------------------------------------------------------- */
8655 /* ------------------------------------------------------------------------- */