three small fixes & three reverts
[tinycc.git] / tccgen.c
blob26e9f53e0893f2eeafea962cd198c6d99a94750a
1 /*
2 * TCC - Tiny C Compiler
3 *
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
21 #define USING_GLOBALS
22 #include "tcc.h"
24 /********************************************************/
25 /* global variables */
27 /* loc : local variable index
28 ind : output code index
29 rsym: return symbol
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;
46 static int in_sizeof;
47 static int in_generic;
48 static int section_sym;
50 ST_DATA SValue *vtop;
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
74 #define gjmp gjmp_acs
75 /* <---- */
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) */
80 ST_DATA int func_vc;
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;
86 #if PTR_SIZE == 4
87 #define VT_SIZE_T (VT_INT | VT_UNSIGNED)
88 #define VT_PTRDIFF_T VT_INT
89 #elif LONG_SIZE == 4
90 #define VT_SIZE_T (VT_LLONG | VT_UNSIGNED)
91 #define VT_PTRDIFF_T VT_LLONG
92 #else
93 #define VT_SIZE_T (VT_LONG | VT_LLONG | VT_UNSIGNED)
94 #define VT_PTRDIFF_T (VT_LONG | VT_LLONG)
95 #endif
97 ST_DATA struct switch_t {
98 struct case_t {
99 int64_t v1, v2;
100 int sym;
101 } **p; int n; /* list of case ranges */
102 int def_sym; /* default symbol */
103 int *bsym;
104 struct scope *scope;
105 struct switch_t *prev;
106 SValue sv;
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
113 short size;
114 short align;
115 } arr_temp_local_vars[MAX_TEMP_LOCAL_VARIABLE_NUMBER];
116 short nb_temp_local_vars;
118 static struct scope {
119 struct scope *prev;
120 struct { int loc, num; } vla;
121 struct { Sym *s; int n; } cl;
122 int *bsym, *csym;
123 Sym *lstk, *llstk;
124 } *cur_scope, *loop_scope, *root_scope;
126 typedef struct {
127 Section *sec;
128 int local_offset;
129 Sym *flex_array_ref;
130 } init_params;
132 /********************************************************/
133 /* stab debug support */
135 static const struct {
136 int type;
137 const char *name;
138 } default_debug[] = {
139 { VT_INT, "int:t1=r1;-2147483648;2147483647;" },
140 { VT_BYTE, "char:t2=r2;0;127;" },
141 #if LONG_SIZE == 4
142 { VT_LONG | VT_INT, "long int:t3=r3;-2147483648;2147483647;" },
143 #else
144 { VT_LLONG | VT_LONG, "long int:t3=r3;-9223372036854775808;9223372036854775807;" },
145 #endif
146 { VT_INT | VT_UNSIGNED, "unsigned int:t4=r4;0;037777777777;" },
147 #if LONG_SIZE == 4
148 { VT_LONG | VT_INT | VT_UNSIGNED, "long unsigned int:t5=r5;0;037777777777;" },
149 #else
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;" },
152 #endif
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 { VT_LDOUBLE, "long double:t16=r1;16;0;" },
164 { -1, "_Float32:t17=r1;4;0;" },
165 { -1, "_Float64:t18=r1;8;0;" },
166 { -1, "_Float128:t19=r1;16;0;" },
167 { -1, "_Float32x:t20=r1;8;0;" },
168 { -1, "_Float64x:t21=r1;16;0;" },
169 { -1, "_Decimal32:t22=r1;4;0;" },
170 { -1, "_Decimal64:t23=r1;8;0;" },
171 { -1, "_Decimal128:t24=r1;16;0;" },
172 /* if default char is unsigned */
173 { VT_BYTE | VT_UNSIGNED, "unsigned char:t25=r25;0;255;" },
174 /* boolean type */
175 { VT_BOOL, "bool:t26=r26;0;255;" },
176 { VT_VOID, "void:t27=27" },
179 static int debug_next_type;
181 static struct debug_hash {
182 int debug_type;
183 Sym *type;
184 } *debug_hash;
186 static int n_debug_hash;
188 static struct debug_info {
189 int start;
190 int end;
191 int n_sym;
192 struct debug_sym {
193 int type;
194 unsigned long value;
195 char *str;
196 Section *sec;
197 int sym_index;
198 } *sym;
199 struct debug_info *child, *next, *last, *parent;
200 } *debug_info, *debug_info_root;
202 /********************************************************/
203 #if 1
204 #define precedence_parser
205 static void init_prec(void);
206 #endif
207 /********************************************************/
208 #ifndef CONFIG_TCC_ASM
209 ST_FUNC void asm_instr(void)
211 tcc_error("inline asm() not supported");
213 ST_FUNC void asm_global_instr(void)
215 tcc_error("inline asm() not supported");
217 #endif
219 /* ------------------------------------------------------------------------- */
220 static void gen_cast(CType *type);
221 static void gen_cast_s(int t);
222 static inline CType *pointed_type(CType *type);
223 static int is_compatible_types(CType *type1, CType *type2);
224 static int parse_btype(CType *type, AttributeDef *ad);
225 static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td);
226 static void parse_expr_type(CType *type);
227 static void init_putv(init_params *p, CType *type, unsigned long c);
228 static void decl_initializer(init_params *p, CType *type, unsigned long c, int flags);
229 static void block(int is_expr);
230 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
231 static void decl(int l);
232 static int decl0(int l, int is_for_loop_init, Sym *);
233 static void expr_eq(void);
234 static void vla_runtime_type_size(CType *type, int *a);
235 static int is_compatible_unqualified_types(CType *type1, CType *type2);
236 static inline int64_t expr_const64(void);
237 static void vpush64(int ty, unsigned long long v);
238 static void vpush(CType *type);
239 static int gvtst(int inv, int t);
240 static void gen_inline_functions(TCCState *s);
241 static void free_inline_functions(TCCState *s);
242 static void skip_or_save_block(TokenString **str);
243 static void gv_dup(void);
244 static int get_temp_local_var(int size,int align);
245 static void clear_temp_local_var_list();
246 static void cast_error(CType *st, CType *dt);
248 ST_INLN int is_float(int t)
250 int bt = t & VT_BTYPE;
251 return bt == VT_LDOUBLE
252 || bt == VT_DOUBLE
253 || bt == VT_FLOAT
254 || bt == VT_QFLOAT;
257 static inline int is_integer_btype(int bt)
259 return bt == VT_BYTE
260 || bt == VT_BOOL
261 || bt == VT_SHORT
262 || bt == VT_INT
263 || bt == VT_LLONG;
266 static int btype_size(int bt)
268 return bt == VT_BYTE || bt == VT_BOOL ? 1 :
269 bt == VT_SHORT ? 2 :
270 bt == VT_INT ? 4 :
271 bt == VT_LLONG ? 8 :
272 bt == VT_PTR ? PTR_SIZE : 0;
275 /* returns function return register from type */
276 static int R_RET(int t)
278 if (!is_float(t))
279 return REG_IRET;
280 #ifdef TCC_TARGET_X86_64
281 if ((t & VT_BTYPE) == VT_LDOUBLE)
282 return TREG_ST0;
283 #elif defined TCC_TARGET_RISCV64
284 if ((t & VT_BTYPE) == VT_LDOUBLE)
285 return REG_IRET;
286 #endif
287 return REG_FRET;
290 /* returns 2nd function return register, if any */
291 static int R2_RET(int t)
293 t &= VT_BTYPE;
294 #if PTR_SIZE == 4
295 if (t == VT_LLONG)
296 return REG_IRE2;
297 #elif defined TCC_TARGET_X86_64
298 if (t == VT_QLONG)
299 return REG_IRE2;
300 if (t == VT_QFLOAT)
301 return REG_FRE2;
302 #elif defined TCC_TARGET_RISCV64
303 if (t == VT_LDOUBLE)
304 return REG_IRE2;
305 #endif
306 return VT_CONST;
309 /* returns true for two-word types */
310 #define USING_TWO_WORDS(t) (R2_RET(t) != VT_CONST)
312 /* put function return registers to stack value */
313 static void PUT_R_RET(SValue *sv, int t)
315 sv->r = R_RET(t), sv->r2 = R2_RET(t);
318 /* returns function return register class for type t */
319 static int RC_RET(int t)
321 return reg_classes[R_RET(t)] & ~(RC_FLOAT | RC_INT);
324 /* returns generic register class for type t */
325 static int RC_TYPE(int t)
327 if (!is_float(t))
328 return RC_INT;
329 #ifdef TCC_TARGET_X86_64
330 if ((t & VT_BTYPE) == VT_LDOUBLE)
331 return RC_ST0;
332 if ((t & VT_BTYPE) == VT_QFLOAT)
333 return RC_FRET;
334 #elif defined TCC_TARGET_RISCV64
335 if ((t & VT_BTYPE) == VT_LDOUBLE)
336 return RC_INT;
337 #endif
338 return RC_FLOAT;
341 /* returns 2nd register class corresponding to t and rc */
342 static int RC2_TYPE(int t, int rc)
344 if (!USING_TWO_WORDS(t))
345 return 0;
346 #ifdef RC_IRE2
347 if (rc == RC_IRET)
348 return RC_IRE2;
349 #endif
350 #ifdef RC_FRE2
351 if (rc == RC_FRET)
352 return RC_FRE2;
353 #endif
354 if (rc & RC_FLOAT)
355 return RC_FLOAT;
356 return RC_INT;
359 /* we use our own 'finite' function to avoid potential problems with
360 non standard math libs */
361 /* XXX: endianness dependent */
362 ST_FUNC int ieee_finite(double d)
364 int p[4];
365 memcpy(p, &d, sizeof(double));
366 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
369 /* compiling intel long double natively */
370 #if (defined __i386__ || defined __x86_64__) \
371 && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
372 # define TCC_IS_NATIVE_387
373 #endif
375 ST_FUNC void test_lvalue(void)
377 if (!(vtop->r & VT_LVAL))
378 expect("lvalue");
381 ST_FUNC void check_vstack(void)
383 if (vtop != vstack - 1)
384 tcc_error("internal compiler error: vstack leak (%d)",
385 (int)(vtop - vstack + 1));
388 /* ------------------------------------------------------------------------- */
389 /* vstack debugging aid */
391 #if 0
392 void pv (const char *lbl, int a, int b)
394 int i;
395 for (i = a; i < a + b; ++i) {
396 SValue *p = &vtop[-i];
397 printf("%s vtop[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n",
398 lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);
401 #endif
403 /* ------------------------------------------------------------------------- */
404 /* start of translation unit info */
405 ST_FUNC void tcc_debug_start(TCCState *s1)
407 if (s1->do_debug) {
408 int i;
409 char buf[512];
411 /* file info: full path + filename */
412 section_sym = put_elf_sym(symtab_section, 0, 0,
413 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
414 text_section->sh_num, NULL);
415 getcwd(buf, sizeof(buf));
416 #ifdef _WIN32
417 normalize_slashes(buf);
418 #endif
419 pstrcat(buf, sizeof(buf), "/");
420 put_stabs_r(s1, buf, N_SO, 0, 0,
421 text_section->data_offset, text_section, section_sym);
422 put_stabs_r(s1, file->prev ? file->prev->filename : file->filename,
423 N_SO, 0, 0,
424 text_section->data_offset, text_section, section_sym);
425 for (i = 0; i < sizeof (default_debug) / sizeof (default_debug[0]); i++)
426 put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0);
428 new_file = last_line_num = 0;
429 func_ind = -1;
430 debug_next_type = sizeof(default_debug) / sizeof(default_debug[0]);
431 debug_hash = NULL;
432 n_debug_hash = 0;
434 /* we're currently 'including' the <command line> */
435 tcc_debug_bincl(s1);
438 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
439 symbols can be safely used */
440 put_elf_sym(symtab_section, 0, 0,
441 ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
442 SHN_ABS, file->filename);
445 static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned long value,
446 Section *sec, int sym_index)
448 struct debug_sym *s;
450 if (debug_info) {
451 debug_info->sym =
452 (struct debug_sym *)tcc_realloc (debug_info->sym,
453 sizeof(struct debug_sym) *
454 (debug_info->n_sym + 1));
455 s = debug_info->sym + debug_info->n_sym++;
456 s->type = type;
457 s->value = value;
458 s->str = tcc_strdup(str);
459 s->sec = sec;
460 s->sym_index = sym_index;
462 else if (sec)
463 put_stabs_r (s1, str, type, 0, 0, value, sec, sym_index);
464 else
465 put_stabs (s1, str, type, 0, 0, value);
468 static void tcc_debug_stabn(int type, int value)
470 if (type == N_LBRAC) {
471 struct debug_info *info =
472 (struct debug_info *) tcc_mallocz(sizeof (*info));
474 info->start = value;
475 info->parent = debug_info;
476 if (debug_info) {
477 if (debug_info->child) {
478 if (debug_info->child->last)
479 debug_info->child->last->next = info;
480 else
481 debug_info->child->next = info;
482 debug_info->child->last = info;
484 else
485 debug_info->child = info;
487 else
488 debug_info_root = info;
489 debug_info = info;
491 else {
492 debug_info->end = value;
493 debug_info = debug_info->parent;
497 static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result)
499 int type;
500 int n = 0;
501 int debug_type = -1;
502 Sym *t = s;
503 CString str;
505 for (;;) {
506 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE);
507 if ((type & VT_BTYPE) != VT_BYTE)
508 type &= ~VT_DEFSIGN;
509 if (type == VT_PTR || type == (VT_PTR | VT_ARRAY))
510 n++, t = t->type.ref;
511 else
512 break;
514 if ((type & VT_BTYPE) == VT_STRUCT) {
515 int i;
517 t = t->type.ref;
518 for (i = 0; i < n_debug_hash; i++) {
519 if (t == debug_hash[i].type) {
520 debug_type = debug_hash[i].debug_type;
521 break;
524 if (debug_type == -1) {
525 debug_type = ++debug_next_type;
526 debug_hash = (struct debug_hash *)
527 tcc_realloc (debug_hash,
528 (n_debug_hash + 1) * sizeof(*debug_hash));
529 debug_hash[n_debug_hash].debug_type = debug_type;
530 debug_hash[n_debug_hash++].type = t;
531 cstr_new (&str);
532 cstr_printf (&str, "%s:T%d=%c%d",
533 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
534 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL),
535 debug_type,
536 IS_UNION (t->type.t) ? 'u' : 's',
537 t->c);
538 while (t->next) {
539 int pos, size, align;
541 t = t->next;
542 cstr_printf (&str, "%s:",
543 (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
544 ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL));
545 tcc_get_debug_info (s1, t, &str);
546 if (t->type.t & VT_BITFIELD) {
547 pos = t->c * 8 + BIT_POS(t->type.t);
548 size = BIT_SIZE(t->type.t);
550 else {
551 pos = t->c * 8;
552 size = type_size(&t->type, &align) * 8;
554 cstr_printf (&str, ",%d,%d;", pos, size);
556 cstr_printf (&str, ";");
557 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0);
558 cstr_free (&str);
561 else if (IS_ENUM(type)) {
562 Sym *e = t = t->type.ref;
564 debug_type = ++debug_next_type;
565 cstr_new (&str);
566 cstr_printf (&str, "%s:T%d=e",
567 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
568 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL),
569 debug_type);
570 while (t->next) {
571 t = t->next;
572 cstr_printf (&str, "%s:",
573 (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
574 ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL));
575 cstr_printf (&str, e->type.t & VT_UNSIGNED ? "%u," : "%d,",
576 (int)t->enum_val);
578 cstr_printf (&str, ";");
579 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0);
580 cstr_free (&str);
582 else if ((type & VT_BTYPE) != VT_FUNC) {
583 type &= ~VT_STRUCT_MASK;
584 for (debug_type = 1;
585 debug_type <= sizeof(default_debug) / sizeof(default_debug[0]);
586 debug_type++)
587 if (default_debug[debug_type - 1].type == type)
588 break;
589 if (debug_type > sizeof(default_debug) / sizeof(default_debug[0]))
590 return;
592 if (n > 0)
593 cstr_printf (result, "%d=", ++debug_next_type);
594 t = s;
595 for (;;) {
596 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE);
597 if ((type & VT_BTYPE) != VT_BYTE)
598 type &= ~VT_DEFSIGN;
599 if (type == VT_PTR)
600 cstr_printf (result, "%d=*", ++debug_next_type);
601 else if (type == (VT_PTR | VT_ARRAY))
602 cstr_printf (result, "%d=ar1;0;%d;",
603 ++debug_next_type, t->type.ref->c - 1);
604 else if (type == VT_FUNC) {
605 cstr_printf (result, "%d=f", ++debug_next_type);
606 tcc_get_debug_info (s1, t->type.ref, result);
607 return;
609 else
610 break;
611 t = t->type.ref;
613 cstr_printf (result, "%d", debug_type);
616 static void tcc_debug_finish (TCCState *s1, struct debug_info *cur)
618 while (cur) {
619 int i;
620 struct debug_info *next = cur->next;
622 for (i = 0; i < cur->n_sym; i++) {
623 struct debug_sym *s = &cur->sym[i];
625 if (s->sec)
626 put_stabs_r(s1, s->str, s->type, 0, 0, s->value,
627 s->sec, s->sym_index);
628 else
629 put_stabs(s1, s->str, s->type, 0, 0, s->value);
630 tcc_free (s->str);
632 tcc_free (cur->sym);
633 put_stabn(s1, N_LBRAC, 0, 0, cur->start);
634 tcc_debug_finish (s1, cur->child);
635 put_stabn(s1, N_RBRAC, 0, 0, cur->end);
636 tcc_free (cur);
637 cur = next;
641 static void tcc_add_debug_info(TCCState *s1, int param, Sym *s, Sym *e)
643 CString debug_str;
644 cstr_new (&debug_str);
645 for (; s != e; s = s->prev) {
646 if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL)
647 continue;
648 cstr_reset (&debug_str);
649 cstr_printf (&debug_str, "%s:%s", get_tok_str(s->v, NULL), param ? "p" : "");
650 tcc_get_debug_info(s1, s, &debug_str);
651 tcc_debug_stabs(s1, debug_str.data, param ? N_PSYM : N_LSYM, s->c, NULL, 0);
653 cstr_free (&debug_str);
656 static void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bind)
658 Section *s = s1->sections[sh_num];
659 CString str;
661 cstr_new (&str);
662 cstr_printf (&str, "%s:%c",
663 get_tok_str(sym->v, NULL),
664 sym_bind == STB_GLOBAL ? 'G' : local_scope ? 'V' : 'S'
666 tcc_get_debug_info(s1, sym, &str);
667 if (sym_bind == STB_GLOBAL)
668 tcc_debug_stabs(s1, str.data, N_GSYM, 0, NULL, 0);
669 else
670 tcc_debug_stabs(s1, str.data,
671 (sym->type.t & VT_STATIC) && data_section == s
672 ? N_STSYM : N_LCSYM, 0, s, sym->c);
673 cstr_free (&str);
676 static void tcc_debug_typedef(TCCState *s1, Sym *sym)
678 CString str;
680 cstr_new (&str);
681 cstr_printf (&str, "%s:t",
682 (sym->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
683 ? "" : get_tok_str(sym->v & ~SYM_FIELD, NULL));
684 tcc_get_debug_info(s1, sym, &str);
685 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0);
686 cstr_free (&str);
689 /* put end of translation unit info */
690 ST_FUNC void tcc_debug_end(TCCState *s1)
692 if (!s1->do_debug)
693 return;
694 put_stabs_r(s1, NULL, N_SO, 0, 0,
695 text_section->data_offset, text_section, section_sym);
696 tcc_free(debug_hash);
699 static BufferedFile* put_new_file(TCCState *s1)
701 BufferedFile *f = file;
702 /* use upper file if from inline ":asm:" */
703 if (f->filename[0] == ':')
704 f = f->prev;
705 if (f && new_file) {
706 put_stabs_r(s1, f->filename, N_SOL, 0, 0, ind, text_section, section_sym);
707 new_file = last_line_num = 0;
709 return f;
712 /* generate line number info */
713 ST_FUNC void tcc_debug_line(TCCState *s1)
715 BufferedFile *f;
716 if (!s1->do_debug
717 || cur_text_section != text_section
718 || !(f = put_new_file(s1))
719 || last_line_num == f->line_num)
720 return;
721 if (func_ind != -1) {
722 put_stabn(s1, N_SLINE, 0, f->line_num, ind - func_ind);
723 } else {
724 /* from tcc_assemble */
725 put_stabs_r(s1, NULL, N_SLINE, 0, f->line_num, ind, text_section, section_sym);
727 last_line_num = f->line_num;
730 /* put function symbol */
731 ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
733 CString debug_str;
734 BufferedFile *f;
735 if (!s1->do_debug)
736 return;
737 debug_info_root = NULL;
738 debug_info = NULL;
739 tcc_debug_stabn(N_LBRAC, ind - func_ind);
740 if (!(f = put_new_file(s1)))
741 return;
742 cstr_new (&debug_str);
743 cstr_printf(&debug_str, "%s:%c", funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
744 tcc_get_debug_info(s1, sym->type.ref, &debug_str);
745 put_stabs_r(s1, debug_str.data, N_FUN, 0, f->line_num, 0, cur_text_section, sym->c);
746 cstr_free (&debug_str);
748 tcc_debug_line(s1);
751 /* put function size */
752 ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
754 if (!s1->do_debug)
755 return;
756 tcc_debug_stabn(N_RBRAC, size);
757 tcc_debug_finish (s1, debug_info_root);
760 /* put alternative filename */
761 ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename)
763 if (0 == strcmp(file->filename, filename))
764 return;
765 pstrcpy(file->filename, sizeof(file->filename), filename);
766 new_file = 1;
769 /* begin of #include */
770 ST_FUNC void tcc_debug_bincl(TCCState *s1)
772 if (!s1->do_debug)
773 return;
774 put_stabs(s1, file->filename, N_BINCL, 0, 0, 0);
775 new_file = 1;
778 /* end of #include */
779 ST_FUNC void tcc_debug_eincl(TCCState *s1)
781 if (!s1->do_debug)
782 return;
783 put_stabn(s1, N_EINCL, 0, 0, 0);
784 new_file = 1;
787 /* ------------------------------------------------------------------------- */
788 /* initialize vstack and types. This must be done also for tcc -E */
789 ST_FUNC void tccgen_init(TCCState *s1)
791 vtop = vstack - 1;
792 memset(vtop, 0, sizeof *vtop);
794 /* define some often used types */
795 int_type.t = VT_INT;
797 char_type.t = VT_BYTE;
798 if (s1->char_is_unsigned)
799 char_type.t |= VT_UNSIGNED;
800 char_pointer_type = char_type;
801 mk_pointer(&char_pointer_type);
803 func_old_type.t = VT_FUNC;
804 func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);
805 func_old_type.ref->f.func_call = FUNC_CDECL;
806 func_old_type.ref->f.func_type = FUNC_OLD;
807 #ifdef precedence_parser
808 init_prec();
809 #endif
810 cstr_new(&initstr);
813 ST_FUNC int tccgen_compile(TCCState *s1)
815 cur_text_section = NULL;
816 funcname = "";
817 anon_sym = SYM_FIRST_ANOM;
818 section_sym = 0;
819 const_wanted = 0;
820 nocode_wanted = 0x80000000;
821 local_scope = 0;
823 tcc_debug_start(s1);
824 #ifdef TCC_TARGET_ARM
825 arm_init(s1);
826 #endif
827 #ifdef INC_DEBUG
828 printf("%s: **** new file\n", file->filename);
829 #endif
830 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
831 next();
832 decl(VT_CONST);
833 gen_inline_functions(s1);
834 check_vstack();
835 /* end of translation unit info */
836 tcc_debug_end(s1);
837 return 0;
840 ST_FUNC void tccgen_finish(TCCState *s1)
842 cstr_free(&initstr);
843 free_inline_functions(s1);
844 sym_pop(&global_stack, NULL, 0);
845 sym_pop(&local_stack, NULL, 0);
846 /* free preprocessor macros */
847 free_defines(NULL);
848 /* free sym_pools */
849 dynarray_reset(&sym_pools, &nb_sym_pools);
850 sym_free_first = NULL;
853 /* ------------------------------------------------------------------------- */
854 ST_FUNC ElfSym *elfsym(Sym *s)
856 if (!s || !s->c)
857 return NULL;
858 return &((ElfSym *)symtab_section->data)[s->c];
861 /* apply storage attributes to Elf symbol */
862 ST_FUNC void update_storage(Sym *sym)
864 ElfSym *esym;
865 int sym_bind, old_sym_bind;
867 esym = elfsym(sym);
868 if (!esym)
869 return;
871 if (sym->a.visibility)
872 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
873 | sym->a.visibility;
875 if (sym->type.t & (VT_STATIC | VT_INLINE))
876 sym_bind = STB_LOCAL;
877 else if (sym->a.weak)
878 sym_bind = STB_WEAK;
879 else
880 sym_bind = STB_GLOBAL;
881 old_sym_bind = ELFW(ST_BIND)(esym->st_info);
882 if (sym_bind != old_sym_bind) {
883 esym->st_info = ELFW(ST_INFO)(sym_bind, ELFW(ST_TYPE)(esym->st_info));
886 #ifdef TCC_TARGET_PE
887 if (sym->a.dllimport)
888 esym->st_other |= ST_PE_IMPORT;
889 if (sym->a.dllexport)
890 esym->st_other |= ST_PE_EXPORT;
891 #endif
893 #if 0
894 printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n",
895 get_tok_str(sym->v, NULL),
896 sym_bind == STB_WEAK ? 'w' : sym_bind == STB_LOCAL ? 'l' : 'g',
897 sym->a.visibility,
898 sym->a.dllexport,
899 sym->a.dllimport
901 #endif
904 /* ------------------------------------------------------------------------- */
905 /* update sym->c so that it points to an external symbol in section
906 'section' with value 'value' */
908 ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
909 addr_t value, unsigned long size,
910 int can_add_underscore)
912 int sym_type, sym_bind, info, other, t;
913 ElfSym *esym;
914 const char *name;
915 char buf1[256];
917 if (!sym->c) {
918 name = get_tok_str(sym->v, NULL);
919 t = sym->type.t;
920 if ((t & VT_BTYPE) == VT_FUNC) {
921 sym_type = STT_FUNC;
922 } else if ((t & VT_BTYPE) == VT_VOID) {
923 sym_type = STT_NOTYPE;
924 } else {
925 sym_type = STT_OBJECT;
927 if (t & (VT_STATIC | VT_INLINE))
928 sym_bind = STB_LOCAL;
929 else
930 sym_bind = STB_GLOBAL;
931 other = 0;
933 #ifdef TCC_TARGET_PE
934 if (sym_type == STT_FUNC && sym->type.ref) {
935 Sym *ref = sym->type.ref;
936 if (ref->a.nodecorate) {
937 can_add_underscore = 0;
939 if (ref->f.func_call == FUNC_STDCALL && can_add_underscore) {
940 sprintf(buf1, "_%s@%d", name, ref->f.func_args * PTR_SIZE);
941 name = buf1;
942 other |= ST_PE_STDCALL;
943 can_add_underscore = 0;
946 #endif
948 if (sym->asm_label) {
949 name = get_tok_str(sym->asm_label, NULL);
950 can_add_underscore = 0;
953 if (tcc_state->leading_underscore && can_add_underscore) {
954 buf1[0] = '_';
955 pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
956 name = buf1;
959 info = ELFW(ST_INFO)(sym_bind, sym_type);
960 sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name);
962 if (tcc_state->do_debug
963 && sym_type != STT_FUNC
964 && sym->v < SYM_FIRST_ANOM)
965 tcc_debug_extern_sym(tcc_state, sym, sh_num, sym_bind);
967 } else {
968 esym = elfsym(sym);
969 esym->st_value = value;
970 esym->st_size = size;
971 esym->st_shndx = sh_num;
973 update_storage(sym);
976 ST_FUNC void put_extern_sym(Sym *sym, Section *section,
977 addr_t value, unsigned long size)
979 int sh_num = section ? section->sh_num : SHN_UNDEF;
980 put_extern_sym2(sym, sh_num, value, size, 1);
983 /* add a new relocation entry to symbol 'sym' in section 's' */
984 ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
985 addr_t addend)
987 int c = 0;
989 if (nocode_wanted && s == cur_text_section)
990 return;
992 if (sym) {
993 if (0 == sym->c)
994 put_extern_sym(sym, NULL, 0, 0);
995 c = sym->c;
998 /* now we can add ELF relocation info */
999 put_elf_reloca(symtab_section, s, offset, type, c, addend);
1002 #if PTR_SIZE == 4
1003 ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
1005 greloca(s, sym, offset, type, 0);
1007 #endif
1009 /* ------------------------------------------------------------------------- */
1010 /* symbol allocator */
1011 static Sym *__sym_malloc(void)
1013 Sym *sym_pool, *sym, *last_sym;
1014 int i;
1016 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
1017 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
1019 last_sym = sym_free_first;
1020 sym = sym_pool;
1021 for(i = 0; i < SYM_POOL_NB; i++) {
1022 sym->next = last_sym;
1023 last_sym = sym;
1024 sym++;
1026 sym_free_first = last_sym;
1027 return last_sym;
1030 static inline Sym *sym_malloc(void)
1032 Sym *sym;
1033 #ifndef SYM_DEBUG
1034 sym = sym_free_first;
1035 if (!sym)
1036 sym = __sym_malloc();
1037 sym_free_first = sym->next;
1038 return sym;
1039 #else
1040 sym = tcc_malloc(sizeof(Sym));
1041 return sym;
1042 #endif
1045 ST_INLN void sym_free(Sym *sym)
1047 #ifndef SYM_DEBUG
1048 sym->next = sym_free_first;
1049 sym_free_first = sym;
1050 #else
1051 tcc_free(sym);
1052 #endif
1055 /* push, without hashing */
1056 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c)
1058 Sym *s;
1060 s = sym_malloc();
1061 memset(s, 0, sizeof *s);
1062 s->v = v;
1063 s->type.t = t;
1064 s->c = c;
1065 /* add in stack */
1066 s->prev = *ps;
1067 *ps = s;
1068 return s;
1071 /* find a symbol and return its associated structure. 's' is the top
1072 of the symbol stack */
1073 ST_FUNC Sym *sym_find2(Sym *s, int v)
1075 while (s) {
1076 if (s->v == v)
1077 return s;
1078 else if (s->v == -1)
1079 return NULL;
1080 s = s->prev;
1082 return NULL;
1085 /* structure lookup */
1086 ST_INLN Sym *struct_find(int v)
1088 v -= TOK_IDENT;
1089 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1090 return NULL;
1091 return table_ident[v]->sym_struct;
1094 /* find an identifier */
1095 ST_INLN Sym *sym_find(int v)
1097 v -= TOK_IDENT;
1098 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1099 return NULL;
1100 return table_ident[v]->sym_identifier;
1103 static int sym_scope(Sym *s)
1105 if (IS_ENUM_VAL (s->type.t))
1106 return s->type.ref->sym_scope;
1107 else
1108 return s->sym_scope;
1111 /* push a given symbol on the symbol stack */
1112 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
1114 Sym *s, **ps;
1115 TokenSym *ts;
1117 if (local_stack)
1118 ps = &local_stack;
1119 else
1120 ps = &global_stack;
1121 s = sym_push2(ps, v, type->t, c);
1122 s->type.ref = type->ref;
1123 s->r = r;
1124 /* don't record fields or anonymous symbols */
1125 /* XXX: simplify */
1126 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1127 /* record symbol in token array */
1128 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1129 if (v & SYM_STRUCT)
1130 ps = &ts->sym_struct;
1131 else
1132 ps = &ts->sym_identifier;
1133 s->prev_tok = *ps;
1134 *ps = s;
1135 s->sym_scope = local_scope;
1136 if (s->prev_tok && sym_scope(s->prev_tok) == s->sym_scope)
1137 tcc_error("redeclaration of '%s'",
1138 get_tok_str(v & ~SYM_STRUCT, NULL));
1140 return s;
1143 /* push a global identifier */
1144 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
1146 Sym *s, **ps;
1147 s = sym_push2(&global_stack, v, t, c);
1148 s->r = VT_CONST | VT_SYM;
1149 /* don't record anonymous symbol */
1150 if (v < SYM_FIRST_ANOM) {
1151 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
1152 /* modify the top most local identifier, so that sym_identifier will
1153 point to 's' when popped; happens when called from inline asm */
1154 while (*ps != NULL && (*ps)->sym_scope)
1155 ps = &(*ps)->prev_tok;
1156 s->prev_tok = *ps;
1157 *ps = s;
1159 return s;
1162 /* pop symbols until top reaches 'b'. If KEEP is non-zero don't really
1163 pop them yet from the list, but do remove them from the token array. */
1164 ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep)
1166 Sym *s, *ss, **ps;
1167 TokenSym *ts;
1168 int v;
1170 s = *ptop;
1171 while(s != b) {
1172 ss = s->prev;
1173 v = s->v;
1174 /* remove symbol in token array */
1175 /* XXX: simplify */
1176 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1177 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1178 if (v & SYM_STRUCT)
1179 ps = &ts->sym_struct;
1180 else
1181 ps = &ts->sym_identifier;
1182 *ps = s->prev_tok;
1184 if (!keep)
1185 sym_free(s);
1186 s = ss;
1188 if (!keep)
1189 *ptop = b;
1192 /* ------------------------------------------------------------------------- */
1193 static void vcheck_cmp(void)
1195 /* cannot let cpu flags if other instruction are generated. Also
1196 avoid leaving VT_JMP anywhere except on the top of the stack
1197 because it would complicate the code generator.
1199 Don't do this when nocode_wanted. vtop might come from
1200 !nocode_wanted regions (see 88_codeopt.c) and transforming
1201 it to a register without actually generating code is wrong
1202 as their value might still be used for real. All values
1203 we push under nocode_wanted will eventually be popped
1204 again, so that the VT_CMP/VT_JMP value will be in vtop
1205 when code is unsuppressed again. */
1207 if (vtop->r == VT_CMP && !nocode_wanted)
1208 gv(RC_INT);
1211 static void vsetc(CType *type, int r, CValue *vc)
1213 if (vtop >= vstack + (VSTACK_SIZE - 1))
1214 tcc_error("memory full (vstack)");
1215 vcheck_cmp();
1216 vtop++;
1217 vtop->type = *type;
1218 vtop->r = r;
1219 vtop->r2 = VT_CONST;
1220 vtop->c = *vc;
1221 vtop->sym = NULL;
1224 ST_FUNC void vswap(void)
1226 SValue tmp;
1228 vcheck_cmp();
1229 tmp = vtop[0];
1230 vtop[0] = vtop[-1];
1231 vtop[-1] = tmp;
1234 /* pop stack value */
1235 ST_FUNC void vpop(void)
1237 int v;
1238 v = vtop->r & VT_VALMASK;
1239 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1240 /* for x86, we need to pop the FP stack */
1241 if (v == TREG_ST0) {
1242 o(0xd8dd); /* fstp %st(0) */
1243 } else
1244 #endif
1245 if (v == VT_CMP) {
1246 /* need to put correct jump if && or || without test */
1247 gsym(vtop->jtrue);
1248 gsym(vtop->jfalse);
1250 vtop--;
1253 /* push constant of type "type" with useless value */
1254 static void vpush(CType *type)
1256 vset(type, VT_CONST, 0);
1259 /* push arbitrary 64bit constant */
1260 static void vpush64(int ty, unsigned long long v)
1262 CValue cval;
1263 CType ctype;
1264 ctype.t = ty;
1265 ctype.ref = NULL;
1266 cval.i = v;
1267 vsetc(&ctype, VT_CONST, &cval);
1270 /* push integer constant */
1271 ST_FUNC void vpushi(int v)
1273 vpush64(VT_INT, v);
1276 /* push a pointer sized constant */
1277 static void vpushs(addr_t v)
1279 vpush64(VT_SIZE_T, v);
1282 /* push long long constant */
1283 static inline void vpushll(long long v)
1285 vpush64(VT_LLONG, v);
1288 ST_FUNC void vset(CType *type, int r, int v)
1290 CValue cval;
1291 cval.i = v;
1292 vsetc(type, r, &cval);
1295 static void vseti(int r, int v)
1297 CType type;
1298 type.t = VT_INT;
1299 type.ref = NULL;
1300 vset(&type, r, v);
1303 ST_FUNC void vpushv(SValue *v)
1305 if (vtop >= vstack + (VSTACK_SIZE - 1))
1306 tcc_error("memory full (vstack)");
1307 vtop++;
1308 *vtop = *v;
1311 static void vdup(void)
1313 vpushv(vtop);
1316 /* rotate n first stack elements to the bottom
1317 I1 ... In -> I2 ... In I1 [top is right]
1319 ST_FUNC void vrotb(int n)
1321 int i;
1322 SValue tmp;
1324 vcheck_cmp();
1325 tmp = vtop[-n + 1];
1326 for(i=-n+1;i!=0;i++)
1327 vtop[i] = vtop[i+1];
1328 vtop[0] = tmp;
1331 /* rotate the n elements before entry e towards the top
1332 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1334 ST_FUNC void vrote(SValue *e, int n)
1336 int i;
1337 SValue tmp;
1339 vcheck_cmp();
1340 tmp = *e;
1341 for(i = 0;i < n - 1; i++)
1342 e[-i] = e[-i - 1];
1343 e[-n + 1] = tmp;
1346 /* rotate n first stack elements to the top
1347 I1 ... In -> In I1 ... I(n-1) [top is right]
1349 ST_FUNC void vrott(int n)
1351 vrote(vtop, n);
1354 /* ------------------------------------------------------------------------- */
1355 /* vtop->r = VT_CMP means CPU-flags have been set from comparison or test. */
1357 /* called from generators to set the result from relational ops */
1358 ST_FUNC void vset_VT_CMP(int op)
1360 vtop->r = VT_CMP;
1361 vtop->cmp_op = op;
1362 vtop->jfalse = 0;
1363 vtop->jtrue = 0;
1366 /* called once before asking generators to load VT_CMP to a register */
1367 static void vset_VT_JMP(void)
1369 int op = vtop->cmp_op;
1371 if (vtop->jtrue || vtop->jfalse) {
1372 /* we need to jump to 'mov $0,%R' or 'mov $1,%R' */
1373 int inv = op & (op < 2); /* small optimization */
1374 vseti(VT_JMP+inv, gvtst(inv, 0));
1375 } else {
1376 /* otherwise convert flags (rsp. 0/1) to register */
1377 vtop->c.i = op;
1378 if (op < 2) /* doesn't seem to happen */
1379 vtop->r = VT_CONST;
1383 /* Set CPU Flags, doesn't yet jump */
1384 static void gvtst_set(int inv, int t)
1386 int *p;
1388 if (vtop->r != VT_CMP) {
1389 vpushi(0);
1390 gen_op(TOK_NE);
1391 if (vtop->r != VT_CMP) /* must be VT_CONST then */
1392 vset_VT_CMP(vtop->c.i != 0);
1395 p = inv ? &vtop->jfalse : &vtop->jtrue;
1396 *p = gjmp_append(*p, t);
1399 /* Generate value test
1401 * Generate a test for any value (jump, comparison and integers) */
1402 static int gvtst(int inv, int t)
1404 int op, x, u;
1406 gvtst_set(inv, t);
1407 t = vtop->jtrue, u = vtop->jfalse;
1408 if (inv)
1409 x = u, u = t, t = x;
1410 op = vtop->cmp_op;
1412 /* jump to the wanted target */
1413 if (op > 1)
1414 t = gjmp_cond(op ^ inv, t);
1415 else if (op != inv)
1416 t = gjmp(t);
1417 /* resolve complementary jumps to here */
1418 gsym(u);
1420 vtop--;
1421 return t;
1424 /* generate a zero or nozero test */
1425 static void gen_test_zero(int op)
1427 if (vtop->r == VT_CMP) {
1428 int j;
1429 if (op == TOK_EQ) {
1430 j = vtop->jfalse;
1431 vtop->jfalse = vtop->jtrue;
1432 vtop->jtrue = j;
1433 vtop->cmp_op ^= 1;
1435 } else {
1436 vpushi(0);
1437 gen_op(op);
1441 /* ------------------------------------------------------------------------- */
1442 /* push a symbol value of TYPE */
1443 static inline void vpushsym(CType *type, Sym *sym)
1445 CValue cval;
1446 cval.i = 0;
1447 vsetc(type, VT_CONST | VT_SYM, &cval);
1448 vtop->sym = sym;
1451 /* Return a static symbol pointing to a section */
1452 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
1454 int v;
1455 Sym *sym;
1457 v = anon_sym++;
1458 sym = sym_push(v, type, VT_CONST | VT_SYM, 0);
1459 sym->type.t |= VT_STATIC;
1460 put_extern_sym(sym, sec, offset, size);
1461 return sym;
1464 /* push a reference to a section offset by adding a dummy symbol */
1465 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
1467 vpushsym(type, get_sym_ref(type, sec, offset, size));
1470 /* define a new external reference to a symbol 'v' of type 'u' */
1471 ST_FUNC Sym *external_global_sym(int v, CType *type)
1473 Sym *s;
1475 s = sym_find(v);
1476 if (!s) {
1477 /* push forward reference */
1478 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
1479 s->type.ref = type->ref;
1480 } else if (IS_ASM_SYM(s)) {
1481 s->type.t = type->t | (s->type.t & VT_EXTERN);
1482 s->type.ref = type->ref;
1483 update_storage(s);
1485 return s;
1488 /* Merge symbol attributes. */
1489 static void merge_symattr(struct SymAttr *sa, struct SymAttr *sa1)
1491 if (sa1->aligned && !sa->aligned)
1492 sa->aligned = sa1->aligned;
1493 sa->packed |= sa1->packed;
1494 sa->weak |= sa1->weak;
1495 if (sa1->visibility != STV_DEFAULT) {
1496 int vis = sa->visibility;
1497 if (vis == STV_DEFAULT
1498 || vis > sa1->visibility)
1499 vis = sa1->visibility;
1500 sa->visibility = vis;
1502 sa->dllexport |= sa1->dllexport;
1503 sa->nodecorate |= sa1->nodecorate;
1504 sa->dllimport |= sa1->dllimport;
1507 /* Merge function attributes. */
1508 static void merge_funcattr(struct FuncAttr *fa, struct FuncAttr *fa1)
1510 if (fa1->func_call && !fa->func_call)
1511 fa->func_call = fa1->func_call;
1512 if (fa1->func_type && !fa->func_type)
1513 fa->func_type = fa1->func_type;
1514 if (fa1->func_args && !fa->func_args)
1515 fa->func_args = fa1->func_args;
1516 if (fa1->func_noreturn)
1517 fa->func_noreturn = 1;
1518 if (fa1->func_ctor)
1519 fa->func_ctor = 1;
1520 if (fa1->func_dtor)
1521 fa->func_dtor = 1;
1524 /* Merge attributes. */
1525 static void merge_attr(AttributeDef *ad, AttributeDef *ad1)
1527 merge_symattr(&ad->a, &ad1->a);
1528 merge_funcattr(&ad->f, &ad1->f);
1530 if (ad1->section)
1531 ad->section = ad1->section;
1532 if (ad1->alias_target)
1533 ad->alias_target = ad1->alias_target;
1534 if (ad1->asm_label)
1535 ad->asm_label = ad1->asm_label;
1536 if (ad1->attr_mode)
1537 ad->attr_mode = ad1->attr_mode;
1540 /* Merge some type attributes. */
1541 static void patch_type(Sym *sym, CType *type)
1543 if (!(type->t & VT_EXTERN) || IS_ENUM_VAL(sym->type.t)) {
1544 if (!(sym->type.t & VT_EXTERN))
1545 tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL));
1546 sym->type.t &= ~VT_EXTERN;
1549 if (IS_ASM_SYM(sym)) {
1550 /* stay static if both are static */
1551 sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
1552 sym->type.ref = type->ref;
1555 if (!is_compatible_types(&sym->type, type)) {
1556 tcc_error("incompatible types for redefinition of '%s'",
1557 get_tok_str(sym->v, NULL));
1559 } else if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
1560 int static_proto = sym->type.t & VT_STATIC;
1561 /* warn if static follows non-static function declaration */
1562 if ((type->t & VT_STATIC) && !static_proto
1563 /* XXX this test for inline shouldn't be here. Until we
1564 implement gnu-inline mode again it silences a warning for
1565 mingw caused by our workarounds. */
1566 && !((type->t | sym->type.t) & VT_INLINE))
1567 tcc_warning("static storage ignored for redefinition of '%s'",
1568 get_tok_str(sym->v, NULL));
1570 /* set 'inline' if both agree or if one has static */
1571 if ((type->t | sym->type.t) & VT_INLINE) {
1572 if (!((type->t ^ sym->type.t) & VT_INLINE)
1573 || ((type->t | sym->type.t) & VT_STATIC))
1574 static_proto |= VT_INLINE;
1577 if (0 == (type->t & VT_EXTERN)) {
1578 struct FuncAttr f = sym->type.ref->f;
1579 /* put complete type, use static from prototype */
1580 sym->type.t = (type->t & ~(VT_STATIC|VT_INLINE)) | static_proto;
1581 sym->type.ref = type->ref;
1582 merge_funcattr(&sym->type.ref->f, &f);
1583 } else {
1584 sym->type.t &= ~VT_INLINE | static_proto;
1587 if (sym->type.ref->f.func_type == FUNC_OLD
1588 && type->ref->f.func_type != FUNC_OLD) {
1589 sym->type.ref = type->ref;
1592 } else {
1593 if ((sym->type.t & VT_ARRAY) && type->ref->c >= 0) {
1594 /* set array size if it was omitted in extern declaration */
1595 sym->type.ref->c = type->ref->c;
1597 if ((type->t ^ sym->type.t) & VT_STATIC)
1598 tcc_warning("storage mismatch for redefinition of '%s'",
1599 get_tok_str(sym->v, NULL));
1603 /* Merge some storage attributes. */
1604 static void patch_storage(Sym *sym, AttributeDef *ad, CType *type)
1606 if (type)
1607 patch_type(sym, type);
1609 #ifdef TCC_TARGET_PE
1610 if (sym->a.dllimport != ad->a.dllimport)
1611 tcc_error("incompatible dll linkage for redefinition of '%s'",
1612 get_tok_str(sym->v, NULL));
1613 #endif
1614 merge_symattr(&sym->a, &ad->a);
1615 if (ad->asm_label)
1616 sym->asm_label = ad->asm_label;
1617 update_storage(sym);
1620 /* copy sym to other stack */
1621 static Sym *sym_copy(Sym *s0, Sym **ps)
1623 Sym *s;
1624 s = sym_malloc(), *s = *s0;
1625 s->prev = *ps, *ps = s;
1626 if (s->v < SYM_FIRST_ANOM) {
1627 ps = &table_ident[s->v - TOK_IDENT]->sym_identifier;
1628 s->prev_tok = *ps, *ps = s;
1630 return s;
1633 /* copy s->type.ref to stack 'ps' for VT_FUNC and VT_PTR */
1634 static void sym_copy_ref(Sym *s, Sym **ps)
1636 int bt = s->type.t & VT_BTYPE;
1637 if (bt == VT_FUNC || bt == VT_PTR) {
1638 Sym **sp = &s->type.ref;
1639 for (s = *sp, *sp = NULL; s; s = s->next) {
1640 Sym *s2 = sym_copy(s, ps);
1641 sp = &(*sp = s2)->next;
1642 sym_copy_ref(s2, ps);
1647 /* define a new external reference to a symbol 'v' */
1648 static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad)
1650 Sym *s;
1652 /* look for global symbol */
1653 s = sym_find(v);
1654 while (s && s->sym_scope)
1655 s = s->prev_tok;
1657 if (!s) {
1658 /* push forward reference */
1659 s = global_identifier_push(v, type->t, 0);
1660 s->r |= r;
1661 s->a = ad->a;
1662 s->asm_label = ad->asm_label;
1663 s->type.ref = type->ref;
1664 /* copy type to the global stack */
1665 if (local_stack)
1666 sym_copy_ref(s, &global_stack);
1667 } else {
1668 patch_storage(s, ad, type);
1670 /* push variables on local_stack if any */
1671 if (local_stack && (s->type.t & VT_BTYPE) != VT_FUNC)
1672 s = sym_copy(s, &local_stack);
1673 return s;
1676 /* push a reference to global symbol v */
1677 ST_FUNC void vpush_global_sym(CType *type, int v)
1679 vpushsym(type, external_global_sym(v, type));
1682 /* save registers up to (vtop - n) stack entry */
1683 ST_FUNC void save_regs(int n)
1685 SValue *p, *p1;
1686 for(p = vstack, p1 = vtop - n; p <= p1; p++)
1687 save_reg(p->r);
1690 /* save r to the memory stack, and mark it as being free */
1691 ST_FUNC void save_reg(int r)
1693 save_reg_upstack(r, 0);
1696 /* save r to the memory stack, and mark it as being free,
1697 if seen up to (vtop - n) stack entry */
1698 ST_FUNC void save_reg_upstack(int r, int n)
1700 int l, size, align, bt;
1701 SValue *p, *p1, sv;
1703 if ((r &= VT_VALMASK) >= VT_CONST)
1704 return;
1705 if (nocode_wanted)
1706 return;
1707 l = 0;
1708 for(p = vstack, p1 = vtop - n; p <= p1; p++) {
1709 if ((p->r & VT_VALMASK) == r || p->r2 == r) {
1710 /* must save value on stack if not already done */
1711 if (!l) {
1712 bt = p->type.t & VT_BTYPE;
1713 if (bt == VT_VOID)
1714 continue;
1715 if ((p->r & VT_LVAL) || bt == VT_FUNC)
1716 bt = VT_PTR;
1717 sv.type.t = bt;
1718 size = type_size(&sv.type, &align);
1719 l = get_temp_local_var(size,align);
1720 sv.r = VT_LOCAL | VT_LVAL;
1721 sv.c.i = l;
1722 store(p->r & VT_VALMASK, &sv);
1723 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1724 /* x86 specific: need to pop fp register ST0 if saved */
1725 if (r == TREG_ST0) {
1726 o(0xd8dd); /* fstp %st(0) */
1728 #endif
1729 /* special long long case */
1730 if (p->r2 < VT_CONST && USING_TWO_WORDS(bt)) {
1731 sv.c.i += PTR_SIZE;
1732 store(p->r2, &sv);
1735 /* mark that stack entry as being saved on the stack */
1736 if (p->r & VT_LVAL) {
1737 /* also clear the bounded flag because the
1738 relocation address of the function was stored in
1739 p->c.i */
1740 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
1741 } else {
1742 p->r = VT_LVAL | VT_LOCAL;
1744 p->r2 = VT_CONST;
1745 p->c.i = l;
1750 #ifdef TCC_TARGET_ARM
1751 /* find a register of class 'rc2' with at most one reference on stack.
1752 * If none, call get_reg(rc) */
1753 ST_FUNC int get_reg_ex(int rc, int rc2)
1755 int r;
1756 SValue *p;
1758 for(r=0;r<NB_REGS;r++) {
1759 if (reg_classes[r] & rc2) {
1760 int n;
1761 n=0;
1762 for(p = vstack; p <= vtop; p++) {
1763 if ((p->r & VT_VALMASK) == r ||
1764 p->r2 == r)
1765 n++;
1767 if (n <= 1)
1768 return r;
1771 return get_reg(rc);
1773 #endif
1775 /* find a free register of class 'rc'. If none, save one register */
1776 ST_FUNC int get_reg(int rc)
1778 int r;
1779 SValue *p;
1781 /* find a free register */
1782 for(r=0;r<NB_REGS;r++) {
1783 if (reg_classes[r] & rc) {
1784 if (nocode_wanted)
1785 return r;
1786 for(p=vstack;p<=vtop;p++) {
1787 if ((p->r & VT_VALMASK) == r ||
1788 p->r2 == r)
1789 goto notfound;
1791 return r;
1793 notfound: ;
1796 /* no register left : free the first one on the stack (VERY
1797 IMPORTANT to start from the bottom to ensure that we don't
1798 spill registers used in gen_opi()) */
1799 for(p=vstack;p<=vtop;p++) {
1800 /* look at second register (if long long) */
1801 r = p->r2;
1802 if (r < VT_CONST && (reg_classes[r] & rc))
1803 goto save_found;
1804 r = p->r & VT_VALMASK;
1805 if (r < VT_CONST && (reg_classes[r] & rc)) {
1806 save_found:
1807 save_reg(r);
1808 return r;
1811 /* Should never comes here */
1812 return -1;
1815 /* find a free temporary local variable (return the offset on stack) match the size and align. If none, add new temporary stack variable*/
1816 static int get_temp_local_var(int size,int align){
1817 int i;
1818 struct temp_local_variable *temp_var;
1819 int found_var;
1820 SValue *p;
1821 int r;
1822 char free;
1823 char found;
1824 found=0;
1825 for(i=0;i<nb_temp_local_vars;i++){
1826 temp_var=&arr_temp_local_vars[i];
1827 if(temp_var->size<size||align!=temp_var->align){
1828 continue;
1830 /*check if temp_var is free*/
1831 free=1;
1832 for(p=vstack;p<=vtop;p++) {
1833 r=p->r&VT_VALMASK;
1834 if(r==VT_LOCAL||r==VT_LLOCAL){
1835 if(p->c.i==temp_var->location){
1836 free=0;
1837 break;
1841 if(free){
1842 found_var=temp_var->location;
1843 found=1;
1844 break;
1847 if(!found){
1848 loc = (loc - size) & -align;
1849 if(nb_temp_local_vars<MAX_TEMP_LOCAL_VARIABLE_NUMBER){
1850 temp_var=&arr_temp_local_vars[i];
1851 temp_var->location=loc;
1852 temp_var->size=size;
1853 temp_var->align=align;
1854 nb_temp_local_vars++;
1856 found_var=loc;
1858 return found_var;
1861 static void clear_temp_local_var_list(){
1862 nb_temp_local_vars=0;
1865 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
1866 if needed */
1867 static void move_reg(int r, int s, int t)
1869 SValue sv;
1871 if (r != s) {
1872 save_reg(r);
1873 sv.type.t = t;
1874 sv.type.ref = NULL;
1875 sv.r = s;
1876 sv.c.i = 0;
1877 load(r, &sv);
1881 /* get address of vtop (vtop MUST BE an lvalue) */
1882 ST_FUNC void gaddrof(void)
1884 vtop->r &= ~VT_LVAL;
1885 /* tricky: if saved lvalue, then we can go back to lvalue */
1886 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
1887 vtop->r = (vtop->r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
1890 #ifdef CONFIG_TCC_BCHECK
1891 /* generate a bounded pointer addition */
1892 static void gen_bounded_ptr_add(void)
1894 int save = (vtop[-1].r & VT_VALMASK) == VT_LOCAL;
1895 if (save) {
1896 vpushv(&vtop[-1]);
1897 vrott(3);
1899 vpush_global_sym(&func_old_type, TOK___bound_ptr_add);
1900 vrott(3);
1901 gfunc_call(2);
1902 vtop -= save;
1903 vpushi(0);
1904 /* returned pointer is in REG_IRET */
1905 vtop->r = REG_IRET | VT_BOUNDED;
1906 if (nocode_wanted)
1907 return;
1908 /* relocation offset of the bounding function call point */
1909 vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(ElfW_Rel));
1912 /* patch pointer addition in vtop so that pointer dereferencing is
1913 also tested */
1914 static void gen_bounded_ptr_deref(void)
1916 addr_t func;
1917 int size, align;
1918 ElfW_Rel *rel;
1919 Sym *sym;
1921 if (nocode_wanted)
1922 return;
1924 size = type_size(&vtop->type, &align);
1925 switch(size) {
1926 case 1: func = TOK___bound_ptr_indir1; break;
1927 case 2: func = TOK___bound_ptr_indir2; break;
1928 case 4: func = TOK___bound_ptr_indir4; break;
1929 case 8: func = TOK___bound_ptr_indir8; break;
1930 case 12: func = TOK___bound_ptr_indir12; break;
1931 case 16: func = TOK___bound_ptr_indir16; break;
1932 default:
1933 /* may happen with struct member access */
1934 return;
1936 sym = external_global_sym(func, &func_old_type);
1937 if (!sym->c)
1938 put_extern_sym(sym, NULL, 0, 0);
1939 /* patch relocation */
1940 /* XXX: find a better solution ? */
1941 rel = (ElfW_Rel *)(cur_text_section->reloc->data + vtop->c.i);
1942 rel->r_info = ELFW(R_INFO)(sym->c, ELFW(R_TYPE)(rel->r_info));
1945 /* generate lvalue bound code */
1946 static void gbound(void)
1948 CType type1;
1950 vtop->r &= ~VT_MUSTBOUND;
1951 /* if lvalue, then use checking code before dereferencing */
1952 if (vtop->r & VT_LVAL) {
1953 /* if not VT_BOUNDED value, then make one */
1954 if (!(vtop->r & VT_BOUNDED)) {
1955 /* must save type because we must set it to int to get pointer */
1956 type1 = vtop->type;
1957 vtop->type.t = VT_PTR;
1958 gaddrof();
1959 vpushi(0);
1960 gen_bounded_ptr_add();
1961 vtop->r |= VT_LVAL;
1962 vtop->type = type1;
1964 /* then check for dereferencing */
1965 gen_bounded_ptr_deref();
1969 /* we need to call __bound_ptr_add before we start to load function
1970 args into registers */
1971 ST_FUNC void gbound_args(int nb_args)
1973 int i, v;
1974 SValue *sv;
1976 for (i = 1; i <= nb_args; ++i)
1977 if (vtop[1 - i].r & VT_MUSTBOUND) {
1978 vrotb(i);
1979 gbound();
1980 vrott(i);
1983 sv = vtop - nb_args;
1984 if (sv->r & VT_SYM) {
1985 v = sv->sym->v;
1986 if (v == TOK_setjmp
1987 || v == TOK__setjmp
1988 #ifndef TCC_TARGET_PE
1989 || v == TOK_sigsetjmp
1990 || v == TOK___sigsetjmp
1991 #endif
1993 vpush_global_sym(&func_old_type, TOK___bound_setjmp);
1994 vpushv(sv + 1);
1995 gfunc_call(1);
1996 func_bound_add_epilog = 1;
1998 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
1999 if (v == TOK_alloca)
2000 func_bound_add_epilog = 1;
2001 #endif
2005 /* Add bounds for local symbols from S to E (via ->prev) */
2006 static void add_local_bounds(Sym *s, Sym *e)
2008 for (; s != e; s = s->prev) {
2009 if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL)
2010 continue;
2011 /* Add arrays/structs/unions because we always take address */
2012 if ((s->type.t & VT_ARRAY)
2013 || (s->type.t & VT_BTYPE) == VT_STRUCT
2014 || s->a.addrtaken) {
2015 /* add local bound info */
2016 int align, size = type_size(&s->type, &align);
2017 addr_t *bounds_ptr = section_ptr_add(lbounds_section,
2018 2 * sizeof(addr_t));
2019 bounds_ptr[0] = s->c;
2020 bounds_ptr[1] = size;
2024 #endif
2026 /* Wrapper around sym_pop, that potentially also registers local bounds. */
2027 static void pop_local_syms(Sym **ptop, Sym *b, int keep, int ellipsis)
2029 #ifdef CONFIG_TCC_BCHECK
2030 if (tcc_state->do_bounds_check && !ellipsis && !keep)
2031 add_local_bounds(*ptop, b);
2032 #endif
2033 if (tcc_state->do_debug)
2034 tcc_add_debug_info (tcc_state, !local_scope, *ptop, b);
2035 sym_pop(ptop, b, keep);
2038 static void incr_bf_adr(int o)
2040 vtop->type = char_pointer_type;
2041 gaddrof();
2042 vpushs(o);
2043 gen_op('+');
2044 vtop->type.t = VT_BYTE | VT_UNSIGNED;
2045 vtop->r |= VT_LVAL;
2048 /* single-byte load mode for packed or otherwise unaligned bitfields */
2049 static void load_packed_bf(CType *type, int bit_pos, int bit_size)
2051 int n, o, bits;
2052 save_reg_upstack(vtop->r, 1);
2053 vpush64(type->t & VT_BTYPE, 0); // B X
2054 bits = 0, o = bit_pos >> 3, bit_pos &= 7;
2055 do {
2056 vswap(); // X B
2057 incr_bf_adr(o);
2058 vdup(); // X B B
2059 n = 8 - bit_pos;
2060 if (n > bit_size)
2061 n = bit_size;
2062 if (bit_pos)
2063 vpushi(bit_pos), gen_op(TOK_SHR), bit_pos = 0; // X B Y
2064 if (n < 8)
2065 vpushi((1 << n) - 1), gen_op('&');
2066 gen_cast(type);
2067 if (bits)
2068 vpushi(bits), gen_op(TOK_SHL);
2069 vrotb(3); // B Y X
2070 gen_op('|'); // B X
2071 bits += n, bit_size -= n, o = 1;
2072 } while (bit_size);
2073 vswap(), vpop();
2074 if (!(type->t & VT_UNSIGNED)) {
2075 n = ((type->t & VT_BTYPE) == VT_LLONG ? 64 : 32) - bits;
2076 vpushi(n), gen_op(TOK_SHL);
2077 vpushi(n), gen_op(TOK_SAR);
2081 /* single-byte store mode for packed or otherwise unaligned bitfields */
2082 static void store_packed_bf(int bit_pos, int bit_size)
2084 int bits, n, o, m, c;
2086 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2087 vswap(); // X B
2088 save_reg_upstack(vtop->r, 1);
2089 bits = 0, o = bit_pos >> 3, bit_pos &= 7;
2090 do {
2091 incr_bf_adr(o); // X B
2092 vswap(); //B X
2093 c ? vdup() : gv_dup(); // B V X
2094 vrott(3); // X B V
2095 if (bits)
2096 vpushi(bits), gen_op(TOK_SHR);
2097 if (bit_pos)
2098 vpushi(bit_pos), gen_op(TOK_SHL);
2099 n = 8 - bit_pos;
2100 if (n > bit_size)
2101 n = bit_size;
2102 if (n < 8) {
2103 m = ((1 << n) - 1) << bit_pos;
2104 vpushi(m), gen_op('&'); // X B V1
2105 vpushv(vtop-1); // X B V1 B
2106 vpushi(m & 0x80 ? ~m & 0x7f : ~m);
2107 gen_op('&'); // X B V1 B1
2108 gen_op('|'); // X B V2
2110 vdup(), vtop[-1] = vtop[-2]; // X B B V2
2111 vstore(), vpop(); // X B
2112 bits += n, bit_size -= n, bit_pos = 0, o = 1;
2113 } while (bit_size);
2114 vpop(), vpop();
2117 static int adjust_bf(SValue *sv, int bit_pos, int bit_size)
2119 int t;
2120 if (0 == sv->type.ref)
2121 return 0;
2122 t = sv->type.ref->auxtype;
2123 if (t != -1 && t != VT_STRUCT) {
2124 sv->type.t = (sv->type.t & ~(VT_BTYPE | VT_LONG)) | t;
2125 sv->r |= VT_LVAL;
2127 return t;
2130 /* store vtop a register belonging to class 'rc'. lvalues are
2131 converted to values. Cannot be used if cannot be converted to
2132 register value (such as structures). */
2133 ST_FUNC int gv(int rc)
2135 int r, r2, r_ok, r2_ok, rc2, bt;
2136 int bit_pos, bit_size, size, align;
2138 /* NOTE: get_reg can modify vstack[] */
2139 if (vtop->type.t & VT_BITFIELD) {
2140 CType type;
2142 bit_pos = BIT_POS(vtop->type.t);
2143 bit_size = BIT_SIZE(vtop->type.t);
2144 /* remove bit field info to avoid loops */
2145 vtop->type.t &= ~VT_STRUCT_MASK;
2147 type.ref = NULL;
2148 type.t = vtop->type.t & VT_UNSIGNED;
2149 if ((vtop->type.t & VT_BTYPE) == VT_BOOL)
2150 type.t |= VT_UNSIGNED;
2152 r = adjust_bf(vtop, bit_pos, bit_size);
2154 if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
2155 type.t |= VT_LLONG;
2156 else
2157 type.t |= VT_INT;
2159 if (r == VT_STRUCT) {
2160 load_packed_bf(&type, bit_pos, bit_size);
2161 } else {
2162 int bits = (type.t & VT_BTYPE) == VT_LLONG ? 64 : 32;
2163 /* cast to int to propagate signedness in following ops */
2164 gen_cast(&type);
2165 /* generate shifts */
2166 vpushi(bits - (bit_pos + bit_size));
2167 gen_op(TOK_SHL);
2168 vpushi(bits - bit_size);
2169 /* NOTE: transformed to SHR if unsigned */
2170 gen_op(TOK_SAR);
2172 r = gv(rc);
2173 } else {
2174 if (is_float(vtop->type.t) &&
2175 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2176 /* CPUs usually cannot use float constants, so we store them
2177 generically in data segment */
2178 init_params p = { data_section };
2179 unsigned long offset;
2180 size = type_size(&vtop->type, &align);
2181 if (NODATA_WANTED)
2182 size = 0, align = 1;
2183 offset = section_add(p.sec, size, align);
2184 vpush_ref(&vtop->type, p.sec, offset, size);
2185 vswap();
2186 init_putv(&p, &vtop->type, offset);
2187 vtop->r |= VT_LVAL;
2189 #ifdef CONFIG_TCC_BCHECK
2190 if (vtop->r & VT_MUSTBOUND)
2191 gbound();
2192 #endif
2194 bt = vtop->type.t & VT_BTYPE;
2196 #ifdef TCC_TARGET_RISCV64
2197 /* XXX mega hack */
2198 if (bt == VT_LDOUBLE && rc == RC_FLOAT)
2199 rc = RC_INT;
2200 #endif
2201 rc2 = RC2_TYPE(bt, rc);
2203 /* need to reload if:
2204 - constant
2205 - lvalue (need to dereference pointer)
2206 - already a register, but not in the right class */
2207 r = vtop->r & VT_VALMASK;
2208 r_ok = !(vtop->r & VT_LVAL) && (r < VT_CONST) && (reg_classes[r] & rc);
2209 r2_ok = !rc2 || ((vtop->r2 < VT_CONST) && (reg_classes[vtop->r2] & rc2));
2211 if (!r_ok || !r2_ok) {
2212 if (!r_ok)
2213 r = get_reg(rc);
2214 if (rc2) {
2215 int load_type = (bt == VT_QFLOAT) ? VT_DOUBLE : VT_PTRDIFF_T;
2216 int original_type = vtop->type.t;
2218 /* two register type load :
2219 expand to two words temporarily */
2220 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2221 /* load constant */
2222 unsigned long long ll = vtop->c.i;
2223 vtop->c.i = ll; /* first word */
2224 load(r, vtop);
2225 vtop->r = r; /* save register value */
2226 vpushi(ll >> 32); /* second word */
2227 } else if (vtop->r & VT_LVAL) {
2228 /* We do not want to modifier the long long pointer here.
2229 So we save any other instances down the stack */
2230 save_reg_upstack(vtop->r, 1);
2231 /* load from memory */
2232 vtop->type.t = load_type;
2233 load(r, vtop);
2234 vdup();
2235 vtop[-1].r = r; /* save register value */
2236 /* increment pointer to get second word */
2237 vtop->type.t = VT_PTRDIFF_T;
2238 gaddrof();
2239 vpushs(PTR_SIZE);
2240 gen_op('+');
2241 vtop->r |= VT_LVAL;
2242 vtop->type.t = load_type;
2243 } else {
2244 /* move registers */
2245 if (!r_ok)
2246 load(r, vtop);
2247 if (r2_ok && vtop->r2 < VT_CONST)
2248 goto done;
2249 vdup();
2250 vtop[-1].r = r; /* save register value */
2251 vtop->r = vtop[-1].r2;
2253 /* Allocate second register. Here we rely on the fact that
2254 get_reg() tries first to free r2 of an SValue. */
2255 r2 = get_reg(rc2);
2256 load(r2, vtop);
2257 vpop();
2258 /* write second register */
2259 vtop->r2 = r2;
2260 done:
2261 vtop->type.t = original_type;
2262 } else {
2263 if (vtop->r == VT_CMP)
2264 vset_VT_JMP();
2265 /* one register type load */
2266 load(r, vtop);
2269 vtop->r = r;
2270 #ifdef TCC_TARGET_C67
2271 /* uses register pairs for doubles */
2272 if (bt == VT_DOUBLE)
2273 vtop->r2 = r+1;
2274 #endif
2276 return r;
2279 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2280 ST_FUNC void gv2(int rc1, int rc2)
2282 /* generate more generic register first. But VT_JMP or VT_CMP
2283 values must be generated first in all cases to avoid possible
2284 reload errors */
2285 if (vtop->r != VT_CMP && rc1 <= rc2) {
2286 vswap();
2287 gv(rc1);
2288 vswap();
2289 gv(rc2);
2290 /* test if reload is needed for first register */
2291 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2292 vswap();
2293 gv(rc1);
2294 vswap();
2296 } else {
2297 gv(rc2);
2298 vswap();
2299 gv(rc1);
2300 vswap();
2301 /* test if reload is needed for first register */
2302 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
2303 gv(rc2);
2308 #if PTR_SIZE == 4
2309 /* expand 64bit on stack in two ints */
2310 ST_FUNC void lexpand(void)
2312 int u, v;
2313 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
2314 v = vtop->r & (VT_VALMASK | VT_LVAL);
2315 if (v == VT_CONST) {
2316 vdup();
2317 vtop[0].c.i >>= 32;
2318 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
2319 vdup();
2320 vtop[0].c.i += 4;
2321 } else {
2322 gv(RC_INT);
2323 vdup();
2324 vtop[0].r = vtop[-1].r2;
2325 vtop[0].r2 = vtop[-1].r2 = VT_CONST;
2327 vtop[0].type.t = vtop[-1].type.t = VT_INT | u;
2329 #endif
2331 #if PTR_SIZE == 4
2332 /* build a long long from two ints */
2333 static void lbuild(int t)
2335 gv2(RC_INT, RC_INT);
2336 vtop[-1].r2 = vtop[0].r;
2337 vtop[-1].type.t = t;
2338 vpop();
2340 #endif
2342 /* convert stack entry to register and duplicate its value in another
2343 register */
2344 static void gv_dup(void)
2346 int t, rc, r;
2348 t = vtop->type.t;
2349 #if PTR_SIZE == 4
2350 if ((t & VT_BTYPE) == VT_LLONG) {
2351 if (t & VT_BITFIELD) {
2352 gv(RC_INT);
2353 t = vtop->type.t;
2355 lexpand();
2356 gv_dup();
2357 vswap();
2358 vrotb(3);
2359 gv_dup();
2360 vrotb(4);
2361 /* stack: H L L1 H1 */
2362 lbuild(t);
2363 vrotb(3);
2364 vrotb(3);
2365 vswap();
2366 lbuild(t);
2367 vswap();
2368 return;
2370 #endif
2371 /* duplicate value */
2372 rc = RC_TYPE(t);
2373 gv(rc);
2374 r = get_reg(rc);
2375 vdup();
2376 load(r, vtop);
2377 vtop->r = r;
2380 #if PTR_SIZE == 4
2381 /* generate CPU independent (unsigned) long long operations */
2382 static void gen_opl(int op)
2384 int t, a, b, op1, c, i;
2385 int func;
2386 unsigned short reg_iret = REG_IRET;
2387 unsigned short reg_lret = REG_IRE2;
2388 SValue tmp;
2390 switch(op) {
2391 case '/':
2392 case TOK_PDIV:
2393 func = TOK___divdi3;
2394 goto gen_func;
2395 case TOK_UDIV:
2396 func = TOK___udivdi3;
2397 goto gen_func;
2398 case '%':
2399 func = TOK___moddi3;
2400 goto gen_mod_func;
2401 case TOK_UMOD:
2402 func = TOK___umoddi3;
2403 gen_mod_func:
2404 #ifdef TCC_ARM_EABI
2405 reg_iret = TREG_R2;
2406 reg_lret = TREG_R3;
2407 #endif
2408 gen_func:
2409 /* call generic long long function */
2410 vpush_global_sym(&func_old_type, func);
2411 vrott(3);
2412 gfunc_call(2);
2413 vpushi(0);
2414 vtop->r = reg_iret;
2415 vtop->r2 = reg_lret;
2416 break;
2417 case '^':
2418 case '&':
2419 case '|':
2420 case '*':
2421 case '+':
2422 case '-':
2423 //pv("gen_opl A",0,2);
2424 t = vtop->type.t;
2425 vswap();
2426 lexpand();
2427 vrotb(3);
2428 lexpand();
2429 /* stack: L1 H1 L2 H2 */
2430 tmp = vtop[0];
2431 vtop[0] = vtop[-3];
2432 vtop[-3] = tmp;
2433 tmp = vtop[-2];
2434 vtop[-2] = vtop[-3];
2435 vtop[-3] = tmp;
2436 vswap();
2437 /* stack: H1 H2 L1 L2 */
2438 //pv("gen_opl B",0,4);
2439 if (op == '*') {
2440 vpushv(vtop - 1);
2441 vpushv(vtop - 1);
2442 gen_op(TOK_UMULL);
2443 lexpand();
2444 /* stack: H1 H2 L1 L2 ML MH */
2445 for(i=0;i<4;i++)
2446 vrotb(6);
2447 /* stack: ML MH H1 H2 L1 L2 */
2448 tmp = vtop[0];
2449 vtop[0] = vtop[-2];
2450 vtop[-2] = tmp;
2451 /* stack: ML MH H1 L2 H2 L1 */
2452 gen_op('*');
2453 vrotb(3);
2454 vrotb(3);
2455 gen_op('*');
2456 /* stack: ML MH M1 M2 */
2457 gen_op('+');
2458 gen_op('+');
2459 } else if (op == '+' || op == '-') {
2460 /* XXX: add non carry method too (for MIPS or alpha) */
2461 if (op == '+')
2462 op1 = TOK_ADDC1;
2463 else
2464 op1 = TOK_SUBC1;
2465 gen_op(op1);
2466 /* stack: H1 H2 (L1 op L2) */
2467 vrotb(3);
2468 vrotb(3);
2469 gen_op(op1 + 1); /* TOK_xxxC2 */
2470 } else {
2471 gen_op(op);
2472 /* stack: H1 H2 (L1 op L2) */
2473 vrotb(3);
2474 vrotb(3);
2475 /* stack: (L1 op L2) H1 H2 */
2476 gen_op(op);
2477 /* stack: (L1 op L2) (H1 op H2) */
2479 /* stack: L H */
2480 lbuild(t);
2481 break;
2482 case TOK_SAR:
2483 case TOK_SHR:
2484 case TOK_SHL:
2485 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
2486 t = vtop[-1].type.t;
2487 vswap();
2488 lexpand();
2489 vrotb(3);
2490 /* stack: L H shift */
2491 c = (int)vtop->c.i;
2492 /* constant: simpler */
2493 /* NOTE: all comments are for SHL. the other cases are
2494 done by swapping words */
2495 vpop();
2496 if (op != TOK_SHL)
2497 vswap();
2498 if (c >= 32) {
2499 /* stack: L H */
2500 vpop();
2501 if (c > 32) {
2502 vpushi(c - 32);
2503 gen_op(op);
2505 if (op != TOK_SAR) {
2506 vpushi(0);
2507 } else {
2508 gv_dup();
2509 vpushi(31);
2510 gen_op(TOK_SAR);
2512 vswap();
2513 } else {
2514 vswap();
2515 gv_dup();
2516 /* stack: H L L */
2517 vpushi(c);
2518 gen_op(op);
2519 vswap();
2520 vpushi(32 - c);
2521 if (op == TOK_SHL)
2522 gen_op(TOK_SHR);
2523 else
2524 gen_op(TOK_SHL);
2525 vrotb(3);
2526 /* stack: L L H */
2527 vpushi(c);
2528 if (op == TOK_SHL)
2529 gen_op(TOK_SHL);
2530 else
2531 gen_op(TOK_SHR);
2532 gen_op('|');
2534 if (op != TOK_SHL)
2535 vswap();
2536 lbuild(t);
2537 } else {
2538 /* XXX: should provide a faster fallback on x86 ? */
2539 switch(op) {
2540 case TOK_SAR:
2541 func = TOK___ashrdi3;
2542 goto gen_func;
2543 case TOK_SHR:
2544 func = TOK___lshrdi3;
2545 goto gen_func;
2546 case TOK_SHL:
2547 func = TOK___ashldi3;
2548 goto gen_func;
2551 break;
2552 default:
2553 /* compare operations */
2554 t = vtop->type.t;
2555 vswap();
2556 lexpand();
2557 vrotb(3);
2558 lexpand();
2559 /* stack: L1 H1 L2 H2 */
2560 tmp = vtop[-1];
2561 vtop[-1] = vtop[-2];
2562 vtop[-2] = tmp;
2563 /* stack: L1 L2 H1 H2 */
2564 save_regs(4);
2565 /* compare high */
2566 op1 = op;
2567 /* when values are equal, we need to compare low words. since
2568 the jump is inverted, we invert the test too. */
2569 if (op1 == TOK_LT)
2570 op1 = TOK_LE;
2571 else if (op1 == TOK_GT)
2572 op1 = TOK_GE;
2573 else if (op1 == TOK_ULT)
2574 op1 = TOK_ULE;
2575 else if (op1 == TOK_UGT)
2576 op1 = TOK_UGE;
2577 a = 0;
2578 b = 0;
2579 gen_op(op1);
2580 if (op == TOK_NE) {
2581 b = gvtst(0, 0);
2582 } else {
2583 a = gvtst(1, 0);
2584 if (op != TOK_EQ) {
2585 /* generate non equal test */
2586 vpushi(0);
2587 vset_VT_CMP(TOK_NE);
2588 b = gvtst(0, 0);
2591 /* compare low. Always unsigned */
2592 op1 = op;
2593 if (op1 == TOK_LT)
2594 op1 = TOK_ULT;
2595 else if (op1 == TOK_LE)
2596 op1 = TOK_ULE;
2597 else if (op1 == TOK_GT)
2598 op1 = TOK_UGT;
2599 else if (op1 == TOK_GE)
2600 op1 = TOK_UGE;
2601 gen_op(op1);
2602 #if 0//def TCC_TARGET_I386
2603 if (op == TOK_NE) { gsym(b); break; }
2604 if (op == TOK_EQ) { gsym(a); break; }
2605 #endif
2606 gvtst_set(1, a);
2607 gvtst_set(0, b);
2608 break;
2611 #endif
2613 static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
2615 uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
2616 return (a ^ b) >> 63 ? -x : x;
2619 static int gen_opic_lt(uint64_t a, uint64_t b)
2621 return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
2624 /* handle integer constant optimizations and various machine
2625 independent opt */
2626 static void gen_opic(int op)
2628 SValue *v1 = vtop - 1;
2629 SValue *v2 = vtop;
2630 int t1 = v1->type.t & VT_BTYPE;
2631 int t2 = v2->type.t & VT_BTYPE;
2632 int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2633 int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2634 uint64_t l1 = c1 ? v1->c.i : 0;
2635 uint64_t l2 = c2 ? v2->c.i : 0;
2636 int shm = (t1 == VT_LLONG) ? 63 : 31;
2638 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
2639 l1 = ((uint32_t)l1 |
2640 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
2641 if (t2 != VT_LLONG && (PTR_SIZE != 8 || t2 != VT_PTR))
2642 l2 = ((uint32_t)l2 |
2643 (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
2645 if (c1 && c2) {
2646 switch(op) {
2647 case '+': l1 += l2; break;
2648 case '-': l1 -= l2; break;
2649 case '&': l1 &= l2; break;
2650 case '^': l1 ^= l2; break;
2651 case '|': l1 |= l2; break;
2652 case '*': l1 *= l2; break;
2654 case TOK_PDIV:
2655 case '/':
2656 case '%':
2657 case TOK_UDIV:
2658 case TOK_UMOD:
2659 /* if division by zero, generate explicit division */
2660 if (l2 == 0) {
2661 if (const_wanted && !(nocode_wanted & unevalmask))
2662 tcc_error("division by zero in constant");
2663 goto general_case;
2665 switch(op) {
2666 default: l1 = gen_opic_sdiv(l1, l2); break;
2667 case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
2668 case TOK_UDIV: l1 = l1 / l2; break;
2669 case TOK_UMOD: l1 = l1 % l2; break;
2671 break;
2672 case TOK_SHL: l1 <<= (l2 & shm); break;
2673 case TOK_SHR: l1 >>= (l2 & shm); break;
2674 case TOK_SAR:
2675 l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
2676 break;
2677 /* tests */
2678 case TOK_ULT: l1 = l1 < l2; break;
2679 case TOK_UGE: l1 = l1 >= l2; break;
2680 case TOK_EQ: l1 = l1 == l2; break;
2681 case TOK_NE: l1 = l1 != l2; break;
2682 case TOK_ULE: l1 = l1 <= l2; break;
2683 case TOK_UGT: l1 = l1 > l2; break;
2684 case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
2685 case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
2686 case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
2687 case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
2688 /* logical */
2689 case TOK_LAND: l1 = l1 && l2; break;
2690 case TOK_LOR: l1 = l1 || l2; break;
2691 default:
2692 goto general_case;
2694 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
2695 l1 = ((uint32_t)l1 |
2696 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
2697 v1->c.i = l1;
2698 vtop--;
2699 } else {
2700 /* if commutative ops, put c2 as constant */
2701 if (c1 && (op == '+' || op == '&' || op == '^' ||
2702 op == '|' || op == '*' || op == TOK_EQ || op == TOK_NE)) {
2703 vswap();
2704 c2 = c1; //c = c1, c1 = c2, c2 = c;
2705 l2 = l1; //l = l1, l1 = l2, l2 = l;
2707 if (!const_wanted &&
2708 c1 && ((l1 == 0 &&
2709 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
2710 (l1 == -1 && op == TOK_SAR))) {
2711 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
2712 vtop--;
2713 } else if (!const_wanted &&
2714 c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
2715 (op == '|' &&
2716 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||
2717 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
2718 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
2719 if (l2 == 1)
2720 vtop->c.i = 0;
2721 vswap();
2722 vtop--;
2723 } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
2724 op == TOK_PDIV) &&
2725 l2 == 1) ||
2726 ((op == '+' || op == '-' || op == '|' || op == '^' ||
2727 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
2728 l2 == 0) ||
2729 (op == '&' &&
2730 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {
2731 /* filter out NOP operations like x*1, x-0, x&-1... */
2732 vtop--;
2733 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
2734 /* try to use shifts instead of muls or divs */
2735 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
2736 int n = -1;
2737 while (l2) {
2738 l2 >>= 1;
2739 n++;
2741 vtop->c.i = n;
2742 if (op == '*')
2743 op = TOK_SHL;
2744 else if (op == TOK_PDIV)
2745 op = TOK_SAR;
2746 else
2747 op = TOK_SHR;
2749 goto general_case;
2750 } else if (c2 && (op == '+' || op == '-') &&
2751 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
2752 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
2753 /* symbol + constant case */
2754 if (op == '-')
2755 l2 = -l2;
2756 l2 += vtop[-1].c.i;
2757 /* The backends can't always deal with addends to symbols
2758 larger than +-1<<31. Don't construct such. */
2759 if ((int)l2 != l2)
2760 goto general_case;
2761 vtop--;
2762 vtop->c.i = l2;
2763 } else {
2764 general_case:
2765 /* call low level op generator */
2766 if (t1 == VT_LLONG || t2 == VT_LLONG ||
2767 (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
2768 gen_opl(op);
2769 else
2770 gen_opi(op);
2775 /* generate a floating point operation with constant propagation */
2776 static void gen_opif(int op)
2778 int c1, c2;
2779 SValue *v1, *v2;
2780 #if defined _MSC_VER && defined __x86_64__
2781 /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
2782 volatile
2783 #endif
2784 long double f1, f2;
2786 v1 = vtop - 1;
2787 v2 = vtop;
2788 /* currently, we cannot do computations with forward symbols */
2789 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2790 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2791 if (c1 && c2) {
2792 if (v1->type.t == VT_FLOAT) {
2793 f1 = v1->c.f;
2794 f2 = v2->c.f;
2795 } else if (v1->type.t == VT_DOUBLE) {
2796 f1 = v1->c.d;
2797 f2 = v2->c.d;
2798 } else {
2799 f1 = v1->c.ld;
2800 f2 = v2->c.ld;
2803 /* NOTE: we only do constant propagation if finite number (not
2804 NaN or infinity) (ANSI spec) */
2805 if (!ieee_finite(f1) || !ieee_finite(f2))
2806 goto general_case;
2808 switch(op) {
2809 case '+': f1 += f2; break;
2810 case '-': f1 -= f2; break;
2811 case '*': f1 *= f2; break;
2812 case '/':
2813 if (f2 == 0.0) {
2814 /* If not in initializer we need to potentially generate
2815 FP exceptions at runtime, otherwise we want to fold. */
2816 if (!const_wanted)
2817 goto general_case;
2819 f1 /= f2;
2820 break;
2821 /* XXX: also handles tests ? */
2822 default:
2823 goto general_case;
2825 /* XXX: overflow test ? */
2826 if (v1->type.t == VT_FLOAT) {
2827 v1->c.f = f1;
2828 } else if (v1->type.t == VT_DOUBLE) {
2829 v1->c.d = f1;
2830 } else {
2831 v1->c.ld = f1;
2833 vtop--;
2834 } else {
2835 general_case:
2836 gen_opf(op);
2840 /* print a type. If 'varstr' is not NULL, then the variable is also
2841 printed in the type */
2842 /* XXX: union */
2843 /* XXX: add array and function pointers */
2844 static void type_to_str(char *buf, int buf_size,
2845 CType *type, const char *varstr)
2847 int bt, v, t;
2848 Sym *s, *sa;
2849 char buf1[256];
2850 const char *tstr;
2852 t = type->t;
2853 bt = t & VT_BTYPE;
2854 buf[0] = '\0';
2856 if (t & VT_EXTERN)
2857 pstrcat(buf, buf_size, "extern ");
2858 if (t & VT_STATIC)
2859 pstrcat(buf, buf_size, "static ");
2860 if (t & VT_TYPEDEF)
2861 pstrcat(buf, buf_size, "typedef ");
2862 if (t & VT_INLINE)
2863 pstrcat(buf, buf_size, "inline ");
2864 if (t & VT_VOLATILE)
2865 pstrcat(buf, buf_size, "volatile ");
2866 if (t & VT_CONSTANT)
2867 pstrcat(buf, buf_size, "const ");
2869 if (((t & VT_DEFSIGN) && bt == VT_BYTE)
2870 || ((t & VT_UNSIGNED)
2871 && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
2872 && !IS_ENUM(t)
2874 pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed ");
2876 buf_size -= strlen(buf);
2877 buf += strlen(buf);
2879 switch(bt) {
2880 case VT_VOID:
2881 tstr = "void";
2882 goto add_tstr;
2883 case VT_BOOL:
2884 tstr = "_Bool";
2885 goto add_tstr;
2886 case VT_BYTE:
2887 tstr = "char";
2888 goto add_tstr;
2889 case VT_SHORT:
2890 tstr = "short";
2891 goto add_tstr;
2892 case VT_INT:
2893 tstr = "int";
2894 goto maybe_long;
2895 case VT_LLONG:
2896 tstr = "long long";
2897 maybe_long:
2898 if (t & VT_LONG)
2899 tstr = "long";
2900 if (!IS_ENUM(t))
2901 goto add_tstr;
2902 tstr = "enum ";
2903 goto tstruct;
2904 case VT_FLOAT:
2905 tstr = "float";
2906 goto add_tstr;
2907 case VT_DOUBLE:
2908 tstr = "double";
2909 if (!(t & VT_LONG))
2910 goto add_tstr;
2911 case VT_LDOUBLE:
2912 tstr = "long double";
2913 add_tstr:
2914 pstrcat(buf, buf_size, tstr);
2915 break;
2916 case VT_STRUCT:
2917 tstr = "struct ";
2918 if (IS_UNION(t))
2919 tstr = "union ";
2920 tstruct:
2921 pstrcat(buf, buf_size, tstr);
2922 v = type->ref->v & ~SYM_STRUCT;
2923 if (v >= SYM_FIRST_ANOM)
2924 pstrcat(buf, buf_size, "<anonymous>");
2925 else
2926 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2927 break;
2928 case VT_FUNC:
2929 s = type->ref;
2930 buf1[0]=0;
2931 if (varstr && '*' == *varstr) {
2932 pstrcat(buf1, sizeof(buf1), "(");
2933 pstrcat(buf1, sizeof(buf1), varstr);
2934 pstrcat(buf1, sizeof(buf1), ")");
2936 pstrcat(buf1, buf_size, "(");
2937 sa = s->next;
2938 while (sa != NULL) {
2939 char buf2[256];
2940 type_to_str(buf2, sizeof(buf2), &sa->type, NULL);
2941 pstrcat(buf1, sizeof(buf1), buf2);
2942 sa = sa->next;
2943 if (sa)
2944 pstrcat(buf1, sizeof(buf1), ", ");
2946 if (s->f.func_type == FUNC_ELLIPSIS)
2947 pstrcat(buf1, sizeof(buf1), ", ...");
2948 pstrcat(buf1, sizeof(buf1), ")");
2949 type_to_str(buf, buf_size, &s->type, buf1);
2950 goto no_var;
2951 case VT_PTR:
2952 s = type->ref;
2953 if (t & VT_ARRAY) {
2954 if (varstr && '*' == *varstr)
2955 snprintf(buf1, sizeof(buf1), "(%s)[%d]", varstr, s->c);
2956 else
2957 snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c);
2958 type_to_str(buf, buf_size, &s->type, buf1);
2959 goto no_var;
2961 pstrcpy(buf1, sizeof(buf1), "*");
2962 if (t & VT_CONSTANT)
2963 pstrcat(buf1, buf_size, "const ");
2964 if (t & VT_VOLATILE)
2965 pstrcat(buf1, buf_size, "volatile ");
2966 if (varstr)
2967 pstrcat(buf1, sizeof(buf1), varstr);
2968 type_to_str(buf, buf_size, &s->type, buf1);
2969 goto no_var;
2971 if (varstr) {
2972 pstrcat(buf, buf_size, " ");
2973 pstrcat(buf, buf_size, varstr);
2975 no_var: ;
2978 static void type_incompatibility_error(CType* st, CType* dt, const char* fmt)
2980 char buf1[256], buf2[256];
2981 type_to_str(buf1, sizeof(buf1), st, NULL);
2982 type_to_str(buf2, sizeof(buf2), dt, NULL);
2983 tcc_error(fmt, buf1, buf2);
2986 static void type_incompatibility_warning(CType* st, CType* dt, const char* fmt)
2988 char buf1[256], buf2[256];
2989 type_to_str(buf1, sizeof(buf1), st, NULL);
2990 type_to_str(buf2, sizeof(buf2), dt, NULL);
2991 tcc_warning(fmt, buf1, buf2);
2994 static int pointed_size(CType *type)
2996 int align;
2997 return type_size(pointed_type(type), &align);
3000 static void vla_runtime_pointed_size(CType *type)
3002 int align;
3003 vla_runtime_type_size(pointed_type(type), &align);
3006 static inline int is_null_pointer(SValue *p)
3008 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
3009 return 0;
3010 return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
3011 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
3012 ((p->type.t & VT_BTYPE) == VT_PTR &&
3013 (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0) &&
3014 ((pointed_type(&p->type)->t & VT_BTYPE) == VT_VOID) &&
3015 0 == (pointed_type(&p->type)->t & (VT_CONSTANT | VT_VOLATILE))
3019 /* compare function types. OLD functions match any new functions */
3020 static int is_compatible_func(CType *type1, CType *type2)
3022 Sym *s1, *s2;
3024 s1 = type1->ref;
3025 s2 = type2->ref;
3026 if (s1->f.func_call != s2->f.func_call)
3027 return 0;
3028 if (s1->f.func_type != s2->f.func_type
3029 && s1->f.func_type != FUNC_OLD
3030 && s2->f.func_type != FUNC_OLD)
3031 return 0;
3032 /* we should check the function return type for FUNC_OLD too
3033 but that causes problems with the internally used support
3034 functions such as TOK_memmove */
3035 if (s1->f.func_type == FUNC_OLD && !s1->next)
3036 return 1;
3037 if (s2->f.func_type == FUNC_OLD && !s2->next)
3038 return 1;
3039 for (;;) {
3040 if (!is_compatible_unqualified_types(&s1->type, &s2->type))
3041 return 0;
3042 s1 = s1->next;
3043 s2 = s2->next;
3044 if (!s1)
3045 return !s2;
3046 if (!s2)
3047 return 0;
3051 /* return true if type1 and type2 are the same. If unqualified is
3052 true, qualifiers on the types are ignored.
3054 static int compare_types(CType *type1, CType *type2, int unqualified)
3056 int bt1, t1, t2;
3058 t1 = type1->t & VT_TYPE;
3059 t2 = type2->t & VT_TYPE;
3060 if (unqualified) {
3061 /* strip qualifiers before comparing */
3062 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
3063 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
3066 /* Default Vs explicit signedness only matters for char */
3067 if ((t1 & VT_BTYPE) != VT_BYTE) {
3068 t1 &= ~VT_DEFSIGN;
3069 t2 &= ~VT_DEFSIGN;
3071 /* XXX: bitfields ? */
3072 if (t1 != t2)
3073 return 0;
3075 if ((t1 & VT_ARRAY)
3076 && !(type1->ref->c < 0
3077 || type2->ref->c < 0
3078 || type1->ref->c == type2->ref->c))
3079 return 0;
3081 /* test more complicated cases */
3082 bt1 = t1 & VT_BTYPE;
3083 if (bt1 == VT_PTR) {
3084 type1 = pointed_type(type1);
3085 type2 = pointed_type(type2);
3086 return is_compatible_types(type1, type2);
3087 } else if (bt1 == VT_STRUCT) {
3088 return (type1->ref == type2->ref);
3089 } else if (bt1 == VT_FUNC) {
3090 return is_compatible_func(type1, type2);
3091 } else if (IS_ENUM(type1->t) && IS_ENUM(type2->t)) {
3092 /* If both are enums then they must be the same, if only one is then
3093 t1 and t2 must be equal, which was checked above already. */
3094 return type1->ref == type2->ref;
3095 } else {
3096 return 1;
3100 /* Check if OP1 and OP2 can be "combined" with operation OP, the combined
3101 type is stored in DEST if non-null (except for pointer plus/minus) . */
3102 static int combine_types(CType *dest, SValue *op1, SValue *op2, int op)
3104 CType *type1 = &op1->type, *type2 = &op2->type, type;
3105 int t1 = type1->t, t2 = type2->t, bt1 = t1 & VT_BTYPE, bt2 = t2 & VT_BTYPE;
3106 int ret = 1;
3108 type.t = VT_VOID;
3109 type.ref = NULL;
3111 if (bt1 == VT_VOID || bt2 == VT_VOID) {
3112 ret = op == '?' ? 1 : 0;
3113 /* NOTE: as an extension, we accept void on only one side */
3114 type.t = VT_VOID;
3115 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
3116 if (op == '+') ; /* Handled in caller */
3117 /* http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6 */
3118 /* If one is a null ptr constant the result type is the other. */
3119 else if (is_null_pointer (op2)) type = *type1;
3120 else if (is_null_pointer (op1)) type = *type2;
3121 else if (bt1 != bt2) {
3122 /* accept comparison or cond-expr between pointer and integer
3123 with a warning */
3124 if ((op == '?' || TOK_ISCOND(op))
3125 && (is_integer_btype(bt1) || is_integer_btype(bt2)))
3126 tcc_warning("pointer/integer mismatch in %s",
3127 op == '?' ? "conditional expression" : "comparison");
3128 else if (op != '-' || !is_integer_btype(bt2))
3129 ret = 0;
3130 type = *(bt1 == VT_PTR ? type1 : type2);
3131 } else {
3132 CType *pt1 = pointed_type(type1);
3133 CType *pt2 = pointed_type(type2);
3134 int pbt1 = pt1->t & VT_BTYPE;
3135 int pbt2 = pt2->t & VT_BTYPE;
3136 int newquals, copied = 0;
3137 if (pbt1 != VT_VOID && pbt2 != VT_VOID
3138 && !compare_types(pt1, pt2, 1/*unqualif*/)) {
3139 if (op != '?' && !TOK_ISCOND(op))
3140 ret = 0;
3141 else
3142 type_incompatibility_warning(type1, type2,
3143 op == '?'
3144 ? "pointer type mismatch in conditional expression ('%s' and '%s')"
3145 : "pointer type mismatch in comparison('%s' and '%s')");
3147 if (op == '?') {
3148 /* pointers to void get preferred, otherwise the
3149 pointed to types minus qualifs should be compatible */
3150 type = *((pbt1 == VT_VOID) ? type1 : type2);
3151 /* combine qualifs */
3152 newquals = ((pt1->t | pt2->t) & (VT_CONSTANT | VT_VOLATILE));
3153 if ((~pointed_type(&type)->t & (VT_CONSTANT | VT_VOLATILE))
3154 & newquals)
3156 /* copy the pointer target symbol */
3157 type.ref = sym_push(SYM_FIELD, &type.ref->type,
3158 0, type.ref->c);
3159 copied = 1;
3160 pointed_type(&type)->t |= newquals;
3162 /* pointers to incomplete arrays get converted to
3163 pointers to completed ones if possible */
3164 if (pt1->t & VT_ARRAY
3165 && pt2->t & VT_ARRAY
3166 && pointed_type(&type)->ref->c < 0
3167 && (pt1->ref->c > 0 || pt2->ref->c > 0))
3169 if (!copied)
3170 type.ref = sym_push(SYM_FIELD, &type.ref->type,
3171 0, type.ref->c);
3172 pointed_type(&type)->ref =
3173 sym_push(SYM_FIELD, &pointed_type(&type)->ref->type,
3174 0, pointed_type(&type)->ref->c);
3175 pointed_type(&type)->ref->c =
3176 0 < pt1->ref->c ? pt1->ref->c : pt2->ref->c;
3180 if (TOK_ISCOND(op))
3181 type.t = VT_SIZE_T;
3182 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
3183 if (op != '?' || !compare_types(type1, type2, 1))
3184 ret = 0;
3185 type = *type1;
3186 } else if (is_float(bt1) || is_float(bt2)) {
3187 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3188 type.t = VT_LDOUBLE;
3189 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3190 type.t = VT_DOUBLE;
3191 } else {
3192 type.t = VT_FLOAT;
3194 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3195 /* cast to biggest op */
3196 type.t = VT_LLONG | VT_LONG;
3197 if (bt1 == VT_LLONG)
3198 type.t &= t1;
3199 if (bt2 == VT_LLONG)
3200 type.t &= t2;
3201 /* convert to unsigned if it does not fit in a long long */
3202 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
3203 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
3204 type.t |= VT_UNSIGNED;
3205 } else {
3206 /* integer operations */
3207 type.t = VT_INT | (VT_LONG & (t1 | t2));
3208 /* convert to unsigned if it does not fit in an integer */
3209 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
3210 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
3211 type.t |= VT_UNSIGNED;
3213 if (dest)
3214 *dest = type;
3215 return ret;
3218 /* generic gen_op: handles types problems */
3219 ST_FUNC void gen_op(int op)
3221 int u, t1, t2, bt1, bt2, t;
3222 CType type1, combtype;
3224 redo:
3225 t1 = vtop[-1].type.t;
3226 t2 = vtop[0].type.t;
3227 bt1 = t1 & VT_BTYPE;
3228 bt2 = t2 & VT_BTYPE;
3230 if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
3231 if (bt2 == VT_FUNC) {
3232 mk_pointer(&vtop->type);
3233 gaddrof();
3235 if (bt1 == VT_FUNC) {
3236 vswap();
3237 mk_pointer(&vtop->type);
3238 gaddrof();
3239 vswap();
3241 goto redo;
3242 } else if (!combine_types(&combtype, vtop - 1, vtop, op)) {
3243 tcc_error_noabort("invalid operand types for binary operation");
3244 vpop();
3245 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
3246 /* at least one operand is a pointer */
3247 /* relational op: must be both pointers */
3248 if (TOK_ISCOND(op))
3249 goto std_op;
3250 /* if both pointers, then it must be the '-' op */
3251 if (bt1 == VT_PTR && bt2 == VT_PTR) {
3252 if (op != '-')
3253 tcc_error("cannot use pointers here");
3254 if (vtop[-1].type.t & VT_VLA) {
3255 vla_runtime_pointed_size(&vtop[-1].type);
3256 } else {
3257 vpushi(pointed_size(&vtop[-1].type));
3259 vrott(3);
3260 gen_opic(op);
3261 vtop->type.t = VT_PTRDIFF_T;
3262 vswap();
3263 gen_op(TOK_PDIV);
3264 } else {
3265 /* exactly one pointer : must be '+' or '-'. */
3266 if (op != '-' && op != '+')
3267 tcc_error("cannot use pointers here");
3268 /* Put pointer as first operand */
3269 if (bt2 == VT_PTR) {
3270 vswap();
3271 t = t1, t1 = t2, t2 = t;
3273 #if PTR_SIZE == 4
3274 if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG)
3275 /* XXX: truncate here because gen_opl can't handle ptr + long long */
3276 gen_cast_s(VT_INT);
3277 #endif
3278 type1 = vtop[-1].type;
3279 if (vtop[-1].type.t & VT_VLA)
3280 vla_runtime_pointed_size(&vtop[-1].type);
3281 else {
3282 u = pointed_size(&vtop[-1].type);
3283 if (u < 0)
3284 tcc_error("unknown array element size");
3285 #if PTR_SIZE == 8
3286 vpushll(u);
3287 #else
3288 /* XXX: cast to int ? (long long case) */
3289 vpushi(u);
3290 #endif
3292 gen_op('*');
3293 #ifdef CONFIG_TCC_BCHECK
3294 if (tcc_state->do_bounds_check && !const_wanted) {
3295 /* if bounded pointers, we generate a special code to
3296 test bounds */
3297 if (op == '-') {
3298 vpushi(0);
3299 vswap();
3300 gen_op('-');
3302 gen_bounded_ptr_add();
3303 } else
3304 #endif
3306 gen_opic(op);
3308 type1.t &= ~VT_ARRAY;
3309 /* put again type if gen_opic() swaped operands */
3310 vtop->type = type1;
3312 } else {
3313 /* floats can only be used for a few operations */
3314 if (is_float(combtype.t)
3315 && op != '+' && op != '-' && op != '*' && op != '/'
3316 && !TOK_ISCOND(op))
3317 tcc_error("invalid operands for binary operation");
3318 else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
3319 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
3320 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))
3321 t |= VT_UNSIGNED;
3322 t |= (VT_LONG & t1);
3323 combtype.t = t;
3325 std_op:
3326 t = t2 = combtype.t;
3327 /* XXX: currently, some unsigned operations are explicit, so
3328 we modify them here */
3329 if (t & VT_UNSIGNED) {
3330 if (op == TOK_SAR)
3331 op = TOK_SHR;
3332 else if (op == '/')
3333 op = TOK_UDIV;
3334 else if (op == '%')
3335 op = TOK_UMOD;
3336 else if (op == TOK_LT)
3337 op = TOK_ULT;
3338 else if (op == TOK_GT)
3339 op = TOK_UGT;
3340 else if (op == TOK_LE)
3341 op = TOK_ULE;
3342 else if (op == TOK_GE)
3343 op = TOK_UGE;
3345 vswap();
3346 gen_cast_s(t);
3347 vswap();
3348 /* special case for shifts and long long: we keep the shift as
3349 an integer */
3350 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
3351 t2 = VT_INT;
3352 gen_cast_s(t2);
3353 if (is_float(t))
3354 gen_opif(op);
3355 else
3356 gen_opic(op);
3357 if (TOK_ISCOND(op)) {
3358 /* relational op: the result is an int */
3359 vtop->type.t = VT_INT;
3360 } else {
3361 vtop->type.t = t;
3364 // Make sure that we have converted to an rvalue:
3365 if (vtop->r & VT_LVAL)
3366 gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
3369 #if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 || defined TCC_TARGET_ARM
3370 #define gen_cvt_itof1 gen_cvt_itof
3371 #else
3372 /* generic itof for unsigned long long case */
3373 static void gen_cvt_itof1(int t)
3375 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
3376 (VT_LLONG | VT_UNSIGNED)) {
3378 if (t == VT_FLOAT)
3379 vpush_global_sym(&func_old_type, TOK___floatundisf);
3380 #if LDOUBLE_SIZE != 8
3381 else if (t == VT_LDOUBLE)
3382 vpush_global_sym(&func_old_type, TOK___floatundixf);
3383 #endif
3384 else
3385 vpush_global_sym(&func_old_type, TOK___floatundidf);
3386 vrott(2);
3387 gfunc_call(1);
3388 vpushi(0);
3389 PUT_R_RET(vtop, t);
3390 } else {
3391 gen_cvt_itof(t);
3394 #endif
3396 #if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
3397 #define gen_cvt_ftoi1 gen_cvt_ftoi
3398 #else
3399 /* generic ftoi for unsigned long long case */
3400 static void gen_cvt_ftoi1(int t)
3402 int st;
3403 if (t == (VT_LLONG | VT_UNSIGNED)) {
3404 /* not handled natively */
3405 st = vtop->type.t & VT_BTYPE;
3406 if (st == VT_FLOAT)
3407 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
3408 #if LDOUBLE_SIZE != 8
3409 else if (st == VT_LDOUBLE)
3410 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
3411 #endif
3412 else
3413 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
3414 vrott(2);
3415 gfunc_call(1);
3416 vpushi(0);
3417 PUT_R_RET(vtop, t);
3418 } else {
3419 gen_cvt_ftoi(t);
3422 #endif
3424 /* special delayed cast for char/short */
3425 static void force_charshort_cast(void)
3427 int sbt = BFGET(vtop->r, VT_MUSTCAST) == 2 ? VT_LLONG : VT_INT;
3428 int dbt = vtop->type.t;
3429 vtop->r &= ~VT_MUSTCAST;
3430 vtop->type.t = sbt;
3431 gen_cast_s(dbt == VT_BOOL ? VT_BYTE|VT_UNSIGNED : dbt);
3432 vtop->type.t = dbt;
3435 static void gen_cast_s(int t)
3437 CType type;
3438 type.t = t;
3439 type.ref = NULL;
3440 gen_cast(&type);
3443 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
3444 static void gen_cast(CType *type)
3446 int sbt, dbt, sf, df, c;
3447 int dbt_bt, sbt_bt, ds, ss, bits, trunc;
3449 /* special delayed cast for char/short */
3450 if (vtop->r & VT_MUSTCAST)
3451 force_charshort_cast();
3453 /* bitfields first get cast to ints */
3454 if (vtop->type.t & VT_BITFIELD)
3455 gv(RC_INT);
3457 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
3458 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3459 if (sbt == VT_FUNC)
3460 sbt = VT_PTR;
3462 again:
3463 if (sbt != dbt) {
3464 sf = is_float(sbt);
3465 df = is_float(dbt);
3466 dbt_bt = dbt & VT_BTYPE;
3467 sbt_bt = sbt & VT_BTYPE;
3469 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3470 #if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
3471 c &= (dbt != VT_LDOUBLE) | !!nocode_wanted;
3472 #endif
3473 if (c) {
3474 /* constant case: we can do it now */
3475 /* XXX: in ISOC, cannot do it if error in convert */
3476 if (sbt == VT_FLOAT)
3477 vtop->c.ld = vtop->c.f;
3478 else if (sbt == VT_DOUBLE)
3479 vtop->c.ld = vtop->c.d;
3481 if (df) {
3482 if (sbt_bt == VT_LLONG) {
3483 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
3484 vtop->c.ld = vtop->c.i;
3485 else
3486 vtop->c.ld = -(long double)-vtop->c.i;
3487 } else if(!sf) {
3488 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
3489 vtop->c.ld = (uint32_t)vtop->c.i;
3490 else
3491 vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
3494 if (dbt == VT_FLOAT)
3495 vtop->c.f = (float)vtop->c.ld;
3496 else if (dbt == VT_DOUBLE)
3497 vtop->c.d = (double)vtop->c.ld;
3498 } else if (sf && dbt == VT_BOOL) {
3499 vtop->c.i = (vtop->c.ld != 0);
3500 } else {
3501 if(sf)
3502 vtop->c.i = vtop->c.ld;
3503 else if (sbt_bt == VT_LLONG || (PTR_SIZE == 8 && sbt == VT_PTR))
3505 else if (sbt & VT_UNSIGNED)
3506 vtop->c.i = (uint32_t)vtop->c.i;
3507 else
3508 vtop->c.i = ((uint32_t)vtop->c.i | -(vtop->c.i & 0x80000000));
3510 if (dbt_bt == VT_LLONG || (PTR_SIZE == 8 && dbt == VT_PTR))
3512 else if (dbt == VT_BOOL)
3513 vtop->c.i = (vtop->c.i != 0);
3514 else {
3515 uint32_t m = dbt_bt == VT_BYTE ? 0xff :
3516 dbt_bt == VT_SHORT ? 0xffff :
3517 0xffffffff;
3518 vtop->c.i &= m;
3519 if (!(dbt & VT_UNSIGNED))
3520 vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
3523 goto done;
3525 } else if (dbt == VT_BOOL
3526 && (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM))
3527 == (VT_CONST | VT_SYM)) {
3528 /* addresses are considered non-zero (see tcctest.c:sinit23) */
3529 vtop->r = VT_CONST;
3530 vtop->c.i = 1;
3531 goto done;
3534 /* cannot generate code for global or static initializers */
3535 if (STATIC_DATA_WANTED)
3536 goto done;
3538 /* non constant case: generate code */
3539 if (dbt == VT_BOOL) {
3540 gen_test_zero(TOK_NE);
3541 goto done;
3544 if (sf || df) {
3545 if (sf && df) {
3546 /* convert from fp to fp */
3547 gen_cvt_ftof(dbt);
3548 } else if (df) {
3549 /* convert int to fp */
3550 gen_cvt_itof1(dbt);
3551 } else {
3552 /* convert fp to int */
3553 sbt = dbt;
3554 if (dbt_bt != VT_LLONG && dbt_bt != VT_INT)
3555 sbt = VT_INT;
3556 gen_cvt_ftoi1(sbt);
3557 goto again; /* may need char/short cast */
3559 goto done;
3562 ds = btype_size(dbt_bt);
3563 ss = btype_size(sbt_bt);
3564 if (ds == 0 || ss == 0) {
3565 if (dbt_bt == VT_VOID)
3566 goto done;
3567 cast_error(&vtop->type, type);
3569 if (IS_ENUM(type->t) && type->ref->c < 0)
3570 tcc_error("cast to incomplete type");
3572 /* same size and no sign conversion needed */
3573 if (ds == ss && ds >= 4)
3574 goto done;
3575 if (dbt_bt == VT_PTR || sbt_bt == VT_PTR) {
3576 tcc_warning("cast between pointer and integer of different size");
3577 if (sbt_bt == VT_PTR) {
3578 /* put integer type to allow logical operations below */
3579 vtop->type.t = (PTR_SIZE == 8 ? VT_LLONG : VT_INT);
3583 /* processor allows { int a = 0, b = *(char*)&a; }
3584 That means that if we cast to less width, we can just
3585 change the type and read it still later. */
3586 #define ALLOW_SUBTYPE_ACCESS 1
3588 if (ALLOW_SUBTYPE_ACCESS && (vtop->r & VT_LVAL)) {
3589 /* value still in memory */
3590 if (ds <= ss)
3591 goto done;
3592 /* ss <= 4 here */
3593 if (ds <= 4 && !(dbt == (VT_SHORT | VT_UNSIGNED) && sbt == VT_BYTE)) {
3594 gv(RC_INT);
3595 goto done; /* no 64bit envolved */
3598 gv(RC_INT);
3600 trunc = 0;
3601 #if PTR_SIZE == 4
3602 if (ds == 8) {
3603 /* generate high word */
3604 if (sbt & VT_UNSIGNED) {
3605 vpushi(0);
3606 gv(RC_INT);
3607 } else {
3608 gv_dup();
3609 vpushi(31);
3610 gen_op(TOK_SAR);
3612 lbuild(dbt);
3613 } else if (ss == 8) {
3614 /* from long long: just take low order word */
3615 lexpand();
3616 vpop();
3618 ss = 4;
3620 #elif PTR_SIZE == 8
3621 if (ds == 8) {
3622 /* need to convert from 32bit to 64bit */
3623 if (sbt & VT_UNSIGNED) {
3624 #if defined(TCC_TARGET_RISCV64)
3625 /* RISC-V keeps 32bit vals in registers sign-extended.
3626 So here we need a zero-extension. */
3627 trunc = 32;
3628 #else
3629 goto done;
3630 #endif
3631 } else {
3632 gen_cvt_sxtw();
3633 goto done;
3635 ss = ds, ds = 4, dbt = sbt;
3636 } else if (ss == 8) {
3637 /* RISC-V keeps 32bit vals in registers sign-extended.
3638 So here we need a sign-extension for signed types and
3639 zero-extension. for unsigned types. */
3640 #if !defined(TCC_TARGET_RISCV64)
3641 trunc = 32; /* zero upper 32 bits for non RISC-V targets */
3642 #endif
3643 } else {
3644 ss = 4;
3646 #endif
3648 if (ds >= ss)
3649 goto done;
3650 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM64
3651 if (ss == 4) {
3652 gen_cvt_csti(dbt);
3653 goto done;
3655 #endif
3656 bits = (ss - ds) * 8;
3657 /* for unsigned, gen_op will convert SAR to SHR */
3658 vtop->type.t = (ss == 8 ? VT_LLONG : VT_INT) | (dbt & VT_UNSIGNED);
3659 vpushi(bits);
3660 gen_op(TOK_SHL);
3661 vpushi(bits - trunc);
3662 gen_op(TOK_SAR);
3663 vpushi(trunc);
3664 gen_op(TOK_SHR);
3666 done:
3667 vtop->type = *type;
3668 vtop->type.t &= ~ ( VT_CONSTANT | VT_VOLATILE | VT_ARRAY );
3671 /* return type size as known at compile time. Put alignment at 'a' */
3672 ST_FUNC int type_size(CType *type, int *a)
3674 Sym *s;
3675 int bt;
3677 bt = type->t & VT_BTYPE;
3678 if (bt == VT_STRUCT) {
3679 /* struct/union */
3680 s = type->ref;
3681 *a = s->r;
3682 return s->c;
3683 } else if (bt == VT_PTR) {
3684 if (type->t & VT_ARRAY) {
3685 int ts;
3687 s = type->ref;
3688 ts = type_size(&s->type, a);
3690 if (ts < 0 && s->c < 0)
3691 ts = -ts;
3693 return ts * s->c;
3694 } else {
3695 *a = PTR_SIZE;
3696 return PTR_SIZE;
3698 } else if (IS_ENUM(type->t) && type->ref->c < 0) {
3699 return -1; /* incomplete enum */
3700 } else if (bt == VT_LDOUBLE) {
3701 *a = LDOUBLE_ALIGN;
3702 return LDOUBLE_SIZE;
3703 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
3704 #ifdef TCC_TARGET_I386
3705 #ifdef TCC_TARGET_PE
3706 *a = 8;
3707 #else
3708 *a = 4;
3709 #endif
3710 #elif defined(TCC_TARGET_ARM)
3711 #ifdef TCC_ARM_EABI
3712 *a = 8;
3713 #else
3714 *a = 4;
3715 #endif
3716 #else
3717 *a = 8;
3718 #endif
3719 return 8;
3720 } else if (bt == VT_INT || bt == VT_FLOAT) {
3721 *a = 4;
3722 return 4;
3723 } else if (bt == VT_SHORT) {
3724 *a = 2;
3725 return 2;
3726 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
3727 *a = 8;
3728 return 16;
3729 } else {
3730 /* char, void, function, _Bool */
3731 *a = 1;
3732 return 1;
3736 /* push type size as known at runtime time on top of value stack. Put
3737 alignment at 'a' */
3738 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
3740 if (type->t & VT_VLA) {
3741 type_size(&type->ref->type, a);
3742 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
3743 } else {
3744 vpushi(type_size(type, a));
3748 /* return the pointed type of t */
3749 static inline CType *pointed_type(CType *type)
3751 return &type->ref->type;
3754 /* modify type so that its it is a pointer to type. */
3755 ST_FUNC void mk_pointer(CType *type)
3757 Sym *s;
3758 s = sym_push(SYM_FIELD, type, 0, -1);
3759 type->t = VT_PTR | (type->t & VT_STORAGE);
3760 type->ref = s;
3763 /* return true if type1 and type2 are exactly the same (including
3764 qualifiers).
3766 static int is_compatible_types(CType *type1, CType *type2)
3768 return compare_types(type1,type2,0);
3771 /* return true if type1 and type2 are the same (ignoring qualifiers).
3773 static int is_compatible_unqualified_types(CType *type1, CType *type2)
3775 return compare_types(type1,type2,1);
3778 static void cast_error(CType *st, CType *dt)
3780 type_incompatibility_error(st, dt, "cannot convert '%s' to '%s'");
3783 /* verify type compatibility to store vtop in 'dt' type */
3784 static void verify_assign_cast(CType *dt)
3786 CType *st, *type1, *type2;
3787 int dbt, sbt, qualwarn, lvl;
3789 st = &vtop->type; /* source type */
3790 dbt = dt->t & VT_BTYPE;
3791 sbt = st->t & VT_BTYPE;
3792 if (dt->t & VT_CONSTANT)
3793 tcc_warning("assignment of read-only location");
3794 switch(dbt) {
3795 case VT_VOID:
3796 if (sbt != dbt)
3797 tcc_error("assignment to void expression");
3798 break;
3799 case VT_PTR:
3800 /* special cases for pointers */
3801 /* '0' can also be a pointer */
3802 if (is_null_pointer(vtop))
3803 break;
3804 /* accept implicit pointer to integer cast with warning */
3805 if (is_integer_btype(sbt)) {
3806 tcc_warning("assignment makes pointer from integer without a cast");
3807 break;
3809 type1 = pointed_type(dt);
3810 if (sbt == VT_PTR)
3811 type2 = pointed_type(st);
3812 else if (sbt == VT_FUNC)
3813 type2 = st; /* a function is implicitly a function pointer */
3814 else
3815 goto error;
3816 if (is_compatible_types(type1, type2))
3817 break;
3818 for (qualwarn = lvl = 0;; ++lvl) {
3819 if (((type2->t & VT_CONSTANT) && !(type1->t & VT_CONSTANT)) ||
3820 ((type2->t & VT_VOLATILE) && !(type1->t & VT_VOLATILE)))
3821 qualwarn = 1;
3822 dbt = type1->t & (VT_BTYPE|VT_LONG);
3823 sbt = type2->t & (VT_BTYPE|VT_LONG);
3824 if (dbt != VT_PTR || sbt != VT_PTR)
3825 break;
3826 type1 = pointed_type(type1);
3827 type2 = pointed_type(type2);
3829 if (!is_compatible_unqualified_types(type1, type2)) {
3830 if ((dbt == VT_VOID || sbt == VT_VOID) && lvl == 0) {
3831 /* void * can match anything */
3832 } else if (dbt == sbt
3833 && is_integer_btype(sbt & VT_BTYPE)
3834 && IS_ENUM(type1->t) + IS_ENUM(type2->t)
3835 + !!((type1->t ^ type2->t) & VT_UNSIGNED) < 2) {
3836 /* Like GCC don't warn by default for merely changes
3837 in pointer target signedness. Do warn for different
3838 base types, though, in particular for unsigned enums
3839 and signed int targets. */
3840 } else {
3841 tcc_warning("assignment from incompatible pointer type");
3842 break;
3845 if (qualwarn)
3846 tcc_warning("assignment discards qualifiers from pointer target type");
3847 break;
3848 case VT_BYTE:
3849 case VT_SHORT:
3850 case VT_INT:
3851 case VT_LLONG:
3852 if (sbt == VT_PTR || sbt == VT_FUNC) {
3853 tcc_warning("assignment makes integer from pointer without a cast");
3854 } else if (sbt == VT_STRUCT) {
3855 goto case_VT_STRUCT;
3857 /* XXX: more tests */
3858 break;
3859 case VT_STRUCT:
3860 case_VT_STRUCT:
3861 if (!is_compatible_unqualified_types(dt, st)) {
3862 error:
3863 cast_error(st, dt);
3865 break;
3869 static void gen_assign_cast(CType *dt)
3871 verify_assign_cast(dt);
3872 gen_cast(dt);
3875 /* store vtop in lvalue pushed on stack */
3876 ST_FUNC void vstore(void)
3878 int sbt, dbt, ft, r, size, align, bit_size, bit_pos, delayed_cast;
3880 ft = vtop[-1].type.t;
3881 sbt = vtop->type.t & VT_BTYPE;
3882 dbt = ft & VT_BTYPE;
3884 verify_assign_cast(&vtop[-1].type);
3886 if (sbt == VT_STRUCT) {
3887 /* if structure, only generate pointer */
3888 /* structure assignment : generate memcpy */
3889 /* XXX: optimize if small size */
3890 size = type_size(&vtop->type, &align);
3892 /* destination */
3893 vswap();
3894 #ifdef CONFIG_TCC_BCHECK
3895 if (vtop->r & VT_MUSTBOUND)
3896 gbound(); /* check would be wrong after gaddrof() */
3897 #endif
3898 vtop->type.t = VT_PTR;
3899 gaddrof();
3901 /* address of memcpy() */
3902 #ifdef TCC_ARM_EABI
3903 if(!(align & 7))
3904 vpush_global_sym(&func_old_type, TOK_memmove8);
3905 else if(!(align & 3))
3906 vpush_global_sym(&func_old_type, TOK_memmove4);
3907 else
3908 #endif
3909 /* Use memmove, rather than memcpy, as dest and src may be same: */
3910 vpush_global_sym(&func_old_type, TOK_memmove);
3912 vswap();
3913 /* source */
3914 vpushv(vtop - 2);
3915 #ifdef CONFIG_TCC_BCHECK
3916 if (vtop->r & VT_MUSTBOUND)
3917 gbound();
3918 #endif
3919 vtop->type.t = VT_PTR;
3920 gaddrof();
3921 /* type size */
3922 vpushi(size);
3923 gfunc_call(3);
3924 /* leave source on stack */
3926 } else if (ft & VT_BITFIELD) {
3927 /* bitfield store handling */
3929 /* save lvalue as expression result (example: s.b = s.a = n;) */
3930 vdup(), vtop[-1] = vtop[-2];
3932 bit_pos = BIT_POS(ft);
3933 bit_size = BIT_SIZE(ft);
3934 /* remove bit field info to avoid loops */
3935 vtop[-1].type.t = ft & ~VT_STRUCT_MASK;
3937 if (dbt == VT_BOOL) {
3938 gen_cast(&vtop[-1].type);
3939 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
3941 r = adjust_bf(vtop - 1, bit_pos, bit_size);
3942 if (dbt != VT_BOOL) {
3943 gen_cast(&vtop[-1].type);
3944 dbt = vtop[-1].type.t & VT_BTYPE;
3946 if (r == VT_STRUCT) {
3947 store_packed_bf(bit_pos, bit_size);
3948 } else {
3949 unsigned long long mask = (1ULL << bit_size) - 1;
3950 if (dbt != VT_BOOL) {
3951 /* mask source */
3952 if (dbt == VT_LLONG)
3953 vpushll(mask);
3954 else
3955 vpushi((unsigned)mask);
3956 gen_op('&');
3958 /* shift source */
3959 vpushi(bit_pos);
3960 gen_op(TOK_SHL);
3961 vswap();
3962 /* duplicate destination */
3963 vdup();
3964 vrott(3);
3965 /* load destination, mask and or with source */
3966 if (dbt == VT_LLONG)
3967 vpushll(~(mask << bit_pos));
3968 else
3969 vpushi(~((unsigned)mask << bit_pos));
3970 gen_op('&');
3971 gen_op('|');
3972 /* store result */
3973 vstore();
3974 /* ... and discard */
3975 vpop();
3977 } else if (dbt == VT_VOID) {
3978 --vtop;
3979 } else {
3980 /* optimize char/short casts */
3981 delayed_cast = 0;
3982 if ((dbt == VT_BYTE || dbt == VT_SHORT)
3983 && is_integer_btype(sbt)
3985 if ((vtop->r & VT_MUSTCAST)
3986 && btype_size(dbt) > btype_size(sbt)
3988 force_charshort_cast();
3989 delayed_cast = 1;
3990 } else {
3991 gen_cast(&vtop[-1].type);
3994 #ifdef CONFIG_TCC_BCHECK
3995 /* bound check case */
3996 if (vtop[-1].r & VT_MUSTBOUND) {
3997 vswap();
3998 gbound();
3999 vswap();
4001 #endif
4002 gv(RC_TYPE(dbt)); /* generate value */
4004 if (delayed_cast) {
4005 vtop->r |= BFVAL(VT_MUSTCAST, (sbt == VT_LLONG) + 1);
4006 //tcc_warning("deley cast %x -> %x", sbt, dbt);
4007 vtop->type.t = ft & VT_TYPE;
4010 /* if lvalue was saved on stack, must read it */
4011 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
4012 SValue sv;
4013 r = get_reg(RC_INT);
4014 sv.type.t = VT_PTRDIFF_T;
4015 sv.r = VT_LOCAL | VT_LVAL;
4016 sv.c.i = vtop[-1].c.i;
4017 load(r, &sv);
4018 vtop[-1].r = r | VT_LVAL;
4021 r = vtop->r & VT_VALMASK;
4022 /* two word case handling :
4023 store second register at word + 4 (or +8 for x86-64) */
4024 if (USING_TWO_WORDS(dbt)) {
4025 int load_type = (dbt == VT_QFLOAT) ? VT_DOUBLE : VT_PTRDIFF_T;
4026 vtop[-1].type.t = load_type;
4027 store(r, vtop - 1);
4028 vswap();
4029 /* convert to int to increment easily */
4030 vtop->type.t = VT_PTRDIFF_T;
4031 gaddrof();
4032 vpushs(PTR_SIZE);
4033 gen_op('+');
4034 vtop->r |= VT_LVAL;
4035 vswap();
4036 vtop[-1].type.t = load_type;
4037 /* XXX: it works because r2 is spilled last ! */
4038 store(vtop->r2, vtop - 1);
4039 } else {
4040 /* single word */
4041 store(r, vtop - 1);
4043 vswap();
4044 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4048 /* post defines POST/PRE add. c is the token ++ or -- */
4049 ST_FUNC void inc(int post, int c)
4051 test_lvalue();
4052 vdup(); /* save lvalue */
4053 if (post) {
4054 gv_dup(); /* duplicate value */
4055 vrotb(3);
4056 vrotb(3);
4058 /* add constant */
4059 vpushi(c - TOK_MID);
4060 gen_op('+');
4061 vstore(); /* store value */
4062 if (post)
4063 vpop(); /* if post op, return saved value */
4066 ST_FUNC void parse_mult_str (CString *astr, const char *msg)
4068 /* read the string */
4069 if (tok != TOK_STR)
4070 expect(msg);
4071 cstr_new(astr);
4072 while (tok == TOK_STR) {
4073 /* XXX: add \0 handling too ? */
4074 cstr_cat(astr, tokc.str.data, -1);
4075 next();
4077 cstr_ccat(astr, '\0');
4080 /* If I is >= 1 and a power of two, returns log2(i)+1.
4081 If I is 0 returns 0. */
4082 ST_FUNC int exact_log2p1(int i)
4084 int ret;
4085 if (!i)
4086 return 0;
4087 for (ret = 1; i >= 1 << 8; ret += 8)
4088 i >>= 8;
4089 if (i >= 1 << 4)
4090 ret += 4, i >>= 4;
4091 if (i >= 1 << 2)
4092 ret += 2, i >>= 2;
4093 if (i >= 1 << 1)
4094 ret++;
4095 return ret;
4098 /* Parse __attribute__((...)) GNUC extension. */
4099 static void parse_attribute(AttributeDef *ad)
4101 int t, n;
4102 CString astr;
4104 redo:
4105 if (tok != TOK_ATTRIBUTE1 && tok != TOK_ATTRIBUTE2)
4106 return;
4107 next();
4108 skip('(');
4109 skip('(');
4110 while (tok != ')') {
4111 if (tok < TOK_IDENT)
4112 expect("attribute name");
4113 t = tok;
4114 next();
4115 switch(t) {
4116 case TOK_CLEANUP1:
4117 case TOK_CLEANUP2:
4119 Sym *s;
4121 skip('(');
4122 s = sym_find(tok);
4123 if (!s) {
4124 tcc_warning("implicit declaration of function '%s'",
4125 get_tok_str(tok, &tokc));
4126 s = external_global_sym(tok, &func_old_type);
4127 } else if ((s->type.t & VT_BTYPE) != VT_FUNC)
4128 tcc_error("'%s' is not declared as function", get_tok_str(tok, &tokc));
4129 ad->cleanup_func = s;
4130 next();
4131 skip(')');
4132 break;
4134 case TOK_CONSTRUCTOR1:
4135 case TOK_CONSTRUCTOR2:
4136 ad->f.func_ctor = 1;
4137 break;
4138 case TOK_DESTRUCTOR1:
4139 case TOK_DESTRUCTOR2:
4140 ad->f.func_dtor = 1;
4141 break;
4142 case TOK_ALWAYS_INLINE1:
4143 case TOK_ALWAYS_INLINE2:
4144 ad->f.func_alwinl = 1;
4145 break;
4146 case TOK_SECTION1:
4147 case TOK_SECTION2:
4148 skip('(');
4149 parse_mult_str(&astr, "section name");
4150 ad->section = find_section(tcc_state, (char *)astr.data);
4151 skip(')');
4152 cstr_free(&astr);
4153 break;
4154 case TOK_ALIAS1:
4155 case TOK_ALIAS2:
4156 skip('(');
4157 parse_mult_str(&astr, "alias(\"target\")");
4158 ad->alias_target = /* save string as token, for later */
4159 tok_alloc((char*)astr.data, astr.size-1)->tok;
4160 skip(')');
4161 cstr_free(&astr);
4162 break;
4163 case TOK_VISIBILITY1:
4164 case TOK_VISIBILITY2:
4165 skip('(');
4166 parse_mult_str(&astr,
4167 "visibility(\"default|hidden|internal|protected\")");
4168 if (!strcmp (astr.data, "default"))
4169 ad->a.visibility = STV_DEFAULT;
4170 else if (!strcmp (astr.data, "hidden"))
4171 ad->a.visibility = STV_HIDDEN;
4172 else if (!strcmp (astr.data, "internal"))
4173 ad->a.visibility = STV_INTERNAL;
4174 else if (!strcmp (astr.data, "protected"))
4175 ad->a.visibility = STV_PROTECTED;
4176 else
4177 expect("visibility(\"default|hidden|internal|protected\")");
4178 skip(')');
4179 cstr_free(&astr);
4180 break;
4181 case TOK_ALIGNED1:
4182 case TOK_ALIGNED2:
4183 if (tok == '(') {
4184 next();
4185 n = expr_const();
4186 if (n <= 0 || (n & (n - 1)) != 0)
4187 tcc_error("alignment must be a positive power of two");
4188 skip(')');
4189 } else {
4190 n = MAX_ALIGN;
4192 ad->a.aligned = exact_log2p1(n);
4193 if (n != 1 << (ad->a.aligned - 1))
4194 tcc_error("alignment of %d is larger than implemented", n);
4195 break;
4196 case TOK_PACKED1:
4197 case TOK_PACKED2:
4198 ad->a.packed = 1;
4199 break;
4200 case TOK_WEAK1:
4201 case TOK_WEAK2:
4202 ad->a.weak = 1;
4203 break;
4204 case TOK_UNUSED1:
4205 case TOK_UNUSED2:
4206 /* currently, no need to handle it because tcc does not
4207 track unused objects */
4208 break;
4209 case TOK_NORETURN1:
4210 case TOK_NORETURN2:
4211 ad->f.func_noreturn = 1;
4212 break;
4213 case TOK_CDECL1:
4214 case TOK_CDECL2:
4215 case TOK_CDECL3:
4216 ad->f.func_call = FUNC_CDECL;
4217 break;
4218 case TOK_STDCALL1:
4219 case TOK_STDCALL2:
4220 case TOK_STDCALL3:
4221 ad->f.func_call = FUNC_STDCALL;
4222 break;
4223 #ifdef TCC_TARGET_I386
4224 case TOK_REGPARM1:
4225 case TOK_REGPARM2:
4226 skip('(');
4227 n = expr_const();
4228 if (n > 3)
4229 n = 3;
4230 else if (n < 0)
4231 n = 0;
4232 if (n > 0)
4233 ad->f.func_call = FUNC_FASTCALL1 + n - 1;
4234 skip(')');
4235 break;
4236 case TOK_FASTCALL1:
4237 case TOK_FASTCALL2:
4238 case TOK_FASTCALL3:
4239 ad->f.func_call = FUNC_FASTCALLW;
4240 break;
4241 #endif
4242 case TOK_MODE:
4243 skip('(');
4244 switch(tok) {
4245 case TOK_MODE_DI:
4246 ad->attr_mode = VT_LLONG + 1;
4247 break;
4248 case TOK_MODE_QI:
4249 ad->attr_mode = VT_BYTE + 1;
4250 break;
4251 case TOK_MODE_HI:
4252 ad->attr_mode = VT_SHORT + 1;
4253 break;
4254 case TOK_MODE_SI:
4255 case TOK_MODE_word:
4256 ad->attr_mode = VT_INT + 1;
4257 break;
4258 default:
4259 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
4260 break;
4262 next();
4263 skip(')');
4264 break;
4265 case TOK_DLLEXPORT:
4266 ad->a.dllexport = 1;
4267 break;
4268 case TOK_NODECORATE:
4269 ad->a.nodecorate = 1;
4270 break;
4271 case TOK_DLLIMPORT:
4272 ad->a.dllimport = 1;
4273 break;
4274 default:
4275 if (tcc_state->warn_unsupported)
4276 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
4277 /* skip parameters */
4278 if (tok == '(') {
4279 int parenthesis = 0;
4280 do {
4281 if (tok == '(')
4282 parenthesis++;
4283 else if (tok == ')')
4284 parenthesis--;
4285 next();
4286 } while (parenthesis && tok != -1);
4288 break;
4290 if (tok != ',')
4291 break;
4292 next();
4294 skip(')');
4295 skip(')');
4296 goto redo;
4299 static Sym * find_field (CType *type, int v, int *cumofs)
4301 Sym *s = type->ref;
4302 v |= SYM_FIELD;
4303 while ((s = s->next) != NULL) {
4304 if ((s->v & SYM_FIELD) &&
4305 (s->type.t & VT_BTYPE) == VT_STRUCT &&
4306 (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
4307 Sym *ret = find_field (&s->type, v, cumofs);
4308 if (ret) {
4309 *cumofs += s->c;
4310 return ret;
4313 if (s->v == v)
4314 break;
4316 return s;
4319 static void struct_layout(CType *type, AttributeDef *ad)
4321 int size, align, maxalign, offset, c, bit_pos, bit_size;
4322 int packed, a, bt, prevbt, prev_bit_size;
4323 int pcc = !tcc_state->ms_bitfields;
4324 int pragma_pack = *tcc_state->pack_stack_ptr;
4325 Sym *f;
4327 maxalign = 1;
4328 offset = 0;
4329 c = 0;
4330 bit_pos = 0;
4331 prevbt = VT_STRUCT; /* make it never match */
4332 prev_bit_size = 0;
4334 //#define BF_DEBUG
4336 for (f = type->ref->next; f; f = f->next) {
4337 if (f->type.t & VT_BITFIELD)
4338 bit_size = BIT_SIZE(f->type.t);
4339 else
4340 bit_size = -1;
4341 size = type_size(&f->type, &align);
4342 a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0;
4343 packed = 0;
4345 if (pcc && bit_size == 0) {
4346 /* in pcc mode, packing does not affect zero-width bitfields */
4348 } else {
4349 /* in pcc mode, attribute packed overrides if set. */
4350 if (pcc && (f->a.packed || ad->a.packed))
4351 align = packed = 1;
4353 /* pragma pack overrides align if lesser and packs bitfields always */
4354 if (pragma_pack) {
4355 packed = 1;
4356 if (pragma_pack < align)
4357 align = pragma_pack;
4358 /* in pcc mode pragma pack also overrides individual align */
4359 if (pcc && pragma_pack < a)
4360 a = 0;
4363 /* some individual align was specified */
4364 if (a)
4365 align = a;
4367 if (type->ref->type.t == VT_UNION) {
4368 if (pcc && bit_size >= 0)
4369 size = (bit_size + 7) >> 3;
4370 offset = 0;
4371 if (size > c)
4372 c = size;
4374 } else if (bit_size < 0) {
4375 if (pcc)
4376 c += (bit_pos + 7) >> 3;
4377 c = (c + align - 1) & -align;
4378 offset = c;
4379 if (size > 0)
4380 c += size;
4381 bit_pos = 0;
4382 prevbt = VT_STRUCT;
4383 prev_bit_size = 0;
4385 } else {
4386 /* A bit-field. Layout is more complicated. There are two
4387 options: PCC (GCC) compatible and MS compatible */
4388 if (pcc) {
4389 /* In PCC layout a bit-field is placed adjacent to the
4390 preceding bit-fields, except if:
4391 - it has zero-width
4392 - an individual alignment was given
4393 - it would overflow its base type container and
4394 there is no packing */
4395 if (bit_size == 0) {
4396 new_field:
4397 c = (c + ((bit_pos + 7) >> 3) + align - 1) & -align;
4398 bit_pos = 0;
4399 } else if (f->a.aligned) {
4400 goto new_field;
4401 } else if (!packed) {
4402 int a8 = align * 8;
4403 int ofs = ((c * 8 + bit_pos) % a8 + bit_size + a8 - 1) / a8;
4404 if (ofs > size / align)
4405 goto new_field;
4408 /* in pcc mode, long long bitfields have type int if they fit */
4409 if (size == 8 && bit_size <= 32)
4410 f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT, size = 4;
4412 while (bit_pos >= align * 8)
4413 c += align, bit_pos -= align * 8;
4414 offset = c;
4416 /* In PCC layout named bit-fields influence the alignment
4417 of the containing struct using the base types alignment,
4418 except for packed fields (which here have correct align). */
4419 if (f->v & SYM_FIRST_ANOM
4420 // && bit_size // ??? gcc on ARM/rpi does that
4422 align = 1;
4424 } else {
4425 bt = f->type.t & VT_BTYPE;
4426 if ((bit_pos + bit_size > size * 8)
4427 || (bit_size > 0) == (bt != prevbt)
4429 c = (c + align - 1) & -align;
4430 offset = c;
4431 bit_pos = 0;
4432 /* In MS bitfield mode a bit-field run always uses
4433 at least as many bits as the underlying type.
4434 To start a new run it's also required that this
4435 or the last bit-field had non-zero width. */
4436 if (bit_size || prev_bit_size)
4437 c += size;
4439 /* In MS layout the records alignment is normally
4440 influenced by the field, except for a zero-width
4441 field at the start of a run (but by further zero-width
4442 fields it is again). */
4443 if (bit_size == 0 && prevbt != bt)
4444 align = 1;
4445 prevbt = bt;
4446 prev_bit_size = bit_size;
4449 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
4450 | (bit_pos << VT_STRUCT_SHIFT);
4451 bit_pos += bit_size;
4453 if (align > maxalign)
4454 maxalign = align;
4456 #ifdef BF_DEBUG
4457 printf("set field %s offset %-2d size %-2d align %-2d",
4458 get_tok_str(f->v & ~SYM_FIELD, NULL), offset, size, align);
4459 if (f->type.t & VT_BITFIELD) {
4460 printf(" pos %-2d bits %-2d",
4461 BIT_POS(f->type.t),
4462 BIT_SIZE(f->type.t)
4465 printf("\n");
4466 #endif
4468 f->c = offset;
4469 f->r = 0;
4472 if (pcc)
4473 c += (bit_pos + 7) >> 3;
4475 /* store size and alignment */
4476 a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1;
4477 if (a < maxalign)
4478 a = maxalign;
4479 type->ref->r = a;
4480 if (pragma_pack && pragma_pack < maxalign && 0 == pcc) {
4481 /* can happen if individual align for some member was given. In
4482 this case MSVC ignores maxalign when aligning the size */
4483 a = pragma_pack;
4484 if (a < bt)
4485 a = bt;
4487 c = (c + a - 1) & -a;
4488 type->ref->c = c;
4490 #ifdef BF_DEBUG
4491 printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout);
4492 #endif
4494 /* check whether we can access bitfields by their type */
4495 for (f = type->ref->next; f; f = f->next) {
4496 int s, px, cx, c0;
4497 CType t;
4499 if (0 == (f->type.t & VT_BITFIELD))
4500 continue;
4501 f->type.ref = f;
4502 f->auxtype = -1;
4503 bit_size = BIT_SIZE(f->type.t);
4504 if (bit_size == 0)
4505 continue;
4506 bit_pos = BIT_POS(f->type.t);
4507 size = type_size(&f->type, &align);
4508 if (bit_pos + bit_size <= size * 8 && f->c + size <= c)
4509 continue;
4511 /* try to access the field using a different type */
4512 c0 = -1, s = align = 1;
4513 t.t = VT_BYTE;
4514 for (;;) {
4515 px = f->c * 8 + bit_pos;
4516 cx = (px >> 3) & -align;
4517 px = px - (cx << 3);
4518 if (c0 == cx)
4519 break;
4520 s = (px + bit_size + 7) >> 3;
4521 if (s > 4) {
4522 t.t = VT_LLONG;
4523 } else if (s > 2) {
4524 t.t = VT_INT;
4525 } else if (s > 1) {
4526 t.t = VT_SHORT;
4527 } else {
4528 t.t = VT_BYTE;
4530 s = type_size(&t, &align);
4531 c0 = cx;
4534 if (px + bit_size <= s * 8 && cx + s <= c) {
4535 /* update offset and bit position */
4536 f->c = cx;
4537 bit_pos = px;
4538 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
4539 | (bit_pos << VT_STRUCT_SHIFT);
4540 if (s != size)
4541 f->auxtype = t.t;
4542 #ifdef BF_DEBUG
4543 printf("FIX field %s offset %-2d size %-2d align %-2d "
4544 "pos %-2d bits %-2d\n",
4545 get_tok_str(f->v & ~SYM_FIELD, NULL),
4546 cx, s, align, px, bit_size);
4547 #endif
4548 } else {
4549 /* fall back to load/store single-byte wise */
4550 f->auxtype = VT_STRUCT;
4551 #ifdef BF_DEBUG
4552 printf("FIX field %s : load byte-wise\n",
4553 get_tok_str(f->v & ~SYM_FIELD, NULL));
4554 #endif
4559 /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
4560 static void struct_decl(CType *type, int u)
4562 int v, c, size, align, flexible;
4563 int bit_size, bsize, bt;
4564 Sym *s, *ss, **ps;
4565 AttributeDef ad, ad1;
4566 CType type1, btype;
4568 memset(&ad, 0, sizeof ad);
4569 next();
4570 parse_attribute(&ad);
4571 if (tok != '{') {
4572 v = tok;
4573 next();
4574 /* struct already defined ? return it */
4575 if (v < TOK_IDENT)
4576 expect("struct/union/enum name");
4577 s = struct_find(v);
4578 if (s && (s->sym_scope == local_scope || tok != '{')) {
4579 if (u == s->type.t)
4580 goto do_decl;
4581 if (u == VT_ENUM && IS_ENUM(s->type.t))
4582 goto do_decl;
4583 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
4585 } else {
4586 v = anon_sym++;
4588 /* Record the original enum/struct/union token. */
4589 type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u;
4590 type1.ref = NULL;
4591 /* we put an undefined size for struct/union */
4592 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
4593 s->r = 0; /* default alignment is zero as gcc */
4594 do_decl:
4595 type->t = s->type.t;
4596 type->ref = s;
4598 if (tok == '{') {
4599 next();
4600 if (s->c != -1)
4601 tcc_error("struct/union/enum already defined");
4602 s->c = -2;
4603 /* cannot be empty */
4604 /* non empty enums are not allowed */
4605 ps = &s->next;
4606 if (u == VT_ENUM) {
4607 long long ll = 0, pl = 0, nl = 0;
4608 CType t;
4609 t.ref = s;
4610 /* enum symbols have static storage */
4611 t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;
4612 for(;;) {
4613 v = tok;
4614 if (v < TOK_UIDENT)
4615 expect("identifier");
4616 ss = sym_find(v);
4617 if (ss && !local_stack)
4618 tcc_error("redefinition of enumerator '%s'",
4619 get_tok_str(v, NULL));
4620 next();
4621 if (tok == '=') {
4622 next();
4623 ll = expr_const64();
4625 ss = sym_push(v, &t, VT_CONST, 0);
4626 ss->enum_val = ll;
4627 *ps = ss, ps = &ss->next;
4628 if (ll < nl)
4629 nl = ll;
4630 if (ll > pl)
4631 pl = ll;
4632 if (tok != ',')
4633 break;
4634 next();
4635 ll++;
4636 /* NOTE: we accept a trailing comma */
4637 if (tok == '}')
4638 break;
4640 skip('}');
4641 /* set integral type of the enum */
4642 t.t = VT_INT;
4643 if (nl >= 0) {
4644 if (pl != (unsigned)pl)
4645 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
4646 t.t |= VT_UNSIGNED;
4647 } else if (pl != (int)pl || nl != (int)nl)
4648 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
4649 s->type.t = type->t = t.t | VT_ENUM;
4650 s->c = 0;
4651 /* set type for enum members */
4652 for (ss = s->next; ss; ss = ss->next) {
4653 ll = ss->enum_val;
4654 if (ll == (int)ll) /* default is int if it fits */
4655 continue;
4656 if (t.t & VT_UNSIGNED) {
4657 ss->type.t |= VT_UNSIGNED;
4658 if (ll == (unsigned)ll)
4659 continue;
4661 ss->type.t = (ss->type.t & ~VT_BTYPE)
4662 | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
4664 } else {
4665 c = 0;
4666 flexible = 0;
4667 while (tok != '}') {
4668 if (!parse_btype(&btype, &ad1)) {
4669 skip(';');
4670 continue;
4672 while (1) {
4673 if (flexible)
4674 tcc_error("flexible array member '%s' not at the end of struct",
4675 get_tok_str(v, NULL));
4676 bit_size = -1;
4677 v = 0;
4678 type1 = btype;
4679 if (tok != ':') {
4680 if (tok != ';')
4681 type_decl(&type1, &ad1, &v, TYPE_DIRECT);
4682 if (v == 0) {
4683 if ((type1.t & VT_BTYPE) != VT_STRUCT)
4684 expect("identifier");
4685 else {
4686 int v = btype.ref->v;
4687 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
4688 if (tcc_state->ms_extensions == 0)
4689 expect("identifier");
4693 if (type_size(&type1, &align) < 0) {
4694 if ((u == VT_STRUCT) && (type1.t & VT_ARRAY) && c)
4695 flexible = 1;
4696 else
4697 tcc_error("field '%s' has incomplete type",
4698 get_tok_str(v, NULL));
4700 if ((type1.t & VT_BTYPE) == VT_FUNC ||
4701 (type1.t & VT_BTYPE) == VT_VOID ||
4702 (type1.t & VT_STORAGE))
4703 tcc_error("invalid type for '%s'",
4704 get_tok_str(v, NULL));
4706 if (tok == ':') {
4707 next();
4708 bit_size = expr_const();
4709 /* XXX: handle v = 0 case for messages */
4710 if (bit_size < 0)
4711 tcc_error("negative width in bit-field '%s'",
4712 get_tok_str(v, NULL));
4713 if (v && bit_size == 0)
4714 tcc_error("zero width for bit-field '%s'",
4715 get_tok_str(v, NULL));
4716 parse_attribute(&ad1);
4718 size = type_size(&type1, &align);
4719 if (bit_size >= 0) {
4720 bt = type1.t & VT_BTYPE;
4721 if (bt != VT_INT &&
4722 bt != VT_BYTE &&
4723 bt != VT_SHORT &&
4724 bt != VT_BOOL &&
4725 bt != VT_LLONG)
4726 tcc_error("bitfields must have scalar type");
4727 bsize = size * 8;
4728 if (bit_size > bsize) {
4729 tcc_error("width of '%s' exceeds its type",
4730 get_tok_str(v, NULL));
4731 } else if (bit_size == bsize
4732 && !ad.a.packed && !ad1.a.packed) {
4733 /* no need for bit fields */
4735 } else if (bit_size == 64) {
4736 tcc_error("field width 64 not implemented");
4737 } else {
4738 type1.t = (type1.t & ~VT_STRUCT_MASK)
4739 | VT_BITFIELD
4740 | (bit_size << (VT_STRUCT_SHIFT + 6));
4743 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
4744 /* Remember we've seen a real field to check
4745 for placement of flexible array member. */
4746 c = 1;
4748 /* If member is a struct or bit-field, enforce
4749 placing into the struct (as anonymous). */
4750 if (v == 0 &&
4751 ((type1.t & VT_BTYPE) == VT_STRUCT ||
4752 bit_size >= 0)) {
4753 v = anon_sym++;
4755 if (v) {
4756 ss = sym_push(v | SYM_FIELD, &type1, 0, 0);
4757 ss->a = ad1.a;
4758 *ps = ss;
4759 ps = &ss->next;
4761 if (tok == ';' || tok == TOK_EOF)
4762 break;
4763 skip(',');
4765 skip(';');
4767 skip('}');
4768 parse_attribute(&ad);
4769 if (ad.cleanup_func) {
4770 tcc_warning("attribute '__cleanup__' ignored on type");
4772 struct_layout(type, &ad);
4777 static void sym_to_attr(AttributeDef *ad, Sym *s)
4779 merge_symattr(&ad->a, &s->a);
4780 merge_funcattr(&ad->f, &s->f);
4783 /* Add type qualifiers to a type. If the type is an array then the qualifiers
4784 are added to the element type, copied because it could be a typedef. */
4785 static void parse_btype_qualify(CType *type, int qualifiers)
4787 while (type->t & VT_ARRAY) {
4788 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
4789 type = &type->ref->type;
4791 type->t |= qualifiers;
4794 /* return 0 if no type declaration. otherwise, return the basic type
4795 and skip it.
4797 static int parse_btype(CType *type, AttributeDef *ad)
4799 int t, u, bt, st, type_found, typespec_found, g, n;
4800 Sym *s;
4801 CType type1;
4803 memset(ad, 0, sizeof(AttributeDef));
4804 type_found = 0;
4805 typespec_found = 0;
4806 t = VT_INT;
4807 bt = st = -1;
4808 type->ref = NULL;
4810 while(1) {
4811 switch(tok) {
4812 case TOK_EXTENSION:
4813 /* currently, we really ignore extension */
4814 next();
4815 continue;
4817 /* basic types */
4818 case TOK_CHAR:
4819 u = VT_BYTE;
4820 basic_type:
4821 next();
4822 basic_type1:
4823 if (u == VT_SHORT || u == VT_LONG) {
4824 if (st != -1 || (bt != -1 && bt != VT_INT))
4825 tmbt: tcc_error("too many basic types");
4826 st = u;
4827 } else {
4828 if (bt != -1 || (st != -1 && u != VT_INT))
4829 goto tmbt;
4830 bt = u;
4832 if (u != VT_INT)
4833 t = (t & ~(VT_BTYPE|VT_LONG)) | u;
4834 typespec_found = 1;
4835 break;
4836 case TOK_VOID:
4837 u = VT_VOID;
4838 goto basic_type;
4839 case TOK_SHORT:
4840 u = VT_SHORT;
4841 goto basic_type;
4842 case TOK_INT:
4843 u = VT_INT;
4844 goto basic_type;
4845 case TOK_ALIGNAS:
4846 { int n;
4847 AttributeDef ad1;
4848 next();
4849 skip('(');
4850 memset(&ad1, 0, sizeof(AttributeDef));
4851 if (parse_btype(&type1, &ad1)) {
4852 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
4853 if (ad1.a.aligned)
4854 n = 1 << (ad1.a.aligned - 1);
4855 else
4856 type_size(&type1, &n);
4857 } else {
4858 n = expr_const();
4859 if (n <= 0 || (n & (n - 1)) != 0)
4860 tcc_error("alignment must be a positive power of two");
4862 skip(')');
4863 ad->a.aligned = exact_log2p1(n);
4865 continue;
4866 case TOK_LONG:
4867 if ((t & VT_BTYPE) == VT_DOUBLE) {
4868 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
4869 } else if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
4870 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LLONG;
4871 } else {
4872 u = VT_LONG;
4873 goto basic_type;
4875 next();
4876 break;
4877 #ifdef TCC_TARGET_ARM64
4878 case TOK_UINT128:
4879 /* GCC's __uint128_t appears in some Linux header files. Make it a
4880 synonym for long double to get the size and alignment right. */
4881 u = VT_LDOUBLE;
4882 goto basic_type;
4883 #endif
4884 case TOK_BOOL:
4885 u = VT_BOOL;
4886 goto basic_type;
4887 case TOK_FLOAT:
4888 u = VT_FLOAT;
4889 goto basic_type;
4890 case TOK_DOUBLE:
4891 if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
4892 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
4893 } else {
4894 u = VT_DOUBLE;
4895 goto basic_type;
4897 next();
4898 break;
4899 case TOK_ENUM:
4900 struct_decl(&type1, VT_ENUM);
4901 basic_type2:
4902 u = type1.t;
4903 type->ref = type1.ref;
4904 goto basic_type1;
4905 case TOK_STRUCT:
4906 struct_decl(&type1, VT_STRUCT);
4907 goto basic_type2;
4908 case TOK_UNION:
4909 struct_decl(&type1, VT_UNION);
4910 goto basic_type2;
4912 /* type modifiers */
4913 case TOK_CONST1:
4914 case TOK_CONST2:
4915 case TOK_CONST3:
4916 type->t = t;
4917 parse_btype_qualify(type, VT_CONSTANT);
4918 t = type->t;
4919 next();
4920 break;
4921 case TOK_VOLATILE1:
4922 case TOK_VOLATILE2:
4923 case TOK_VOLATILE3:
4924 type->t = t;
4925 parse_btype_qualify(type, VT_VOLATILE);
4926 t = type->t;
4927 next();
4928 break;
4929 case TOK_SIGNED1:
4930 case TOK_SIGNED2:
4931 case TOK_SIGNED3:
4932 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
4933 tcc_error("signed and unsigned modifier");
4934 t |= VT_DEFSIGN;
4935 next();
4936 typespec_found = 1;
4937 break;
4938 case TOK_REGISTER:
4939 case TOK_AUTO:
4940 case TOK_RESTRICT1:
4941 case TOK_RESTRICT2:
4942 case TOK_RESTRICT3:
4943 next();
4944 break;
4945 case TOK_UNSIGNED:
4946 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
4947 tcc_error("signed and unsigned modifier");
4948 t |= VT_DEFSIGN | VT_UNSIGNED;
4949 next();
4950 typespec_found = 1;
4951 break;
4953 /* storage */
4954 case TOK_EXTERN:
4955 g = VT_EXTERN;
4956 goto storage;
4957 case TOK_STATIC:
4958 g = VT_STATIC;
4959 goto storage;
4960 case TOK_TYPEDEF:
4961 g = VT_TYPEDEF;
4962 goto storage;
4963 storage:
4964 if (t & (VT_EXTERN|VT_STATIC|VT_TYPEDEF) & ~g)
4965 tcc_error("multiple storage classes");
4966 t |= g;
4967 next();
4968 break;
4969 case TOK_INLINE1:
4970 case TOK_INLINE2:
4971 case TOK_INLINE3:
4972 t |= VT_INLINE;
4973 next();
4974 break;
4975 case TOK_NORETURN3:
4976 next();
4977 ad->f.func_noreturn = 1;
4978 break;
4979 /* GNUC attribute */
4980 case TOK_ATTRIBUTE1:
4981 case TOK_ATTRIBUTE2:
4982 parse_attribute(ad);
4983 if (ad->attr_mode) {
4984 u = ad->attr_mode -1;
4985 t = (t & ~(VT_BTYPE|VT_LONG)) | u;
4987 continue;
4988 /* GNUC typeof */
4989 case TOK_TYPEOF1:
4990 case TOK_TYPEOF2:
4991 case TOK_TYPEOF3:
4992 next();
4993 parse_expr_type(&type1);
4994 /* remove all storage modifiers except typedef */
4995 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
4996 if (type1.ref)
4997 sym_to_attr(ad, type1.ref);
4998 goto basic_type2;
4999 default:
5000 if (typespec_found)
5001 goto the_end;
5002 s = sym_find(tok);
5003 if (!s || !(s->type.t & VT_TYPEDEF))
5004 goto the_end;
5006 n = tok, next();
5007 if (tok == ':' && !in_generic) {
5008 /* ignore if it's a label */
5009 unget_tok(n);
5010 goto the_end;
5013 t &= ~(VT_BTYPE|VT_LONG);
5014 u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u;
5015 type->t = (s->type.t & ~VT_TYPEDEF) | u;
5016 type->ref = s->type.ref;
5017 if (t)
5018 parse_btype_qualify(type, t);
5019 t = type->t;
5020 /* get attributes from typedef */
5021 sym_to_attr(ad, s);
5022 typespec_found = 1;
5023 st = bt = -2;
5024 break;
5026 type_found = 1;
5028 the_end:
5029 if (tcc_state->char_is_unsigned) {
5030 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
5031 t |= VT_UNSIGNED;
5033 /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
5034 bt = t & (VT_BTYPE|VT_LONG);
5035 if (bt == VT_LONG)
5036 t |= LONG_SIZE == 8 ? VT_LLONG : VT_INT;
5037 #if defined TCC_TARGET_PE || (defined _WIN32 && defined _MSC_VER)
5038 if (bt == VT_LDOUBLE)
5039 t = (t & ~(VT_BTYPE|VT_LONG)) | (VT_DOUBLE|VT_LONG);
5040 #endif
5041 type->t = t;
5042 return type_found;
5045 /* convert a function parameter type (array to pointer and function to
5046 function pointer) */
5047 static inline void convert_parameter_type(CType *pt)
5049 /* remove const and volatile qualifiers (XXX: const could be used
5050 to indicate a const function parameter */
5051 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
5052 /* array must be transformed to pointer according to ANSI C */
5053 pt->t &= ~VT_ARRAY;
5054 if ((pt->t & VT_BTYPE) == VT_FUNC) {
5055 mk_pointer(pt);
5059 ST_FUNC void parse_asm_str(CString *astr)
5061 skip('(');
5062 parse_mult_str(astr, "string constant");
5065 /* Parse an asm label and return the token */
5066 static int asm_label_instr(void)
5068 int v;
5069 CString astr;
5071 next();
5072 parse_asm_str(&astr);
5073 skip(')');
5074 #ifdef ASM_DEBUG
5075 printf("asm_alias: \"%s\"\n", (char *)astr.data);
5076 #endif
5077 v = tok_alloc(astr.data, astr.size - 1)->tok;
5078 cstr_free(&astr);
5079 return v;
5082 static int post_type(CType *type, AttributeDef *ad, int storage, int td)
5084 int n, l, t1, arg_size, align, unused_align;
5085 Sym **plast, *s, *first;
5086 AttributeDef ad1;
5087 CType pt;
5089 if (tok == '(') {
5090 /* function type, or recursive declarator (return if so) */
5091 next();
5092 if (td && !(td & TYPE_ABSTRACT))
5093 return 0;
5094 if (tok == ')')
5095 l = 0;
5096 else if (parse_btype(&pt, &ad1))
5097 l = FUNC_NEW;
5098 else if (td) {
5099 merge_attr (ad, &ad1);
5100 return 0;
5101 } else
5102 l = FUNC_OLD;
5103 first = NULL;
5104 plast = &first;
5105 arg_size = 0;
5106 if (l) {
5107 for(;;) {
5108 /* read param name and compute offset */
5109 if (l != FUNC_OLD) {
5110 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
5111 break;
5112 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
5113 if ((pt.t & VT_BTYPE) == VT_VOID)
5114 tcc_error("parameter declared as void");
5115 } else {
5116 n = tok;
5117 if (n < TOK_UIDENT)
5118 expect("identifier");
5119 pt.t = VT_VOID; /* invalid type */
5120 pt.ref = NULL;
5121 next();
5123 convert_parameter_type(&pt);
5124 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
5125 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
5126 *plast = s;
5127 plast = &s->next;
5128 if (tok == ')')
5129 break;
5130 skip(',');
5131 if (l == FUNC_NEW && tok == TOK_DOTS) {
5132 l = FUNC_ELLIPSIS;
5133 next();
5134 break;
5136 if (l == FUNC_NEW && !parse_btype(&pt, &ad1))
5137 tcc_error("invalid type");
5139 } else
5140 /* if no parameters, then old type prototype */
5141 l = FUNC_OLD;
5142 skip(')');
5143 /* NOTE: const is ignored in returned type as it has a special
5144 meaning in gcc / C++ */
5145 type->t &= ~VT_CONSTANT;
5146 /* some ancient pre-K&R C allows a function to return an array
5147 and the array brackets to be put after the arguments, such
5148 that "int c()[]" means something like "int[] c()" */
5149 if (tok == '[') {
5150 next();
5151 skip(']'); /* only handle simple "[]" */
5152 mk_pointer(type);
5154 /* we push a anonymous symbol which will contain the function prototype */
5155 ad->f.func_args = arg_size;
5156 ad->f.func_type = l;
5157 s = sym_push(SYM_FIELD, type, 0, 0);
5158 s->a = ad->a;
5159 s->f = ad->f;
5160 s->next = first;
5161 type->t = VT_FUNC;
5162 type->ref = s;
5163 } else if (tok == '[') {
5164 int saved_nocode_wanted = nocode_wanted;
5165 /* array definition */
5166 next();
5167 while (1) {
5168 /* XXX The optional type-quals and static should only be accepted
5169 in parameter decls. The '*' as well, and then even only
5170 in prototypes (not function defs). */
5171 switch (tok) {
5172 case TOK_RESTRICT1: case TOK_RESTRICT2: case TOK_RESTRICT3:
5173 case TOK_CONST1:
5174 case TOK_VOLATILE1:
5175 case TOK_STATIC:
5176 case '*':
5177 next();
5178 continue;
5179 default:
5180 break;
5182 break;
5184 n = -1;
5185 t1 = 0;
5186 if (tok != ']') {
5187 if (!local_stack || (storage & VT_STATIC))
5188 vpushi(expr_const());
5189 else {
5190 /* VLAs (which can only happen with local_stack && !VT_STATIC)
5191 length must always be evaluated, even under nocode_wanted,
5192 so that its size slot is initialized (e.g. under sizeof
5193 or typeof). */
5194 nocode_wanted = 0;
5195 gexpr();
5197 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
5198 n = vtop->c.i;
5199 if (n < 0)
5200 tcc_error("invalid array size");
5201 } else {
5202 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
5203 tcc_error("size of variable length array should be an integer");
5204 n = 0;
5205 t1 = VT_VLA;
5208 skip(']');
5209 /* parse next post type */
5210 post_type(type, ad, storage, 0);
5212 if ((type->t & VT_BTYPE) == VT_FUNC)
5213 tcc_error("declaration of an array of functions");
5214 if ((type->t & VT_BTYPE) == VT_VOID
5215 || type_size(type, &unused_align) < 0)
5216 tcc_error("declaration of an array of incomplete type elements");
5218 t1 |= type->t & VT_VLA;
5220 if (t1 & VT_VLA) {
5221 if (n < 0)
5222 tcc_error("need explicit inner array size in VLAs");
5223 loc -= type_size(&int_type, &align);
5224 loc &= -align;
5225 n = loc;
5227 vla_runtime_type_size(type, &align);
5228 gen_op('*');
5229 vset(&int_type, VT_LOCAL|VT_LVAL, n);
5230 vswap();
5231 vstore();
5233 if (n != -1)
5234 vpop();
5235 nocode_wanted = saved_nocode_wanted;
5237 /* we push an anonymous symbol which will contain the array
5238 element type */
5239 s = sym_push(SYM_FIELD, type, 0, n);
5240 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
5241 type->ref = s;
5243 return 1;
5246 /* Parse a type declarator (except basic type), and return the type
5247 in 'type'. 'td' is a bitmask indicating which kind of type decl is
5248 expected. 'type' should contain the basic type. 'ad' is the
5249 attribute definition of the basic type. It can be modified by
5250 type_decl(). If this (possibly abstract) declarator is a pointer chain
5251 it returns the innermost pointed to type (equals *type, but is a different
5252 pointer), otherwise returns type itself, that's used for recursive calls. */
5253 static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td)
5255 CType *post, *ret;
5256 int qualifiers, storage;
5258 /* recursive type, remove storage bits first, apply them later again */
5259 storage = type->t & VT_STORAGE;
5260 type->t &= ~VT_STORAGE;
5261 post = ret = type;
5263 while (tok == '*') {
5264 qualifiers = 0;
5265 redo:
5266 next();
5267 switch(tok) {
5268 case TOK_CONST1:
5269 case TOK_CONST2:
5270 case TOK_CONST3:
5271 qualifiers |= VT_CONSTANT;
5272 goto redo;
5273 case TOK_VOLATILE1:
5274 case TOK_VOLATILE2:
5275 case TOK_VOLATILE3:
5276 qualifiers |= VT_VOLATILE;
5277 goto redo;
5278 case TOK_RESTRICT1:
5279 case TOK_RESTRICT2:
5280 case TOK_RESTRICT3:
5281 goto redo;
5282 /* XXX: clarify attribute handling */
5283 case TOK_ATTRIBUTE1:
5284 case TOK_ATTRIBUTE2:
5285 parse_attribute(ad);
5286 break;
5288 mk_pointer(type);
5289 type->t |= qualifiers;
5290 if (ret == type)
5291 /* innermost pointed to type is the one for the first derivation */
5292 ret = pointed_type(type);
5295 if (tok == '(') {
5296 /* This is possibly a parameter type list for abstract declarators
5297 ('int ()'), use post_type for testing this. */
5298 if (!post_type(type, ad, 0, td)) {
5299 /* It's not, so it's a nested declarator, and the post operations
5300 apply to the innermost pointed to type (if any). */
5301 /* XXX: this is not correct to modify 'ad' at this point, but
5302 the syntax is not clear */
5303 parse_attribute(ad);
5304 post = type_decl(type, ad, v, td);
5305 skip(')');
5306 } else
5307 goto abstract;
5308 } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
5309 /* type identifier */
5310 *v = tok;
5311 next();
5312 } else {
5313 abstract:
5314 if (!(td & TYPE_ABSTRACT))
5315 expect("identifier");
5316 *v = 0;
5318 post_type(post, ad, storage, 0);
5319 parse_attribute(ad);
5320 type->t |= storage;
5321 return ret;
5324 /* indirection with full error checking and bound check */
5325 ST_FUNC void indir(void)
5327 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
5328 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
5329 return;
5330 expect("pointer");
5332 if (vtop->r & VT_LVAL)
5333 gv(RC_INT);
5334 vtop->type = *pointed_type(&vtop->type);
5335 /* Arrays and functions are never lvalues */
5336 if (!(vtop->type.t & (VT_ARRAY | VT_VLA))
5337 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
5338 vtop->r |= VT_LVAL;
5339 /* if bound checking, the referenced pointer must be checked */
5340 #ifdef CONFIG_TCC_BCHECK
5341 if (tcc_state->do_bounds_check)
5342 vtop->r |= VT_MUSTBOUND;
5343 #endif
5347 /* pass a parameter to a function and do type checking and casting */
5348 static void gfunc_param_typed(Sym *func, Sym *arg)
5350 int func_type;
5351 CType type;
5353 func_type = func->f.func_type;
5354 if (func_type == FUNC_OLD ||
5355 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
5356 /* default casting : only need to convert float to double */
5357 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
5358 gen_cast_s(VT_DOUBLE);
5359 } else if (vtop->type.t & VT_BITFIELD) {
5360 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
5361 type.ref = vtop->type.ref;
5362 gen_cast(&type);
5363 } else if (vtop->r & VT_MUSTCAST) {
5364 force_charshort_cast();
5366 } else if (arg == NULL) {
5367 tcc_error("too many arguments to function");
5368 } else {
5369 type = arg->type;
5370 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
5371 gen_assign_cast(&type);
5375 /* parse an expression and return its type without any side effect. */
5376 static void expr_type(CType *type, void (*expr_fn)(void))
5378 nocode_wanted++;
5379 expr_fn();
5380 *type = vtop->type;
5381 vpop();
5382 nocode_wanted--;
5385 /* parse an expression of the form '(type)' or '(expr)' and return its
5386 type */
5387 static void parse_expr_type(CType *type)
5389 int n;
5390 AttributeDef ad;
5392 skip('(');
5393 if (parse_btype(type, &ad)) {
5394 type_decl(type, &ad, &n, TYPE_ABSTRACT);
5395 } else {
5396 expr_type(type, gexpr);
5398 skip(')');
5401 static void parse_type(CType *type)
5403 AttributeDef ad;
5404 int n;
5406 if (!parse_btype(type, &ad)) {
5407 expect("type");
5409 type_decl(type, &ad, &n, TYPE_ABSTRACT);
5412 static void parse_builtin_params(int nc, const char *args)
5414 char c, sep = '(';
5415 CType type;
5416 if (nc)
5417 nocode_wanted++;
5418 next();
5419 if (*args == 0)
5420 skip(sep);
5421 while ((c = *args++)) {
5422 skip(sep);
5423 sep = ',';
5424 if (c == 't') {
5425 parse_type(&type);
5426 vpush(&type);
5427 continue;
5429 expr_eq();
5430 type.ref = NULL;
5431 type.t = 0;
5432 switch (c) {
5433 case 'e':
5434 continue;
5435 case 'V':
5436 type.t = VT_CONSTANT;
5437 case 'v':
5438 type.t |= VT_VOID;
5439 mk_pointer (&type);
5440 break;
5441 case 'S':
5442 type.t = VT_CONSTANT;
5443 case 's':
5444 type.t |= char_type.t;
5445 mk_pointer (&type);
5446 break;
5447 case 'i':
5448 type.t = VT_INT;
5449 break;
5450 case 'l':
5451 type.t = VT_SIZE_T;
5452 break;
5453 default:
5454 break;
5456 gen_assign_cast(&type);
5458 skip(')');
5459 if (nc)
5460 nocode_wanted--;
5463 ST_FUNC void unary(void)
5465 int n, t, align, size, r, sizeof_caller;
5466 CType type;
5467 Sym *s;
5468 AttributeDef ad;
5470 /* generate line number info */
5471 if (tcc_state->do_debug)
5472 tcc_debug_line(tcc_state);
5474 sizeof_caller = in_sizeof;
5475 in_sizeof = 0;
5476 type.ref = NULL;
5477 /* XXX: GCC 2.95.3 does not generate a table although it should be
5478 better here */
5479 tok_next:
5480 switch(tok) {
5481 case TOK_EXTENSION:
5482 next();
5483 goto tok_next;
5484 case TOK_LCHAR:
5485 #ifdef TCC_TARGET_PE
5486 t = VT_SHORT|VT_UNSIGNED;
5487 goto push_tokc;
5488 #endif
5489 case TOK_CINT:
5490 case TOK_CCHAR:
5491 t = VT_INT;
5492 push_tokc:
5493 type.t = t;
5494 vsetc(&type, VT_CONST, &tokc);
5495 next();
5496 break;
5497 case TOK_CUINT:
5498 t = VT_INT | VT_UNSIGNED;
5499 goto push_tokc;
5500 case TOK_CLLONG:
5501 t = VT_LLONG;
5502 goto push_tokc;
5503 case TOK_CULLONG:
5504 t = VT_LLONG | VT_UNSIGNED;
5505 goto push_tokc;
5506 case TOK_CFLOAT:
5507 t = VT_FLOAT;
5508 goto push_tokc;
5509 case TOK_CDOUBLE:
5510 t = VT_DOUBLE;
5511 goto push_tokc;
5512 case TOK_CLDOUBLE:
5513 t = VT_LDOUBLE;
5514 goto push_tokc;
5515 case TOK_CLONG:
5516 t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG;
5517 goto push_tokc;
5518 case TOK_CULONG:
5519 t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG | VT_UNSIGNED;
5520 goto push_tokc;
5521 case TOK___FUNCTION__:
5522 if (!gnu_ext)
5523 goto tok_identifier;
5524 /* fall thru */
5525 case TOK___FUNC__:
5527 void *ptr;
5528 int len;
5529 /* special function name identifier */
5530 len = strlen(funcname) + 1;
5531 /* generate char[len] type */
5532 type.t = VT_BYTE;
5533 mk_pointer(&type);
5534 type.t |= VT_ARRAY;
5535 type.ref->c = len;
5536 vpush_ref(&type, data_section, data_section->data_offset, len);
5537 if (!NODATA_WANTED) {
5538 ptr = section_ptr_add(data_section, len);
5539 memcpy(ptr, funcname, len);
5541 next();
5543 break;
5544 case TOK_LSTR:
5545 #ifdef TCC_TARGET_PE
5546 t = VT_SHORT | VT_UNSIGNED;
5547 #else
5548 t = VT_INT;
5549 #endif
5550 goto str_init;
5551 case TOK_STR:
5552 /* string parsing */
5553 t = VT_BYTE;
5554 if (tcc_state->char_is_unsigned)
5555 t = VT_BYTE | VT_UNSIGNED;
5556 str_init:
5557 if (tcc_state->warn_write_strings)
5558 t |= VT_CONSTANT;
5559 type.t = t;
5560 mk_pointer(&type);
5561 type.t |= VT_ARRAY;
5562 memset(&ad, 0, sizeof(AttributeDef));
5563 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
5564 break;
5565 case '(':
5566 next();
5567 /* cast ? */
5568 if (parse_btype(&type, &ad)) {
5569 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
5570 skip(')');
5571 /* check ISOC99 compound literal */
5572 if (tok == '{') {
5573 /* data is allocated locally by default */
5574 if (global_expr)
5575 r = VT_CONST;
5576 else
5577 r = VT_LOCAL;
5578 /* all except arrays are lvalues */
5579 if (!(type.t & VT_ARRAY))
5580 r |= VT_LVAL;
5581 memset(&ad, 0, sizeof(AttributeDef));
5582 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
5583 } else {
5584 if (sizeof_caller) {
5585 vpush(&type);
5586 return;
5588 unary();
5589 gen_cast(&type);
5591 } else if (tok == '{') {
5592 int saved_nocode_wanted = nocode_wanted;
5593 if (const_wanted && !(nocode_wanted & unevalmask))
5594 expect("constant");
5595 if (0 == local_scope)
5596 tcc_error("statement expression outside of function");
5597 /* save all registers */
5598 save_regs(0);
5599 /* statement expression : we do not accept break/continue
5600 inside as GCC does. We do retain the nocode_wanted state,
5601 as statement expressions can't ever be entered from the
5602 outside, so any reactivation of code emission (from labels
5603 or loop heads) can be disabled again after the end of it. */
5604 block(1);
5605 nocode_wanted = saved_nocode_wanted;
5606 skip(')');
5607 } else {
5608 gexpr();
5609 skip(')');
5611 break;
5612 case '*':
5613 next();
5614 unary();
5615 indir();
5616 break;
5617 case '&':
5618 next();
5619 unary();
5620 /* functions names must be treated as function pointers,
5621 except for unary '&' and sizeof. Since we consider that
5622 functions are not lvalues, we only have to handle it
5623 there and in function calls. */
5624 /* arrays can also be used although they are not lvalues */
5625 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
5626 !(vtop->type.t & VT_ARRAY))
5627 test_lvalue();
5628 if (vtop->sym)
5629 vtop->sym->a.addrtaken = 1;
5630 mk_pointer(&vtop->type);
5631 gaddrof();
5632 break;
5633 case '!':
5634 next();
5635 unary();
5636 gen_test_zero(TOK_EQ);
5637 break;
5638 case '~':
5639 next();
5640 unary();
5641 vpushi(-1);
5642 gen_op('^');
5643 break;
5644 case '+':
5645 next();
5646 unary();
5647 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
5648 tcc_error("pointer not accepted for unary plus");
5649 /* In order to force cast, we add zero, except for floating point
5650 where we really need an noop (otherwise -0.0 will be transformed
5651 into +0.0). */
5652 if (!is_float(vtop->type.t)) {
5653 vpushi(0);
5654 gen_op('+');
5656 break;
5657 case TOK_SIZEOF:
5658 case TOK_ALIGNOF1:
5659 case TOK_ALIGNOF2:
5660 case TOK_ALIGNOF3:
5661 t = tok;
5662 next();
5663 in_sizeof++;
5664 expr_type(&type, unary); /* Perform a in_sizeof = 0; */
5665 s = NULL;
5666 if (vtop[1].r & VT_SYM)
5667 s = vtop[1].sym; /* hack: accessing previous vtop */
5668 size = type_size(&type, &align);
5669 if (s && s->a.aligned)
5670 align = 1 << (s->a.aligned - 1);
5671 if (t == TOK_SIZEOF) {
5672 if (!(type.t & VT_VLA)) {
5673 if (size < 0)
5674 tcc_error("sizeof applied to an incomplete type");
5675 vpushs(size);
5676 } else {
5677 vla_runtime_type_size(&type, &align);
5679 } else {
5680 vpushs(align);
5682 vtop->type.t |= VT_UNSIGNED;
5683 break;
5685 case TOK_builtin_expect:
5686 /* __builtin_expect is a no-op for now */
5687 parse_builtin_params(0, "ee");
5688 vpop();
5689 break;
5690 case TOK_builtin_types_compatible_p:
5691 parse_builtin_params(0, "tt");
5692 vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
5693 vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
5694 n = is_compatible_types(&vtop[-1].type, &vtop[0].type);
5695 vtop -= 2;
5696 vpushi(n);
5697 break;
5698 case TOK_builtin_choose_expr:
5700 int64_t c;
5701 next();
5702 skip('(');
5703 c = expr_const64();
5704 skip(',');
5705 if (!c) {
5706 nocode_wanted++;
5708 expr_eq();
5709 if (!c) {
5710 vpop();
5711 nocode_wanted--;
5713 skip(',');
5714 if (c) {
5715 nocode_wanted++;
5717 expr_eq();
5718 if (c) {
5719 vpop();
5720 nocode_wanted--;
5722 skip(')');
5724 break;
5725 case TOK_builtin_constant_p:
5726 parse_builtin_params(1, "e");
5727 n = (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
5728 !((vtop->r & VT_SYM) && vtop->sym->a.addrtaken);
5729 vtop--;
5730 vpushi(n);
5731 break;
5732 case TOK_builtin_frame_address:
5733 case TOK_builtin_return_address:
5735 int tok1 = tok;
5736 int level;
5737 next();
5738 skip('(');
5739 if (tok != TOK_CINT) {
5740 tcc_error("%s only takes positive integers",
5741 tok1 == TOK_builtin_return_address ?
5742 "__builtin_return_address" :
5743 "__builtin_frame_address");
5745 level = (uint32_t)tokc.i;
5746 next();
5747 skip(')');
5748 type.t = VT_VOID;
5749 mk_pointer(&type);
5750 vset(&type, VT_LOCAL, 0); /* local frame */
5751 while (level--) {
5752 #ifdef TCC_TARGET_RISCV64
5753 vpushi(2*PTR_SIZE);
5754 gen_op('-');
5755 #endif
5756 mk_pointer(&vtop->type);
5757 indir(); /* -> parent frame */
5759 if (tok1 == TOK_builtin_return_address) {
5760 // assume return address is just above frame pointer on stack
5761 #ifdef TCC_TARGET_ARM
5762 vpushi(2*PTR_SIZE);
5763 gen_op('+');
5764 #elif defined TCC_TARGET_RISCV64
5765 vpushi(PTR_SIZE);
5766 gen_op('-');
5767 #else
5768 vpushi(PTR_SIZE);
5769 gen_op('+');
5770 #endif
5771 mk_pointer(&vtop->type);
5772 indir();
5775 break;
5776 #ifdef TCC_TARGET_RISCV64
5777 case TOK_builtin_va_start:
5778 parse_builtin_params(0, "ee");
5779 r = vtop->r & VT_VALMASK;
5780 if (r == VT_LLOCAL)
5781 r = VT_LOCAL;
5782 if (r != VT_LOCAL)
5783 tcc_error("__builtin_va_start expects a local variable");
5784 gen_va_start();
5785 vstore();
5786 break;
5787 #endif
5788 #ifdef TCC_TARGET_X86_64
5789 #ifdef TCC_TARGET_PE
5790 case TOK_builtin_va_start:
5791 parse_builtin_params(0, "ee");
5792 r = vtop->r & VT_VALMASK;
5793 if (r == VT_LLOCAL)
5794 r = VT_LOCAL;
5795 if (r != VT_LOCAL)
5796 tcc_error("__builtin_va_start expects a local variable");
5797 vtop->r = r;
5798 vtop->type = char_pointer_type;
5799 vtop->c.i += 8;
5800 vstore();
5801 break;
5802 #else
5803 case TOK_builtin_va_arg_types:
5804 parse_builtin_params(0, "t");
5805 vpushi(classify_x86_64_va_arg(&vtop->type));
5806 vswap();
5807 vpop();
5808 break;
5809 #endif
5810 #endif
5812 #ifdef TCC_TARGET_ARM64
5813 case TOK_builtin_va_start: {
5814 parse_builtin_params(0, "ee");
5815 //xx check types
5816 gen_va_start();
5817 vpushi(0);
5818 vtop->type.t = VT_VOID;
5819 break;
5821 case TOK_builtin_va_arg: {
5822 parse_builtin_params(0, "et");
5823 type = vtop->type;
5824 vpop();
5825 //xx check types
5826 gen_va_arg(&type);
5827 vtop->type = type;
5828 break;
5830 case TOK___arm64_clear_cache: {
5831 parse_builtin_params(0, "ee");
5832 gen_clear_cache();
5833 vpushi(0);
5834 vtop->type.t = VT_VOID;
5835 break;
5837 #endif
5839 /* pre operations */
5840 case TOK_INC:
5841 case TOK_DEC:
5842 t = tok;
5843 next();
5844 unary();
5845 inc(0, t);
5846 break;
5847 case '-':
5848 next();
5849 unary();
5850 t = vtop->type.t & VT_BTYPE;
5851 if (is_float(t)) {
5852 /* In IEEE negate(x) isn't subtract(0,x), but rather
5853 subtract(-0, x). */
5854 vpush(&vtop->type);
5855 if (t == VT_FLOAT)
5856 vtop->c.f = -1.0 * 0.0;
5857 else if (t == VT_DOUBLE)
5858 vtop->c.d = -1.0 * 0.0;
5859 else
5860 vtop->c.ld = -1.0 * 0.0;
5861 } else
5862 vpushi(0);
5863 vswap();
5864 gen_op('-');
5865 break;
5866 case TOK_LAND:
5867 if (!gnu_ext)
5868 goto tok_identifier;
5869 next();
5870 /* allow to take the address of a label */
5871 if (tok < TOK_UIDENT)
5872 expect("label identifier");
5873 s = label_find(tok);
5874 if (!s) {
5875 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
5876 } else {
5877 if (s->r == LABEL_DECLARED)
5878 s->r = LABEL_FORWARD;
5880 if (!s->type.t) {
5881 s->type.t = VT_VOID;
5882 mk_pointer(&s->type);
5883 s->type.t |= VT_STATIC;
5885 vpushsym(&s->type, s);
5886 next();
5887 break;
5889 case TOK_GENERIC:
5891 CType controlling_type;
5892 int has_default = 0;
5893 int has_match = 0;
5894 int learn = 0;
5895 TokenString *str = NULL;
5896 int saved_const_wanted = const_wanted;
5898 next();
5899 skip('(');
5900 const_wanted = 0;
5901 expr_type(&controlling_type, expr_eq);
5902 controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY);
5903 if ((controlling_type.t & VT_BTYPE) == VT_FUNC)
5904 mk_pointer(&controlling_type);
5905 const_wanted = saved_const_wanted;
5906 for (;;) {
5907 learn = 0;
5908 skip(',');
5909 if (tok == TOK_DEFAULT) {
5910 if (has_default)
5911 tcc_error("too many 'default'");
5912 has_default = 1;
5913 if (!has_match)
5914 learn = 1;
5915 next();
5916 } else {
5917 AttributeDef ad_tmp;
5918 int itmp;
5919 CType cur_type;
5921 in_generic++;
5922 parse_btype(&cur_type, &ad_tmp);
5923 in_generic--;
5925 type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
5926 if (compare_types(&controlling_type, &cur_type, 0)) {
5927 if (has_match) {
5928 tcc_error("type match twice");
5930 has_match = 1;
5931 learn = 1;
5934 skip(':');
5935 if (learn) {
5936 if (str)
5937 tok_str_free(str);
5938 skip_or_save_block(&str);
5939 } else {
5940 skip_or_save_block(NULL);
5942 if (tok == ')')
5943 break;
5945 if (!str) {
5946 char buf[60];
5947 type_to_str(buf, sizeof buf, &controlling_type, NULL);
5948 tcc_error("type '%s' does not match any association", buf);
5950 begin_macro(str, 1);
5951 next();
5952 expr_eq();
5953 if (tok != TOK_EOF)
5954 expect(",");
5955 end_macro();
5956 next();
5957 break;
5959 // special qnan , snan and infinity values
5960 case TOK___NAN__:
5961 n = 0x7fc00000;
5962 special_math_val:
5963 vpushi(n);
5964 vtop->type.t = VT_FLOAT;
5965 next();
5966 break;
5967 case TOK___SNAN__:
5968 n = 0x7f800001;
5969 goto special_math_val;
5970 case TOK___INF__:
5971 n = 0x7f800000;
5972 goto special_math_val;
5974 default:
5975 tok_identifier:
5976 t = tok;
5977 next();
5978 if (t < TOK_UIDENT)
5979 expect("identifier");
5980 s = sym_find(t);
5981 if (!s || IS_ASM_SYM(s)) {
5982 const char *name = get_tok_str(t, NULL);
5983 if (tok != '(')
5984 tcc_error("'%s' undeclared", name);
5985 /* for simple function calls, we tolerate undeclared
5986 external reference to int() function */
5987 if (tcc_state->warn_implicit_function_declaration
5988 #ifdef TCC_TARGET_PE
5989 /* people must be warned about using undeclared WINAPI functions
5990 (which usually start with uppercase letter) */
5991 || (name[0] >= 'A' && name[0] <= 'Z')
5992 #endif
5994 tcc_warning("implicit declaration of function '%s'", name);
5995 s = external_global_sym(t, &func_old_type);
5998 r = s->r;
5999 /* A symbol that has a register is a local register variable,
6000 which starts out as VT_LOCAL value. */
6001 if ((r & VT_VALMASK) < VT_CONST)
6002 r = (r & ~VT_VALMASK) | VT_LOCAL;
6004 vset(&s->type, r, s->c);
6005 /* Point to s as backpointer (even without r&VT_SYM).
6006 Will be used by at least the x86 inline asm parser for
6007 regvars. */
6008 vtop->sym = s;
6010 if (r & VT_SYM) {
6011 vtop->c.i = 0;
6012 } else if (r == VT_CONST && IS_ENUM_VAL(s->type.t)) {
6013 vtop->c.i = s->enum_val;
6015 break;
6018 /* post operations */
6019 while (1) {
6020 if (tok == TOK_INC || tok == TOK_DEC) {
6021 inc(1, tok);
6022 next();
6023 } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
6024 int qualifiers, cumofs = 0;
6025 /* field */
6026 if (tok == TOK_ARROW)
6027 indir();
6028 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
6029 test_lvalue();
6030 gaddrof();
6031 /* expect pointer on structure */
6032 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
6033 expect("struct or union");
6034 if (tok == TOK_CDOUBLE)
6035 expect("field name");
6036 next();
6037 if (tok == TOK_CINT || tok == TOK_CUINT)
6038 expect("field name");
6039 s = find_field(&vtop->type, tok, &cumofs);
6040 if (!s)
6041 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc));
6042 /* add field offset to pointer */
6043 vtop->type = char_pointer_type; /* change type to 'char *' */
6044 vpushi(cumofs + s->c);
6045 gen_op('+');
6046 /* change type to field type, and set to lvalue */
6047 vtop->type = s->type;
6048 vtop->type.t |= qualifiers;
6049 /* an array is never an lvalue */
6050 if (!(vtop->type.t & VT_ARRAY)) {
6051 vtop->r |= VT_LVAL;
6052 #ifdef CONFIG_TCC_BCHECK
6053 /* if bound checking, the referenced pointer must be checked */
6054 if (tcc_state->do_bounds_check)
6055 vtop->r |= VT_MUSTBOUND;
6056 #endif
6058 next();
6059 } else if (tok == '[') {
6060 next();
6061 gexpr();
6062 gen_op('+');
6063 indir();
6064 skip(']');
6065 } else if (tok == '(') {
6066 SValue ret;
6067 Sym *sa;
6068 int nb_args, ret_nregs, ret_align, regsize, variadic;
6070 /* function call */
6071 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
6072 /* pointer test (no array accepted) */
6073 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
6074 vtop->type = *pointed_type(&vtop->type);
6075 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
6076 goto error_func;
6077 } else {
6078 error_func:
6079 expect("function pointer");
6081 } else {
6082 vtop->r &= ~VT_LVAL; /* no lvalue */
6084 /* get return type */
6085 s = vtop->type.ref;
6086 next();
6087 sa = s->next; /* first parameter */
6088 nb_args = regsize = 0;
6089 ret.r2 = VT_CONST;
6090 /* compute first implicit argument if a structure is returned */
6091 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
6092 variadic = (s->f.func_type == FUNC_ELLIPSIS);
6093 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
6094 &ret_align, &regsize);
6095 if (ret_nregs <= 0) {
6096 /* get some space for the returned structure */
6097 size = type_size(&s->type, &align);
6098 #ifdef TCC_TARGET_ARM64
6099 /* On arm64, a small struct is return in registers.
6100 It is much easier to write it to memory if we know
6101 that we are allowed to write some extra bytes, so
6102 round the allocated space up to a power of 2: */
6103 if (size < 16)
6104 while (size & (size - 1))
6105 size = (size | (size - 1)) + 1;
6106 #endif
6107 loc = (loc - size) & -align;
6108 ret.type = s->type;
6109 ret.r = VT_LOCAL | VT_LVAL;
6110 /* pass it as 'int' to avoid structure arg passing
6111 problems */
6112 vseti(VT_LOCAL, loc);
6113 #ifdef CONFIG_TCC_BCHECK
6114 if (tcc_state->do_bounds_check)
6115 --loc;
6116 #endif
6117 ret.c = vtop->c;
6118 if (ret_nregs < 0)
6119 vtop--;
6120 else
6121 nb_args++;
6123 } else {
6124 ret_nregs = 1;
6125 ret.type = s->type;
6128 if (ret_nregs > 0) {
6129 /* return in register */
6130 ret.c.i = 0;
6131 PUT_R_RET(&ret, ret.type.t);
6133 if (tok != ')') {
6134 for(;;) {
6135 expr_eq();
6136 gfunc_param_typed(s, sa);
6137 nb_args++;
6138 if (sa)
6139 sa = sa->next;
6140 if (tok == ')')
6141 break;
6142 skip(',');
6145 if (sa)
6146 tcc_error("too few arguments to function");
6147 skip(')');
6148 gfunc_call(nb_args);
6150 if (ret_nregs < 0) {
6151 vsetc(&ret.type, ret.r, &ret.c);
6152 #ifdef TCC_TARGET_RISCV64
6153 arch_transfer_ret_regs(1);
6154 #endif
6155 } else {
6156 /* return value */
6157 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
6158 vsetc(&ret.type, r, &ret.c);
6159 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
6162 /* handle packed struct return */
6163 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
6164 int addr, offset;
6166 size = type_size(&s->type, &align);
6167 /* We're writing whole regs often, make sure there's enough
6168 space. Assume register size is power of 2. */
6169 if (regsize > align)
6170 align = regsize;
6171 loc = (loc - size) & -align;
6172 addr = loc;
6173 offset = 0;
6174 for (;;) {
6175 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
6176 vswap();
6177 vstore();
6178 vtop--;
6179 if (--ret_nregs == 0)
6180 break;
6181 offset += regsize;
6183 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
6186 /* Promote char/short return values. This is matters only
6187 for calling function that were not compiled by TCC and
6188 only on some architectures. For those where it doesn't
6189 matter we expect things to be already promoted to int,
6190 but not larger. */
6191 t = s->type.t & VT_BTYPE;
6192 if (t == VT_BYTE || t == VT_SHORT || t == VT_BOOL) {
6193 #ifdef PROMOTE_RET
6194 vtop->r |= BFVAL(VT_MUSTCAST, 1);
6195 #else
6196 vtop->type.t = VT_INT;
6197 #endif
6200 if (s->f.func_noreturn)
6201 CODE_OFF();
6202 } else {
6203 break;
6208 #ifndef precedence_parser /* original top-down parser */
6210 static void expr_prod(void)
6212 int t;
6214 unary();
6215 while ((t = tok) == '*' || t == '/' || t == '%') {
6216 next();
6217 unary();
6218 gen_op(t);
6222 static void expr_sum(void)
6224 int t;
6226 expr_prod();
6227 while ((t = tok) == '+' || t == '-') {
6228 next();
6229 expr_prod();
6230 gen_op(t);
6234 static void expr_shift(void)
6236 int t;
6238 expr_sum();
6239 while ((t = tok) == TOK_SHL || t == TOK_SAR) {
6240 next();
6241 expr_sum();
6242 gen_op(t);
6246 static void expr_cmp(void)
6248 int t;
6250 expr_shift();
6251 while (((t = tok) >= TOK_ULE && t <= TOK_GT) ||
6252 t == TOK_ULT || t == TOK_UGE) {
6253 next();
6254 expr_shift();
6255 gen_op(t);
6259 static void expr_cmpeq(void)
6261 int t;
6263 expr_cmp();
6264 while ((t = tok) == TOK_EQ || t == TOK_NE) {
6265 next();
6266 expr_cmp();
6267 gen_op(t);
6271 static void expr_and(void)
6273 expr_cmpeq();
6274 while (tok == '&') {
6275 next();
6276 expr_cmpeq();
6277 gen_op('&');
6281 static void expr_xor(void)
6283 expr_and();
6284 while (tok == '^') {
6285 next();
6286 expr_and();
6287 gen_op('^');
6291 static void expr_or(void)
6293 expr_xor();
6294 while (tok == '|') {
6295 next();
6296 expr_xor();
6297 gen_op('|');
6301 static void expr_landor(int op);
6303 static void expr_land(void)
6305 expr_or();
6306 if (tok == TOK_LAND)
6307 expr_landor(tok);
6310 static void expr_lor(void)
6312 expr_land();
6313 if (tok == TOK_LOR)
6314 expr_landor(tok);
6317 # define expr_landor_next(op) op == TOK_LAND ? expr_or() : expr_land()
6318 #else /* defined precedence_parser */
6319 # define expr_landor_next(op) unary(), expr_infix(precedence(op) + 1)
6320 # define expr_lor() unary(), expr_infix(1)
6322 static int precedence(int tok)
6324 switch (tok) {
6325 case TOK_LOR: return 1;
6326 case TOK_LAND: return 2;
6327 case '|': return 3;
6328 case '^': return 4;
6329 case '&': return 5;
6330 case TOK_EQ: case TOK_NE: return 6;
6331 relat: case TOK_ULT: case TOK_UGE: return 7;
6332 case TOK_SHL: case TOK_SAR: return 8;
6333 case '+': case '-': return 9;
6334 case '*': case '/': case '%': return 10;
6335 default:
6336 if (tok >= TOK_ULE && tok <= TOK_GT)
6337 goto relat;
6338 return 0;
6341 static unsigned char prec[256];
6342 static void init_prec(void)
6344 int i;
6345 for (i = 0; i < 256; i++)
6346 prec[i] = precedence(i);
6348 #define precedence(i) ((unsigned)i < 256 ? prec[i] : 0)
6350 static void expr_landor(int op);
6352 static void expr_infix(int p)
6354 int t = tok, p2;
6355 while ((p2 = precedence(t)) >= p) {
6356 if (t == TOK_LOR || t == TOK_LAND) {
6357 expr_landor(t);
6358 } else {
6359 next();
6360 unary();
6361 if (precedence(tok) > p2)
6362 expr_infix(p2 + 1);
6363 gen_op(t);
6365 t = tok;
6368 #endif
6370 /* Assuming vtop is a value used in a conditional context
6371 (i.e. compared with zero) return 0 if it's false, 1 if
6372 true and -1 if it can't be statically determined. */
6373 static int condition_3way(void)
6375 int c = -1;
6376 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
6377 (!(vtop->r & VT_SYM) || !vtop->sym->a.weak)) {
6378 vdup();
6379 gen_cast_s(VT_BOOL);
6380 c = vtop->c.i;
6381 vpop();
6383 return c;
6386 static void expr_landor(int op)
6388 int t = 0, cc = 1, f = 0, i = op == TOK_LAND, c;
6389 for(;;) {
6390 c = f ? i : condition_3way();
6391 if (c < 0)
6392 save_regs(1), cc = 0;
6393 else if (c != i)
6394 nocode_wanted++, f = 1;
6395 if (tok != op)
6396 break;
6397 if (c < 0)
6398 t = gvtst(i, t);
6399 else
6400 vpop();
6401 next();
6402 expr_landor_next(op);
6404 if (cc || f) {
6405 vpop();
6406 vpushi(i ^ f);
6407 gsym(t);
6408 nocode_wanted -= f;
6409 } else {
6410 gvtst_set(i, t);
6414 static int is_cond_bool(SValue *sv)
6416 if ((sv->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST
6417 && (sv->type.t & VT_BTYPE) == VT_INT)
6418 return (unsigned)sv->c.i < 2;
6419 if (sv->r == VT_CMP)
6420 return 1;
6421 return 0;
6424 static void expr_cond(void)
6426 int tt, u, r1, r2, rc, t1, t2, islv, c, g;
6427 SValue sv;
6428 CType type;
6429 int ncw_prev;
6431 expr_lor();
6432 if (tok == '?') {
6433 next();
6434 c = condition_3way();
6435 g = (tok == ':' && gnu_ext);
6436 tt = 0;
6437 if (!g) {
6438 if (c < 0) {
6439 save_regs(1);
6440 tt = gvtst(1, 0);
6441 } else {
6442 vpop();
6444 } else if (c < 0) {
6445 /* needed to avoid having different registers saved in
6446 each branch */
6447 save_regs(1);
6448 gv_dup();
6449 tt = gvtst(0, 0);
6452 ncw_prev = nocode_wanted;
6453 if (c == 0)
6454 nocode_wanted++;
6455 if (!g)
6456 gexpr();
6458 if (c < 0 && vtop->r == VT_CMP) {
6459 t1 = gvtst(0, 0);
6460 vpushi(0);
6461 gvtst_set(0, t1);
6462 gv(RC_INT);
6465 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
6466 mk_pointer(&vtop->type);
6467 sv = *vtop; /* save value to handle it later */
6468 vtop--; /* no vpop so that FP stack is not flushed */
6470 if (g) {
6471 u = tt;
6472 } else if (c < 0) {
6473 u = gjmp(0);
6474 gsym(tt);
6475 } else
6476 u = 0;
6478 nocode_wanted = ncw_prev;
6479 if (c == 1)
6480 nocode_wanted++;
6481 skip(':');
6482 expr_cond();
6484 if (c < 0 && is_cond_bool(vtop) && is_cond_bool(&sv)) {
6485 if (sv.r == VT_CMP) {
6486 t1 = sv.jtrue;
6487 t2 = u;
6488 } else {
6489 t1 = gvtst(0, 0);
6490 t2 = gjmp(0);
6491 gsym(u);
6492 vpushv(&sv);
6494 gvtst_set(0, t1);
6495 gvtst_set(1, t2);
6496 nocode_wanted = ncw_prev;
6497 // tcc_warning("two conditions expr_cond");
6498 return;
6501 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
6502 mk_pointer(&vtop->type);
6504 /* cast operands to correct type according to ISOC rules */
6505 if (!combine_types(&type, &sv, vtop, '?'))
6506 type_incompatibility_error(&sv.type, &vtop->type,
6507 "type mismatch in conditional expression (have '%s' and '%s')");
6508 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
6509 that `(expr ? a : b).mem` does not error with "lvalue expected" */
6510 islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
6512 /* now we convert second operand */
6513 if (c != 1) {
6514 gen_cast(&type);
6515 if (islv) {
6516 mk_pointer(&vtop->type);
6517 gaddrof();
6518 } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
6519 gaddrof();
6522 rc = RC_TYPE(type.t);
6523 /* for long longs, we use fixed registers to avoid having
6524 to handle a complicated move */
6525 if (USING_TWO_WORDS(type.t))
6526 rc = RC_RET(type.t);
6528 tt = r2 = 0;
6529 if (c < 0) {
6530 r2 = gv(rc);
6531 tt = gjmp(0);
6533 gsym(u);
6534 nocode_wanted = ncw_prev;
6536 /* this is horrible, but we must also convert first
6537 operand */
6538 if (c != 0) {
6539 *vtop = sv;
6540 gen_cast(&type);
6541 if (islv) {
6542 mk_pointer(&vtop->type);
6543 gaddrof();
6544 } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
6545 gaddrof();
6548 if (c < 0) {
6549 r1 = gv(rc);
6550 move_reg(r2, r1, islv ? VT_PTR : type.t);
6551 vtop->r = r2;
6552 gsym(tt);
6555 if (islv)
6556 indir();
6560 static void expr_eq(void)
6562 int t;
6564 expr_cond();
6565 if ((t = tok) == '=' || TOK_ASSIGN(t)) {
6566 test_lvalue();
6567 next();
6568 if (t == '=') {
6569 expr_eq();
6570 } else {
6571 vdup();
6572 expr_eq();
6573 gen_op(TOK_ASSIGN_OP(t));
6575 vstore();
6579 ST_FUNC void gexpr(void)
6581 while (1) {
6582 expr_eq();
6583 if (tok != ',')
6584 break;
6585 vpop();
6586 next();
6590 /* parse a constant expression and return value in vtop. */
6591 static void expr_const1(void)
6593 const_wanted++;
6594 nocode_wanted += unevalmask + 1;
6595 expr_cond();
6596 nocode_wanted -= unevalmask + 1;
6597 const_wanted--;
6600 /* parse an integer constant and return its value. */
6601 static inline int64_t expr_const64(void)
6603 int64_t c;
6604 expr_const1();
6605 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
6606 expect("constant expression");
6607 c = vtop->c.i;
6608 vpop();
6609 return c;
6612 /* parse an integer constant and return its value.
6613 Complain if it doesn't fit 32bit (signed or unsigned). */
6614 ST_FUNC int expr_const(void)
6616 int c;
6617 int64_t wc = expr_const64();
6618 c = wc;
6619 if (c != wc && (unsigned)c != wc)
6620 tcc_error("constant exceeds 32 bit");
6621 return c;
6624 /* ------------------------------------------------------------------------- */
6625 /* return from function */
6627 #ifndef TCC_TARGET_ARM64
6628 static void gfunc_return(CType *func_type)
6630 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
6631 CType type, ret_type;
6632 int ret_align, ret_nregs, regsize;
6633 ret_nregs = gfunc_sret(func_type, func_var, &ret_type,
6634 &ret_align, &regsize);
6635 if (ret_nregs < 0) {
6636 #ifdef TCC_TARGET_RISCV64
6637 arch_transfer_ret_regs(0);
6638 #endif
6639 } else if (0 == ret_nregs) {
6640 /* if returning structure, must copy it to implicit
6641 first pointer arg location */
6642 type = *func_type;
6643 mk_pointer(&type);
6644 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
6645 indir();
6646 vswap();
6647 /* copy structure value to pointer */
6648 vstore();
6649 } else {
6650 /* returning structure packed into registers */
6651 int size, addr, align, rc;
6652 size = type_size(func_type,&align);
6653 if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
6654 (vtop->c.i & (ret_align-1)))
6655 && (align & (ret_align-1))) {
6656 loc = (loc - size) & -ret_align;
6657 addr = loc;
6658 type = *func_type;
6659 vset(&type, VT_LOCAL | VT_LVAL, addr);
6660 vswap();
6661 vstore();
6662 vpop();
6663 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
6665 vtop->type = ret_type;
6666 rc = RC_RET(ret_type.t);
6667 if (ret_nregs == 1)
6668 gv(rc);
6669 else {
6670 for (;;) {
6671 vdup();
6672 gv(rc);
6673 vpop();
6674 if (--ret_nregs == 0)
6675 break;
6676 /* We assume that when a structure is returned in multiple
6677 registers, their classes are consecutive values of the
6678 suite s(n) = 2^n */
6679 rc <<= 1;
6680 vtop->c.i += regsize;
6684 } else {
6685 gv(RC_RET(func_type->t));
6687 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
6689 #endif
6691 static void check_func_return(void)
6693 if ((func_vt.t & VT_BTYPE) == VT_VOID)
6694 return;
6695 if (!strcmp (funcname, "main")
6696 && (func_vt.t & VT_BTYPE) == VT_INT) {
6697 /* main returns 0 by default */
6698 vpushi(0);
6699 gen_assign_cast(&func_vt);
6700 gfunc_return(&func_vt);
6701 } else {
6702 tcc_warning("function might return no value: '%s'", funcname);
6706 /* ------------------------------------------------------------------------- */
6707 /* switch/case */
6709 static int case_cmpi(const void *pa, const void *pb)
6711 int64_t a = (*(struct case_t**) pa)->v1;
6712 int64_t b = (*(struct case_t**) pb)->v1;
6713 return a < b ? -1 : a > b;
6716 static int case_cmpu(const void *pa, const void *pb)
6718 uint64_t a = (uint64_t)(*(struct case_t**) pa)->v1;
6719 uint64_t b = (uint64_t)(*(struct case_t**) pb)->v1;
6720 return a < b ? -1 : a > b;
6723 static void gtst_addr(int t, int a)
6725 gsym_addr(gvtst(0, t), a);
6728 static void gcase(struct case_t **base, int len, int *bsym)
6730 struct case_t *p;
6731 int e;
6732 int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG;
6733 while (len > 8) {
6734 /* binary search */
6735 p = base[len/2];
6736 vdup();
6737 if (ll)
6738 vpushll(p->v2);
6739 else
6740 vpushi(p->v2);
6741 gen_op(TOK_LE);
6742 e = gvtst(1, 0);
6743 vdup();
6744 if (ll)
6745 vpushll(p->v1);
6746 else
6747 vpushi(p->v1);
6748 gen_op(TOK_GE);
6749 gtst_addr(0, p->sym); /* v1 <= x <= v2 */
6750 /* x < v1 */
6751 gcase(base, len/2, bsym);
6752 /* x > v2 */
6753 gsym(e);
6754 e = len/2 + 1;
6755 base += e; len -= e;
6757 /* linear scan */
6758 while (len--) {
6759 p = *base++;
6760 vdup();
6761 if (ll)
6762 vpushll(p->v2);
6763 else
6764 vpushi(p->v2);
6765 if (p->v1 == p->v2) {
6766 gen_op(TOK_EQ);
6767 gtst_addr(0, p->sym);
6768 } else {
6769 gen_op(TOK_LE);
6770 e = gvtst(1, 0);
6771 vdup();
6772 if (ll)
6773 vpushll(p->v1);
6774 else
6775 vpushi(p->v1);
6776 gen_op(TOK_GE);
6777 gtst_addr(0, p->sym);
6778 gsym(e);
6781 *bsym = gjmp(*bsym);
6784 /* ------------------------------------------------------------------------- */
6785 /* __attribute__((cleanup(fn))) */
6787 static void try_call_scope_cleanup(Sym *stop)
6789 Sym *cls = cur_scope->cl.s;
6791 for (; cls != stop; cls = cls->ncl) {
6792 Sym *fs = cls->next;
6793 Sym *vs = cls->prev_tok;
6795 vpushsym(&fs->type, fs);
6796 vset(&vs->type, vs->r, vs->c);
6797 vtop->sym = vs;
6798 mk_pointer(&vtop->type);
6799 gaddrof();
6800 gfunc_call(1);
6804 static void try_call_cleanup_goto(Sym *cleanupstate)
6806 Sym *oc, *cc;
6807 int ocd, ccd;
6809 if (!cur_scope->cl.s)
6810 return;
6812 /* search NCA of both cleanup chains given parents and initial depth */
6813 ocd = cleanupstate ? cleanupstate->v & ~SYM_FIELD : 0;
6814 for (ccd = cur_scope->cl.n, oc = cleanupstate; ocd > ccd; --ocd, oc = oc->ncl)
6816 for (cc = cur_scope->cl.s; ccd > ocd; --ccd, cc = cc->ncl)
6818 for (; cc != oc; cc = cc->ncl, oc = oc->ncl, --ccd)
6821 try_call_scope_cleanup(cc);
6824 /* call 'func' for each __attribute__((cleanup(func))) */
6825 static void block_cleanup(struct scope *o)
6827 int jmp = 0;
6828 Sym *g, **pg;
6829 for (pg = &pending_gotos; (g = *pg) && g->c > o->cl.n;) {
6830 if (g->prev_tok->r & LABEL_FORWARD) {
6831 Sym *pcl = g->next;
6832 if (!jmp)
6833 jmp = gjmp(0);
6834 gsym(pcl->jnext);
6835 try_call_scope_cleanup(o->cl.s);
6836 pcl->jnext = gjmp(0);
6837 if (!o->cl.n)
6838 goto remove_pending;
6839 g->c = o->cl.n;
6840 pg = &g->prev;
6841 } else {
6842 remove_pending:
6843 *pg = g->prev;
6844 sym_free(g);
6847 gsym(jmp);
6848 try_call_scope_cleanup(o->cl.s);
6851 /* ------------------------------------------------------------------------- */
6852 /* VLA */
6854 static void vla_restore(int loc)
6856 if (loc)
6857 gen_vla_sp_restore(loc);
6860 static void vla_leave(struct scope *o)
6862 if (o->vla.num < cur_scope->vla.num)
6863 vla_restore(o->vla.loc);
6866 /* ------------------------------------------------------------------------- */
6867 /* local scopes */
6869 void new_scope(struct scope *o)
6871 /* copy and link previous scope */
6872 *o = *cur_scope;
6873 o->prev = cur_scope;
6874 cur_scope = o;
6876 /* record local declaration stack position */
6877 o->lstk = local_stack;
6878 o->llstk = local_label_stack;
6880 ++local_scope;
6882 if (tcc_state->do_debug)
6883 tcc_debug_stabn(N_LBRAC, ind - func_ind);
6886 void prev_scope(struct scope *o, int is_expr)
6888 vla_leave(o->prev);
6890 if (o->cl.s != o->prev->cl.s)
6891 block_cleanup(o->prev);
6893 /* pop locally defined labels */
6894 label_pop(&local_label_stack, o->llstk, is_expr);
6896 /* In the is_expr case (a statement expression is finished here),
6897 vtop might refer to symbols on the local_stack. Either via the
6898 type or via vtop->sym. We can't pop those nor any that in turn
6899 might be referred to. To make it easier we don't roll back
6900 any symbols in that case; some upper level call to block() will
6901 do that. We do have to remove such symbols from the lookup
6902 tables, though. sym_pop will do that. */
6904 /* pop locally defined symbols */
6905 pop_local_syms(&local_stack, o->lstk, is_expr, 0);
6906 cur_scope = o->prev;
6907 --local_scope;
6909 if (tcc_state->do_debug)
6910 tcc_debug_stabn(N_RBRAC, ind - func_ind);
6913 /* leave a scope via break/continue(/goto) */
6914 void leave_scope(struct scope *o)
6916 if (!o)
6917 return;
6918 try_call_scope_cleanup(o->cl.s);
6919 vla_leave(o);
6922 /* ------------------------------------------------------------------------- */
6923 /* call block from 'for do while' loops */
6925 static void lblock(int *bsym, int *csym)
6927 struct scope *lo = loop_scope, *co = cur_scope;
6928 int *b = co->bsym, *c = co->csym;
6929 if (csym) {
6930 co->csym = csym;
6931 loop_scope = co;
6933 co->bsym = bsym;
6934 block(0);
6935 co->bsym = b;
6936 if (csym) {
6937 co->csym = c;
6938 loop_scope = lo;
6942 static void block(int is_expr)
6944 int a, b, c, d, e, t;
6945 struct scope o;
6946 Sym *s;
6948 if (is_expr) {
6949 /* default return value is (void) */
6950 vpushi(0);
6951 vtop->type.t = VT_VOID;
6954 again:
6955 t = tok;
6956 /* If the token carries a value, next() might destroy it. Only with
6957 invalid code such as f(){"123"4;} */
6958 if (TOK_HAS_VALUE(t))
6959 goto expr;
6960 next();
6962 if (t == TOK_IF) {
6963 skip('(');
6964 gexpr();
6965 skip(')');
6966 a = gvtst(1, 0);
6967 block(0);
6968 if (tok == TOK_ELSE) {
6969 d = gjmp(0);
6970 gsym(a);
6971 next();
6972 block(0);
6973 gsym(d); /* patch else jmp */
6974 } else {
6975 gsym(a);
6978 } else if (t == TOK_WHILE) {
6979 d = gind();
6980 skip('(');
6981 gexpr();
6982 skip(')');
6983 a = gvtst(1, 0);
6984 b = 0;
6985 lblock(&a, &b);
6986 gjmp_addr(d);
6987 gsym_addr(b, d);
6988 gsym(a);
6990 } else if (t == '{') {
6991 new_scope(&o);
6993 /* handle local labels declarations */
6994 while (tok == TOK_LABEL) {
6995 do {
6996 next();
6997 if (tok < TOK_UIDENT)
6998 expect("label identifier");
6999 label_push(&local_label_stack, tok, LABEL_DECLARED);
7000 next();
7001 } while (tok == ',');
7002 skip(';');
7005 while (tok != '}') {
7006 decl(VT_LOCAL);
7007 if (tok != '}') {
7008 if (is_expr)
7009 vpop();
7010 block(is_expr);
7014 prev_scope(&o, is_expr);
7015 if (local_scope)
7016 next();
7017 else if (!nocode_wanted)
7018 check_func_return();
7020 } else if (t == TOK_RETURN) {
7021 b = (func_vt.t & VT_BTYPE) != VT_VOID;
7022 if (tok != ';') {
7023 gexpr();
7024 if (b) {
7025 gen_assign_cast(&func_vt);
7026 } else {
7027 if (vtop->type.t != VT_VOID)
7028 tcc_warning("void function returns a value");
7029 vtop--;
7031 } else if (b) {
7032 tcc_warning("'return' with no value");
7033 b = 0;
7035 leave_scope(root_scope);
7036 if (b)
7037 gfunc_return(&func_vt);
7038 skip(';');
7039 /* jump unless last stmt in top-level block */
7040 if (tok != '}' || local_scope != 1)
7041 rsym = gjmp(rsym);
7042 CODE_OFF();
7044 } else if (t == TOK_BREAK) {
7045 /* compute jump */
7046 if (!cur_scope->bsym)
7047 tcc_error("cannot break");
7048 if (cur_switch && cur_scope->bsym == cur_switch->bsym)
7049 leave_scope(cur_switch->scope);
7050 else
7051 leave_scope(loop_scope);
7052 *cur_scope->bsym = gjmp(*cur_scope->bsym);
7053 skip(';');
7055 } else if (t == TOK_CONTINUE) {
7056 /* compute jump */
7057 if (!cur_scope->csym)
7058 tcc_error("cannot continue");
7059 leave_scope(loop_scope);
7060 *cur_scope->csym = gjmp(*cur_scope->csym);
7061 skip(';');
7063 } else if (t == TOK_FOR) {
7064 new_scope(&o);
7066 skip('(');
7067 if (tok != ';') {
7068 /* c99 for-loop init decl? */
7069 if (!decl0(VT_LOCAL, 1, NULL)) {
7070 /* no, regular for-loop init expr */
7071 gexpr();
7072 vpop();
7075 skip(';');
7076 a = b = 0;
7077 c = d = gind();
7078 if (tok != ';') {
7079 gexpr();
7080 a = gvtst(1, 0);
7082 skip(';');
7083 if (tok != ')') {
7084 e = gjmp(0);
7085 d = gind();
7086 gexpr();
7087 vpop();
7088 gjmp_addr(c);
7089 gsym(e);
7091 skip(')');
7092 lblock(&a, &b);
7093 gjmp_addr(d);
7094 gsym_addr(b, d);
7095 gsym(a);
7096 prev_scope(&o, 0);
7098 } else if (t == TOK_DO) {
7099 a = b = 0;
7100 d = gind();
7101 lblock(&a, &b);
7102 gsym(b);
7103 skip(TOK_WHILE);
7104 skip('(');
7105 gexpr();
7106 skip(')');
7107 skip(';');
7108 c = gvtst(0, 0);
7109 gsym_addr(c, d);
7110 gsym(a);
7112 } else if (t == TOK_SWITCH) {
7113 struct switch_t *sw;
7115 sw = tcc_mallocz(sizeof *sw);
7116 sw->bsym = &a;
7117 sw->scope = cur_scope;
7118 sw->prev = cur_switch;
7119 cur_switch = sw;
7121 skip('(');
7122 gexpr();
7123 skip(')');
7124 sw->sv = *vtop--; /* save switch value */
7126 a = 0;
7127 b = gjmp(0); /* jump to first case */
7128 lblock(&a, NULL);
7129 a = gjmp(a); /* add implicit break */
7130 /* case lookup */
7131 gsym(b);
7133 if (sw->sv.type.t & VT_UNSIGNED)
7134 qsort(sw->p, sw->n, sizeof(void*), case_cmpu);
7135 else
7136 qsort(sw->p, sw->n, sizeof(void*), case_cmpi);
7138 for (b = 1; b < sw->n; b++)
7139 if (sw->sv.type.t & VT_UNSIGNED
7140 ? (uint64_t)sw->p[b - 1]->v2 >= (uint64_t)sw->p[b]->v1
7141 : sw->p[b - 1]->v2 >= sw->p[b]->v1)
7142 tcc_error("duplicate case value");
7144 vpushv(&sw->sv);
7145 gv(RC_INT);
7146 d = 0, gcase(sw->p, sw->n, &d);
7147 vpop();
7148 if (sw->def_sym)
7149 gsym_addr(d, sw->def_sym);
7150 else
7151 gsym(d);
7152 /* break label */
7153 gsym(a);
7155 dynarray_reset(&sw->p, &sw->n);
7156 cur_switch = sw->prev;
7157 tcc_free(sw);
7159 } else if (t == TOK_CASE) {
7160 struct case_t *cr = tcc_malloc(sizeof(struct case_t));
7161 if (!cur_switch)
7162 expect("switch");
7163 cr->v1 = cr->v2 = expr_const64();
7164 if (gnu_ext && tok == TOK_DOTS) {
7165 next();
7166 cr->v2 = expr_const64();
7167 if ((!(cur_switch->sv.type.t & VT_UNSIGNED) && cr->v2 < cr->v1)
7168 || (cur_switch->sv.type.t & VT_UNSIGNED && (uint64_t)cr->v2 < (uint64_t)cr->v1))
7169 tcc_warning("empty case range");
7171 cr->sym = gind();
7172 dynarray_add(&cur_switch->p, &cur_switch->n, cr);
7173 skip(':');
7174 is_expr = 0;
7175 goto block_after_label;
7177 } else if (t == TOK_DEFAULT) {
7178 if (!cur_switch)
7179 expect("switch");
7180 if (cur_switch->def_sym)
7181 tcc_error("too many 'default'");
7182 cur_switch->def_sym = gind();
7183 skip(':');
7184 is_expr = 0;
7185 goto block_after_label;
7187 } else if (t == TOK_GOTO) {
7188 vla_restore(root_scope->vla.loc);
7189 if (tok == '*' && gnu_ext) {
7190 /* computed goto */
7191 next();
7192 gexpr();
7193 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
7194 expect("pointer");
7195 ggoto();
7197 } else if (tok >= TOK_UIDENT) {
7198 s = label_find(tok);
7199 /* put forward definition if needed */
7200 if (!s)
7201 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
7202 else if (s->r == LABEL_DECLARED)
7203 s->r = LABEL_FORWARD;
7205 if (s->r & LABEL_FORWARD) {
7206 /* start new goto chain for cleanups, linked via label->next */
7207 if (cur_scope->cl.s && !nocode_wanted) {
7208 sym_push2(&pending_gotos, SYM_FIELD, 0, cur_scope->cl.n);
7209 pending_gotos->prev_tok = s;
7210 s = sym_push2(&s->next, SYM_FIELD, 0, 0);
7211 pending_gotos->next = s;
7213 s->jnext = gjmp(s->jnext);
7214 } else {
7215 try_call_cleanup_goto(s->cleanupstate);
7216 gjmp_addr(s->jnext);
7218 next();
7220 } else {
7221 expect("label identifier");
7223 skip(';');
7225 } else if (t == TOK_ASM1 || t == TOK_ASM2 || t == TOK_ASM3) {
7226 asm_instr();
7228 } else {
7229 if (tok == ':' && t >= TOK_UIDENT) {
7230 /* label case */
7231 next();
7232 s = label_find(t);
7233 if (s) {
7234 if (s->r == LABEL_DEFINED)
7235 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
7236 s->r = LABEL_DEFINED;
7237 if (s->next) {
7238 Sym *pcl; /* pending cleanup goto */
7239 for (pcl = s->next; pcl; pcl = pcl->prev)
7240 gsym(pcl->jnext);
7241 sym_pop(&s->next, NULL, 0);
7242 } else
7243 gsym(s->jnext);
7244 } else {
7245 s = label_push(&global_label_stack, t, LABEL_DEFINED);
7247 s->jnext = gind();
7248 s->cleanupstate = cur_scope->cl.s;
7250 block_after_label:
7251 vla_restore(cur_scope->vla.loc);
7252 /* we accept this, but it is a mistake */
7253 if (tok == '}') {
7254 tcc_warning("deprecated use of label at end of compound statement");
7255 } else {
7256 goto again;
7259 } else {
7260 /* expression case */
7261 if (t != ';') {
7262 unget_tok(t);
7263 expr:
7264 if (is_expr) {
7265 vpop();
7266 gexpr();
7267 } else {
7268 gexpr();
7269 vpop();
7271 skip(';');
7277 /* This skips over a stream of tokens containing balanced {} and ()
7278 pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started
7279 with a '{'). If STR then allocates and stores the skipped tokens
7280 in *STR. This doesn't check if () and {} are nested correctly,
7281 i.e. "({)}" is accepted. */
7282 static void skip_or_save_block(TokenString **str)
7284 int braces = tok == '{';
7285 int level = 0;
7286 if (str)
7287 *str = tok_str_alloc();
7289 while ((level > 0 || (tok != '}' && tok != ',' && tok != ';' && tok != ')'))) {
7290 int t;
7291 if (tok == TOK_EOF) {
7292 if (str || level > 0)
7293 tcc_error("unexpected end of file");
7294 else
7295 break;
7297 if (str)
7298 tok_str_add_tok(*str);
7299 t = tok;
7300 next();
7301 if (t == '{' || t == '(') {
7302 level++;
7303 } else if (t == '}' || t == ')') {
7304 level--;
7305 if (level == 0 && braces && t == '}')
7306 break;
7309 if (str) {
7310 tok_str_add(*str, -1);
7311 tok_str_add(*str, 0);
7315 #define EXPR_CONST 1
7316 #define EXPR_ANY 2
7318 static void parse_init_elem(int expr_type)
7320 int saved_global_expr;
7321 switch(expr_type) {
7322 case EXPR_CONST:
7323 /* compound literals must be allocated globally in this case */
7324 saved_global_expr = global_expr;
7325 global_expr = 1;
7326 expr_const1();
7327 global_expr = saved_global_expr;
7328 /* NOTE: symbols are accepted, as well as lvalue for anon symbols
7329 (compound literals). */
7330 if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST
7331 && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL)
7332 || vtop->sym->v < SYM_FIRST_ANOM))
7333 #ifdef TCC_TARGET_PE
7334 || ((vtop->r & VT_SYM) && vtop->sym->a.dllimport)
7335 #endif
7337 tcc_error("initializer element is not constant");
7338 break;
7339 case EXPR_ANY:
7340 expr_eq();
7341 break;
7345 #if 1
7346 static void init_assert(init_params *p, int offset)
7348 if (p->sec ? !NODATA_WANTED && offset > p->sec->data_offset
7349 : !nocode_wanted && offset > p->local_offset)
7350 tcc_internal_error("initializer overflow");
7352 #else
7353 #define init_assert(sec, offset)
7354 #endif
7356 /* put zeros for variable based init */
7357 static void init_putz(init_params *p, unsigned long c, int size)
7359 init_assert(p, c + size);
7360 if (p->sec) {
7361 /* nothing to do because globals are already set to zero */
7362 } else {
7363 vpush_global_sym(&func_old_type, TOK_memset);
7364 vseti(VT_LOCAL, c);
7365 #ifdef TCC_TARGET_ARM
7366 vpushs(size);
7367 vpushi(0);
7368 #else
7369 vpushi(0);
7370 vpushs(size);
7371 #endif
7372 gfunc_call(3);
7376 #define DIF_FIRST 1
7377 #define DIF_SIZE_ONLY 2
7378 #define DIF_HAVE_ELEM 4
7379 #define DIF_CLEAR 8
7381 /* delete relocations for specified range c ... c + size. Unfortunatly
7382 in very special cases, relocations may occur unordered */
7383 static void decl_design_delrels(Section *sec, int c, int size)
7385 ElfW_Rel *rel, *rel2, *rel_end;
7386 if (!sec || !sec->reloc)
7387 return;
7388 rel = rel2 = (ElfW_Rel*)sec->reloc->data;
7389 rel_end = (ElfW_Rel*)(sec->reloc->data + sec->reloc->data_offset);
7390 while (rel < rel_end) {
7391 if (rel->r_offset >= c && rel->r_offset < c + size) {
7392 sec->reloc->data_offset -= sizeof *rel;
7393 } else {
7394 if (rel2 != rel)
7395 memcpy(rel2, rel, sizeof *rel);
7396 ++rel2;
7398 ++rel;
7402 static void decl_design_flex(init_params *p, Sym *ref, int index)
7404 if (ref == p->flex_array_ref) {
7405 if (index >= ref->c)
7406 ref->c = index + 1;
7407 } else if (ref->c < 0)
7408 tcc_error("flexible array has zero size in this context");
7411 /* t is the array or struct type. c is the array or struct
7412 address. cur_field is the pointer to the current
7413 field, for arrays the 'c' member contains the current start
7414 index. 'flags' is as in decl_initializer.
7415 'al' contains the already initialized length of the
7416 current container (starting at c). This returns the new length of that. */
7417 static int decl_designator(init_params *p, CType *type, unsigned long c,
7418 Sym **cur_field, int flags, int al)
7420 Sym *s, *f;
7421 int index, index_last, align, l, nb_elems, elem_size;
7422 unsigned long corig = c;
7424 elem_size = 0;
7425 nb_elems = 1;
7427 if (flags & DIF_HAVE_ELEM)
7428 goto no_designator;
7430 if (gnu_ext && tok >= TOK_UIDENT) {
7431 l = tok, next();
7432 if (tok == ':')
7433 goto struct_field;
7434 unget_tok(l);
7437 /* NOTE: we only support ranges for last designator */
7438 while (nb_elems == 1 && (tok == '[' || tok == '.')) {
7439 if (tok == '[') {
7440 if (!(type->t & VT_ARRAY))
7441 expect("array type");
7442 next();
7443 index = index_last = expr_const();
7444 if (tok == TOK_DOTS && gnu_ext) {
7445 next();
7446 index_last = expr_const();
7448 skip(']');
7449 s = type->ref;
7450 decl_design_flex(p, s, index_last);
7451 if (index < 0 || index_last >= s->c || index_last < index)
7452 tcc_error("index exceeds array bounds or range is empty");
7453 if (cur_field)
7454 (*cur_field)->c = index_last;
7455 type = pointed_type(type);
7456 elem_size = type_size(type, &align);
7457 c += index * elem_size;
7458 nb_elems = index_last - index + 1;
7459 } else {
7460 int cumofs;
7461 next();
7462 l = tok;
7463 struct_field:
7464 next();
7465 if ((type->t & VT_BTYPE) != VT_STRUCT)
7466 expect("struct/union type");
7467 cumofs = 0;
7468 f = find_field(type, l, &cumofs);
7469 if (!f)
7470 expect("field");
7471 if (cur_field)
7472 *cur_field = f;
7473 type = &f->type;
7474 c += cumofs + f->c;
7476 cur_field = NULL;
7478 if (!cur_field) {
7479 if (tok == '=') {
7480 next();
7481 } else if (!gnu_ext) {
7482 expect("=");
7484 } else {
7485 no_designator:
7486 if (type->t & VT_ARRAY) {
7487 index = (*cur_field)->c;
7488 s = type->ref;
7489 decl_design_flex(p, s, index);
7490 if (index >= s->c)
7491 tcc_error("too many initializers");
7492 type = pointed_type(type);
7493 elem_size = type_size(type, &align);
7494 c += index * elem_size;
7495 } else {
7496 f = *cur_field;
7497 while (f && (f->v & SYM_FIRST_ANOM) && (f->type.t & VT_BITFIELD))
7498 *cur_field = f = f->next;
7499 if (!f)
7500 tcc_error("too many initializers");
7501 type = &f->type;
7502 c += f->c;
7506 if (!elem_size) /* for structs */
7507 elem_size = type_size(type, &align);
7509 /* Using designators the same element can be initialized more
7510 than once. In that case we need to delete possibly already
7511 existing relocations. */
7512 if (!(flags & DIF_SIZE_ONLY) && c - corig < al) {
7513 decl_design_delrels(p->sec, c, elem_size * nb_elems);
7514 flags &= ~DIF_CLEAR; /* mark stack dirty too */
7517 decl_initializer(p, type, c, flags & ~DIF_FIRST);
7519 if (!(flags & DIF_SIZE_ONLY) && nb_elems > 1) {
7520 Sym aref = {0};
7521 CType t1;
7522 int i;
7523 if (p->sec || (type->t & VT_ARRAY)) {
7524 /* make init_putv/vstore believe it were a struct */
7525 aref.c = elem_size;
7526 t1.t = VT_STRUCT, t1.ref = &aref;
7527 type = &t1;
7529 if (p->sec)
7530 vpush_ref(type, p->sec, c, elem_size);
7531 else
7532 vset(type, VT_LOCAL|VT_LVAL, c);
7533 for (i = 1; i < nb_elems; i++) {
7534 vdup();
7535 init_putv(p, type, c + elem_size * i);
7537 vpop();
7540 c += nb_elems * elem_size;
7541 if (c - corig > al)
7542 al = c - corig;
7543 return al;
7546 /* store a value or an expression directly in global data or in local array */
7547 static void init_putv(init_params *p, CType *type, unsigned long c)
7549 int bt;
7550 void *ptr;
7551 CType dtype;
7552 int size, align;
7553 Section *sec = p->sec;
7555 dtype = *type;
7556 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
7558 size = type_size(type, &align);
7559 if (type->t & VT_BITFIELD)
7560 size = (BIT_POS(type->t) + BIT_SIZE(type->t) + 7) / 8;
7561 init_assert(p, c + size);
7563 if (sec) {
7564 /* XXX: not portable */
7565 /* XXX: generate error if incorrect relocation */
7566 gen_assign_cast(&dtype);
7567 bt = type->t & VT_BTYPE;
7569 if ((vtop->r & VT_SYM)
7570 && bt != VT_PTR
7571 && bt != VT_FUNC
7572 && (bt != (PTR_SIZE == 8 ? VT_LLONG : VT_INT)
7573 || (type->t & VT_BITFIELD))
7574 && !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM)
7576 tcc_error("initializer element is not computable at load time");
7578 if (NODATA_WANTED) {
7579 vtop--;
7580 return;
7583 ptr = sec->data + c;
7585 /* XXX: make code faster ? */
7586 if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) &&
7587 vtop->sym->v >= SYM_FIRST_ANOM &&
7588 /* XXX This rejects compound literals like
7589 '(void *){ptr}'. The problem is that '&sym' is
7590 represented the same way, which would be ruled out
7591 by the SYM_FIRST_ANOM check above, but also '"string"'
7592 in 'char *p = "string"' is represented the same
7593 with the type being VT_PTR and the symbol being an
7594 anonymous one. That is, there's no difference in vtop
7595 between '(void *){x}' and '&(void *){x}'. Ignore
7596 pointer typed entities here. Hopefully no real code
7597 will ever use compound literals with scalar type. */
7598 (vtop->type.t & VT_BTYPE) != VT_PTR) {
7599 /* These come from compound literals, memcpy stuff over. */
7600 Section *ssec;
7601 ElfSym *esym;
7602 ElfW_Rel *rel;
7603 esym = elfsym(vtop->sym);
7604 ssec = tcc_state->sections[esym->st_shndx];
7605 memmove (ptr, ssec->data + esym->st_value + (int)vtop->c.i, size);
7606 if (ssec->reloc) {
7607 /* We need to copy over all memory contents, and that
7608 includes relocations. Use the fact that relocs are
7609 created it order, so look from the end of relocs
7610 until we hit one before the copied region. */
7611 int num_relocs = ssec->reloc->data_offset / sizeof(*rel);
7612 rel = (ElfW_Rel*)(ssec->reloc->data + ssec->reloc->data_offset);
7613 while (num_relocs--) {
7614 rel--;
7615 if (rel->r_offset >= esym->st_value + size)
7616 continue;
7617 if (rel->r_offset < esym->st_value)
7618 break;
7619 put_elf_reloca(symtab_section, sec,
7620 c + rel->r_offset - esym->st_value,
7621 ELFW(R_TYPE)(rel->r_info),
7622 ELFW(R_SYM)(rel->r_info),
7623 #if PTR_SIZE == 8
7624 rel->r_addend
7625 #else
7627 #endif
7631 } else {
7632 if (type->t & VT_BITFIELD) {
7633 int bit_pos, bit_size, bits, n;
7634 unsigned char *p, v, m;
7635 bit_pos = BIT_POS(vtop->type.t);
7636 bit_size = BIT_SIZE(vtop->type.t);
7637 p = (unsigned char*)ptr + (bit_pos >> 3);
7638 bit_pos &= 7, bits = 0;
7639 while (bit_size) {
7640 n = 8 - bit_pos;
7641 if (n > bit_size)
7642 n = bit_size;
7643 v = vtop->c.i >> bits << bit_pos;
7644 m = ((1 << n) - 1) << bit_pos;
7645 *p = (*p & ~m) | (v & m);
7646 bits += n, bit_size -= n, bit_pos = 0, ++p;
7648 } else
7649 switch(bt) {
7650 /* XXX: when cross-compiling we assume that each type has the
7651 same representation on host and target, which is likely to
7652 be wrong in the case of long double */
7653 case VT_BOOL:
7654 vtop->c.i = vtop->c.i != 0;
7655 case VT_BYTE:
7656 *(char *)ptr = vtop->c.i;
7657 break;
7658 case VT_SHORT:
7659 *(short *)ptr = vtop->c.i;
7660 break;
7661 case VT_FLOAT:
7662 *(float*)ptr = vtop->c.f;
7663 break;
7664 case VT_DOUBLE:
7665 *(double *)ptr = vtop->c.d;
7666 break;
7667 case VT_LDOUBLE:
7668 #if defined TCC_IS_NATIVE_387
7669 if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
7670 memcpy(ptr, &vtop->c.ld, 10);
7671 #ifdef __TINYC__
7672 else if (sizeof (long double) == sizeof (double))
7673 __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld));
7674 #endif
7675 else if (vtop->c.ld == 0.0)
7677 else
7678 #endif
7679 if (sizeof(long double) == LDOUBLE_SIZE)
7680 *(long double*)ptr = vtop->c.ld;
7681 else if (sizeof(double) == LDOUBLE_SIZE)
7682 *(double *)ptr = (double)vtop->c.ld;
7683 else
7684 tcc_error("can't cross compile long double constants");
7685 break;
7686 #if PTR_SIZE != 8
7687 case VT_LLONG:
7688 *(long long *)ptr = vtop->c.i;
7689 break;
7690 #else
7691 case VT_LLONG:
7692 #endif
7693 case VT_PTR:
7695 addr_t val = vtop->c.i;
7696 #if PTR_SIZE == 8
7697 if (vtop->r & VT_SYM)
7698 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
7699 else
7700 *(addr_t *)ptr = val;
7701 #else
7702 if (vtop->r & VT_SYM)
7703 greloc(sec, vtop->sym, c, R_DATA_PTR);
7704 *(addr_t *)ptr = val;
7705 #endif
7706 break;
7708 default:
7710 int val = vtop->c.i;
7711 #if PTR_SIZE == 8
7712 if (vtop->r & VT_SYM)
7713 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
7714 else
7715 *(int *)ptr = val;
7716 #else
7717 if (vtop->r & VT_SYM)
7718 greloc(sec, vtop->sym, c, R_DATA_PTR);
7719 *(int *)ptr = val;
7720 #endif
7721 break;
7725 vtop--;
7726 } else {
7727 vset(&dtype, VT_LOCAL|VT_LVAL, c);
7728 vswap();
7729 vstore();
7730 vpop();
7734 /* 't' contains the type and storage info. 'c' is the offset of the
7735 object in section 'sec'. If 'sec' is NULL, it means stack based
7736 allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi
7737 dimension implicit array init handling). 'flags & DIF_SIZE_ONLY' is true if
7738 size only evaluation is wanted (only for arrays). */
7739 static void decl_initializer(init_params *p, CType *type, unsigned long c, int flags)
7741 int len, n, no_oblock, i;
7742 int size1, align1;
7743 Sym *s, *f;
7744 Sym indexsym;
7745 CType *t1;
7747 /* generate line number info */
7748 if (!p->sec && tcc_state->do_debug)
7749 tcc_debug_line(tcc_state);
7751 if (!(flags & DIF_HAVE_ELEM) && tok != '{' &&
7752 /* In case of strings we have special handling for arrays, so
7753 don't consume them as initializer value (which would commit them
7754 to some anonymous symbol). */
7755 tok != TOK_LSTR && tok != TOK_STR &&
7756 !(flags & DIF_SIZE_ONLY)) {
7757 parse_init_elem(!p->sec ? EXPR_ANY : EXPR_CONST);
7758 flags |= DIF_HAVE_ELEM;
7761 if ((flags & DIF_HAVE_ELEM) &&
7762 !(type->t & VT_ARRAY) &&
7763 /* Use i_c_parameter_t, to strip toplevel qualifiers.
7764 The source type might have VT_CONSTANT set, which is
7765 of course assignable to non-const elements. */
7766 is_compatible_unqualified_types(type, &vtop->type)) {
7767 goto init_putv;
7769 } else if (type->t & VT_ARRAY) {
7770 no_oblock = 1;
7771 if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) ||
7772 tok == '{') {
7773 skip('{');
7774 no_oblock = 0;
7777 s = type->ref;
7778 n = s->c;
7779 t1 = pointed_type(type);
7780 size1 = type_size(t1, &align1);
7782 /* only parse strings here if correct type (otherwise: handle
7783 them as ((w)char *) expressions */
7784 if ((tok == TOK_LSTR &&
7785 #ifdef TCC_TARGET_PE
7786 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
7787 #else
7788 (t1->t & VT_BTYPE) == VT_INT
7789 #endif
7790 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
7791 len = 0;
7792 cstr_reset(&initstr);
7793 if (size1 != (tok == TOK_STR ? 1 : sizeof(nwchar_t)))
7794 tcc_error("unhandled string literal merging");
7795 while (tok == TOK_STR || tok == TOK_LSTR) {
7796 if (initstr.size)
7797 initstr.size -= size1;
7798 if (tok == TOK_STR)
7799 len += tokc.str.size;
7800 else
7801 len += tokc.str.size / sizeof(nwchar_t);
7802 len--;
7803 cstr_cat(&initstr, tokc.str.data, tokc.str.size);
7804 next();
7806 if (tok != ')' && tok != '}' && tok != ',' && tok != ';'
7807 && tok != TOK_EOF) {
7808 /* Not a lone literal but part of a bigger expression. */
7809 unget_tok(size1 == 1 ? TOK_STR : TOK_LSTR);
7810 tokc.str.size = initstr.size;
7811 tokc.str.data = initstr.data;
7812 goto do_init_array;
7815 if (!(flags & DIF_SIZE_ONLY)) {
7816 int nb = n;
7817 if (len < nb)
7818 nb = len;
7819 if (len > nb)
7820 tcc_warning("initializer-string for array is too long");
7821 /* in order to go faster for common case (char
7822 string in global variable, we handle it
7823 specifically */
7824 if (p->sec && size1 == 1) {
7825 init_assert(p, c + nb);
7826 if (!NODATA_WANTED)
7827 memcpy(p->sec->data + c, initstr.data, nb);
7828 } else {
7829 for(i=0;i<n;i++) {
7830 if (i >= nb) {
7831 /* only add trailing zero if enough storage (no
7832 warning in this case since it is standard) */
7833 if (flags & DIF_CLEAR)
7834 break;
7835 if (n - i >= 4) {
7836 init_putz(p, c + i * size1, (n - i) * size1);
7837 break;
7839 ch = 0;
7840 } else if (size1 == 1)
7841 ch = ((unsigned char *)initstr.data)[i];
7842 else
7843 ch = ((nwchar_t *)initstr.data)[i];
7844 vpushi(ch);
7845 init_putv(p, t1, c + i * size1);
7848 } else {
7849 decl_design_flex(p, s, len);
7851 } else {
7853 do_init_array:
7854 indexsym.c = 0;
7855 f = &indexsym;
7857 do_init_list:
7858 /* zero memory once in advance */
7859 if (!(flags & (DIF_CLEAR | DIF_SIZE_ONLY))) {
7860 init_putz(p, c, n*size1);
7861 flags |= DIF_CLEAR;
7864 len = 0;
7865 while (tok != '}' || (flags & DIF_HAVE_ELEM)) {
7866 len = decl_designator(p, type, c, &f, flags, len);
7867 flags &= ~DIF_HAVE_ELEM;
7868 if (type->t & VT_ARRAY) {
7869 ++indexsym.c;
7870 /* special test for multi dimensional arrays (may not
7871 be strictly correct if designators are used at the
7872 same time) */
7873 if (no_oblock && len >= n*size1)
7874 break;
7875 } else {
7876 if (s->type.t == VT_UNION)
7877 f = NULL;
7878 else
7879 f = f->next;
7880 if (no_oblock && f == NULL)
7881 break;
7884 if (tok == '}')
7885 break;
7886 skip(',');
7889 if (!no_oblock)
7890 skip('}');
7891 } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
7892 no_oblock = 1;
7893 if ((flags & DIF_FIRST) || tok == '{') {
7894 skip('{');
7895 no_oblock = 0;
7897 s = type->ref;
7898 f = s->next;
7899 n = s->c;
7900 size1 = 1;
7901 goto do_init_list;
7902 } else if (tok == '{') {
7903 if (flags & DIF_HAVE_ELEM)
7904 skip(';');
7905 next();
7906 decl_initializer(p, type, c, flags & ~DIF_HAVE_ELEM);
7907 skip('}');
7908 } else if ((flags & DIF_SIZE_ONLY)) {
7909 /* If we supported only ISO C we wouldn't have to accept calling
7910 this on anything than an array if DIF_SIZE_ONLY (and even then
7911 only on the outermost level, so no recursion would be needed),
7912 because initializing a flex array member isn't supported.
7913 But GNU C supports it, so we need to recurse even into
7914 subfields of structs and arrays when DIF_SIZE_ONLY is set. */
7915 /* just skip expression */
7916 skip_or_save_block(NULL);
7917 } else {
7918 if (!(flags & DIF_HAVE_ELEM)) {
7919 /* This should happen only when we haven't parsed
7920 the init element above for fear of committing a
7921 string constant to memory too early. */
7922 if (tok != TOK_STR && tok != TOK_LSTR)
7923 expect("string constant");
7924 parse_init_elem(!p->sec ? EXPR_ANY : EXPR_CONST);
7926 init_putv:
7927 if (!p->sec && (flags & DIF_CLEAR) /* container was already zero'd */
7928 && (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST
7929 && vtop->c.i == 0
7930 && btype_size(type->t & VT_BTYPE) /* not for fp constants */
7932 vpop();
7933 else
7934 init_putv(p, type, c);
7938 /* parse an initializer for type 't' if 'has_init' is non zero, and
7939 allocate space in local or global data space ('r' is either
7940 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7941 variable 'v' of scope 'scope' is declared before initializers
7942 are parsed. If 'v' is zero, then a reference to the new object
7943 is put in the value stack. If 'has_init' is 2, a special parsing
7944 is done to handle string constants. */
7945 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
7946 int has_init, int v, int scope)
7948 int size, align, addr;
7949 TokenString *init_str = NULL;
7951 Section *sec;
7952 Sym *flexible_array;
7953 Sym *sym = NULL;
7954 int saved_nocode_wanted = nocode_wanted;
7955 #ifdef CONFIG_TCC_BCHECK
7956 int bcheck = tcc_state->do_bounds_check && !NODATA_WANTED;
7957 #endif
7958 init_params p = {0};
7960 /* Always allocate static or global variables */
7961 if (v && (r & VT_VALMASK) == VT_CONST)
7962 nocode_wanted |= 0x80000000;
7964 flexible_array = NULL;
7965 size = type_size(type, &align);
7967 /* exactly one flexible array may be initialized, either the
7968 toplevel array or the last member of the toplevel struct */
7970 if (size < 0) {
7971 /* If the base type itself was an array type of unspecified size
7972 (like in 'typedef int arr[]; arr x = {1};') then we will
7973 overwrite the unknown size by the real one for this decl.
7974 We need to unshare the ref symbol holding that size. */
7975 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
7976 p.flex_array_ref = type->ref;
7978 } else if (has_init && (type->t & VT_BTYPE) == VT_STRUCT) {
7979 Sym *field = type->ref->next;
7980 if (field) {
7981 while (field->next)
7982 field = field->next;
7983 if (field->type.t & VT_ARRAY && field->type.ref->c < 0) {
7984 flexible_array = field;
7985 p.flex_array_ref = field->type.ref;
7986 size = -1;
7991 if (size < 0) {
7992 /* If unknown size, do a dry-run 1st pass */
7993 if (!has_init)
7994 tcc_error("unknown type size");
7995 if (has_init == 2) {
7996 /* only get strings */
7997 init_str = tok_str_alloc();
7998 while (tok == TOK_STR || tok == TOK_LSTR) {
7999 tok_str_add_tok(init_str);
8000 next();
8002 tok_str_add(init_str, -1);
8003 tok_str_add(init_str, 0);
8004 } else
8005 skip_or_save_block(&init_str);
8006 unget_tok(0);
8008 /* compute size */
8009 begin_macro(init_str, 1);
8010 next();
8011 decl_initializer(&p, type, 0, DIF_FIRST | DIF_SIZE_ONLY);
8012 /* prepare second initializer parsing */
8013 macro_ptr = init_str->str;
8014 next();
8016 /* if still unknown size, error */
8017 size = type_size(type, &align);
8018 if (size < 0)
8019 tcc_error("unknown type size");
8021 /* If there's a flex member and it was used in the initializer
8022 adjust size. */
8023 if (flexible_array && flexible_array->type.ref->c > 0)
8024 size += flexible_array->type.ref->c
8025 * pointed_size(&flexible_array->type);
8028 /* take into account specified alignment if bigger */
8029 if (ad->a.aligned) {
8030 int speca = 1 << (ad->a.aligned - 1);
8031 if (speca > align)
8032 align = speca;
8033 } else if (ad->a.packed) {
8034 align = 1;
8037 if (!v && NODATA_WANTED)
8038 size = 0, align = 1;
8040 if ((r & VT_VALMASK) == VT_LOCAL) {
8041 sec = NULL;
8042 #ifdef CONFIG_TCC_BCHECK
8043 if (bcheck && v) {
8044 /* add padding between stack variables for bound checking */
8045 loc--;
8047 #endif
8048 loc = (loc - size) & -align;
8049 addr = loc;
8050 p.local_offset = addr + size;
8051 #ifdef CONFIG_TCC_BCHECK
8052 if (bcheck && v) {
8053 /* add padding between stack variables for bound checking */
8054 loc--;
8056 #endif
8057 if (v) {
8058 /* local variable */
8059 #ifdef CONFIG_TCC_ASM
8060 if (ad->asm_label) {
8061 int reg = asm_parse_regvar(ad->asm_label);
8062 if (reg >= 0)
8063 r = (r & ~VT_VALMASK) | reg;
8065 #endif
8066 sym = sym_push(v, type, r, addr);
8067 if (ad->cleanup_func) {
8068 Sym *cls = sym_push2(&all_cleanups,
8069 SYM_FIELD | ++cur_scope->cl.n, 0, 0);
8070 cls->prev_tok = sym;
8071 cls->next = ad->cleanup_func;
8072 cls->ncl = cur_scope->cl.s;
8073 cur_scope->cl.s = cls;
8076 sym->a = ad->a;
8077 } else {
8078 /* push local reference */
8079 vset(type, r, addr);
8081 } else {
8082 if (v && scope == VT_CONST) {
8083 /* see if the symbol was already defined */
8084 sym = sym_find(v);
8085 if (sym) {
8086 patch_storage(sym, ad, type);
8087 /* we accept several definitions of the same global variable. */
8088 if (!has_init && sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)
8089 goto no_alloc;
8093 /* allocate symbol in corresponding section */
8094 sec = ad->section;
8095 if (!sec) {
8096 if (has_init)
8097 sec = data_section;
8098 else if (tcc_state->nocommon)
8099 sec = bss_section;
8102 if (sec) {
8103 addr = section_add(sec, size, align);
8104 #ifdef CONFIG_TCC_BCHECK
8105 /* add padding if bound check */
8106 if (bcheck)
8107 section_add(sec, 1, 1);
8108 #endif
8109 } else {
8110 addr = align; /* SHN_COMMON is special, symbol value is align */
8111 sec = common_section;
8114 if (v) {
8115 if (!sym) {
8116 sym = sym_push(v, type, r | VT_SYM, 0);
8117 patch_storage(sym, ad, NULL);
8119 /* update symbol definition */
8120 put_extern_sym(sym, sec, addr, size);
8121 } else {
8122 /* push global reference */
8123 vpush_ref(type, sec, addr, size);
8124 sym = vtop->sym;
8125 vtop->r |= r;
8128 #ifdef CONFIG_TCC_BCHECK
8129 /* handles bounds now because the symbol must be defined
8130 before for the relocation */
8131 if (bcheck) {
8132 addr_t *bounds_ptr;
8134 greloca(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR, 0);
8135 /* then add global bound info */
8136 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
8137 bounds_ptr[0] = 0; /* relocated */
8138 bounds_ptr[1] = size;
8140 #endif
8143 if (type->t & VT_VLA) {
8144 int a;
8146 if (NODATA_WANTED)
8147 goto no_alloc;
8149 /* save current stack pointer */
8150 if (root_scope->vla.loc == 0) {
8151 struct scope *v = cur_scope;
8152 gen_vla_sp_save(loc -= PTR_SIZE);
8153 do v->vla.loc = loc; while ((v = v->prev));
8156 vla_runtime_type_size(type, &a);
8157 gen_vla_alloc(type, a);
8158 #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
8159 /* on _WIN64, because of the function args scratch area, the
8160 result of alloca differs from RSP and is returned in RAX. */
8161 gen_vla_result(addr), addr = (loc -= PTR_SIZE);
8162 #endif
8163 gen_vla_sp_save(addr);
8164 cur_scope->vla.loc = addr;
8165 cur_scope->vla.num++;
8166 } else if (has_init) {
8167 p.sec = sec;
8168 decl_initializer(&p, type, addr, DIF_FIRST);
8169 /* patch flexible array member size back to -1, */
8170 /* for possible subsequent similar declarations */
8171 if (flexible_array)
8172 flexible_array->type.ref->c = -1;
8175 no_alloc:
8176 /* restore parse state if needed */
8177 if (init_str) {
8178 end_macro();
8179 next();
8182 nocode_wanted = saved_nocode_wanted;
8185 /* parse a function defined by symbol 'sym' and generate its code in
8186 'cur_text_section' */
8187 static void gen_function(Sym *sym)
8189 struct scope f = { 0 };
8190 cur_scope = root_scope = &f;
8191 nocode_wanted = 0;
8192 ind = cur_text_section->data_offset;
8193 if (sym->a.aligned) {
8194 size_t newoff = section_add(cur_text_section, 0,
8195 1 << (sym->a.aligned - 1));
8196 gen_fill_nops(newoff - ind);
8198 /* NOTE: we patch the symbol size later */
8199 put_extern_sym(sym, cur_text_section, ind, 0);
8200 if (sym->type.ref->f.func_ctor)
8201 add_array (tcc_state, ".init_array", sym->c);
8202 if (sym->type.ref->f.func_dtor)
8203 add_array (tcc_state, ".fini_array", sym->c);
8205 funcname = get_tok_str(sym->v, NULL);
8206 func_ind = ind;
8207 func_vt = sym->type.ref->type;
8208 func_var = sym->type.ref->f.func_type == FUNC_ELLIPSIS;
8210 /* put debug symbol */
8211 tcc_debug_funcstart(tcc_state, sym);
8212 /* push a dummy symbol to enable local sym storage */
8213 sym_push2(&local_stack, SYM_FIELD, 0, 0);
8214 local_scope = 1; /* for function parameters */
8215 gfunc_prolog(sym);
8216 local_scope = 0;
8217 rsym = 0;
8218 clear_temp_local_var_list();
8219 block(0);
8220 gsym(rsym);
8221 nocode_wanted = 0;
8222 /* reset local stack */
8223 pop_local_syms(&local_stack, NULL, 0, func_var);
8224 gfunc_epilog();
8225 cur_text_section->data_offset = ind;
8226 local_scope = 0;
8227 label_pop(&global_label_stack, NULL, 0);
8228 sym_pop(&all_cleanups, NULL, 0);
8229 /* patch symbol size */
8230 elfsym(sym)->st_size = ind - func_ind;
8231 /* end of function */
8232 tcc_debug_funcend(tcc_state, ind - func_ind);
8233 /* It's better to crash than to generate wrong code */
8234 cur_text_section = NULL;
8235 funcname = ""; /* for safety */
8236 func_vt.t = VT_VOID; /* for safety */
8237 func_var = 0; /* for safety */
8238 ind = 0; /* for safety */
8239 nocode_wanted = 0x80000000;
8240 check_vstack();
8241 /* do this after funcend debug info */
8242 next();
8245 static void gen_inline_functions(TCCState *s)
8247 Sym *sym;
8248 int inline_generated, i;
8249 struct InlineFunc *fn;
8251 tcc_open_bf(s, ":inline:", 0);
8252 /* iterate while inline function are referenced */
8253 do {
8254 inline_generated = 0;
8255 for (i = 0; i < s->nb_inline_fns; ++i) {
8256 fn = s->inline_fns[i];
8257 sym = fn->sym;
8258 if (sym && (sym->c || !(sym->type.t & VT_INLINE))) {
8259 /* the function was used or forced (and then not internal):
8260 generate its code and convert it to a normal function */
8261 fn->sym = NULL;
8262 tcc_debug_putfile(s, fn->filename);
8263 begin_macro(fn->func_str, 1);
8264 next();
8265 cur_text_section = text_section;
8266 gen_function(sym);
8267 end_macro();
8269 inline_generated = 1;
8272 } while (inline_generated);
8273 tcc_close();
8276 static void free_inline_functions(TCCState *s)
8278 int i;
8279 /* free tokens of unused inline functions */
8280 for (i = 0; i < s->nb_inline_fns; ++i) {
8281 struct InlineFunc *fn = s->inline_fns[i];
8282 if (fn->sym)
8283 tok_str_free(fn->func_str);
8285 dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
8288 /* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
8289 if parsing old style parameter decl list (and FUNC_SYM is set then) */
8290 static int decl0(int l, int is_for_loop_init, Sym *func_sym)
8292 int v, has_init, r, oldint;
8293 CType type, btype;
8294 Sym *sym;
8295 AttributeDef ad, adbase;
8297 while (1) {
8298 if (tok == TOK_STATIC_ASSERT) {
8299 CString error_str;
8300 int c;
8302 next();
8303 skip('(');
8304 c = expr_const();
8306 if (tok == ')') {
8307 if (!c)
8308 tcc_error("_Static_assert fail");
8309 next();
8310 goto static_assert_out;
8313 skip(',');
8314 parse_mult_str(&error_str, "string constant");
8315 if (c == 0)
8316 tcc_error("%s", (char *)error_str.data);
8317 cstr_free(&error_str);
8318 skip(')');
8319 static_assert_out:
8320 skip(';');
8321 continue;
8324 oldint = 0;
8325 if (!parse_btype(&btype, &adbase)) {
8326 if (is_for_loop_init)
8327 return 0;
8328 /* skip redundant ';' if not in old parameter decl scope */
8329 if (tok == ';' && l != VT_CMP) {
8330 next();
8331 continue;
8333 if (l != VT_CONST)
8334 break;
8335 if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
8336 /* global asm block */
8337 asm_global_instr();
8338 continue;
8340 if (tok >= TOK_UIDENT) {
8341 /* special test for old K&R protos without explicit int
8342 type. Only accepted when defining global data */
8343 btype.t = VT_INT;
8344 oldint = 1;
8345 } else {
8346 if (tok != TOK_EOF)
8347 expect("declaration");
8348 break;
8352 if (tok == ';') {
8353 if ((btype.t & VT_BTYPE) == VT_STRUCT) {
8354 v = btype.ref->v;
8355 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
8356 tcc_warning("unnamed struct/union that defines no instances");
8357 next();
8358 continue;
8360 if (IS_ENUM(btype.t)) {
8361 next();
8362 continue;
8366 while (1) { /* iterate thru each declaration */
8367 type = btype;
8368 ad = adbase;
8369 type_decl(&type, &ad, &v, TYPE_DIRECT);
8370 #if 0
8372 char buf[500];
8373 type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL));
8374 printf("type = '%s'\n", buf);
8376 #endif
8377 if ((type.t & VT_BTYPE) == VT_FUNC) {
8378 if ((type.t & VT_STATIC) && (l == VT_LOCAL))
8379 tcc_error("function without file scope cannot be static");
8380 /* if old style function prototype, we accept a
8381 declaration list */
8382 sym = type.ref;
8383 if (sym->f.func_type == FUNC_OLD && l == VT_CONST)
8384 decl0(VT_CMP, 0, sym);
8385 #ifdef TCC_TARGET_MACHO
8386 if (sym->f.func_alwinl
8387 && ((type.t & (VT_EXTERN | VT_INLINE))
8388 == (VT_EXTERN | VT_INLINE))) {
8389 /* always_inline functions must be handled as if they
8390 don't generate multiple global defs, even if extern
8391 inline, i.e. GNU inline semantics for those. Rewrite
8392 them into static inline. */
8393 type.t &= ~VT_EXTERN;
8394 type.t |= VT_STATIC;
8396 #endif
8397 /* always compile 'extern inline' */
8398 if (type.t & VT_EXTERN)
8399 type.t &= ~VT_INLINE;
8401 } else if (oldint) {
8402 tcc_warning("type defaults to int");
8405 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
8406 ad.asm_label = asm_label_instr();
8407 /* parse one last attribute list, after asm label */
8408 parse_attribute(&ad);
8409 #if 0
8410 /* gcc does not allow __asm__("label") with function definition,
8411 but why not ... */
8412 if (tok == '{')
8413 expect(";");
8414 #endif
8417 #ifdef TCC_TARGET_PE
8418 if (ad.a.dllimport || ad.a.dllexport) {
8419 if (type.t & VT_STATIC)
8420 tcc_error("cannot have dll linkage with static");
8421 if (type.t & VT_TYPEDEF) {
8422 tcc_warning("'%s' attribute ignored for typedef",
8423 ad.a.dllimport ? (ad.a.dllimport = 0, "dllimport") :
8424 (ad.a.dllexport = 0, "dllexport"));
8425 } else if (ad.a.dllimport) {
8426 if ((type.t & VT_BTYPE) == VT_FUNC)
8427 ad.a.dllimport = 0;
8428 else
8429 type.t |= VT_EXTERN;
8432 #endif
8433 if (tok == '{') {
8434 if (l != VT_CONST)
8435 tcc_error("cannot use local functions");
8436 if ((type.t & VT_BTYPE) != VT_FUNC)
8437 expect("function definition");
8439 /* reject abstract declarators in function definition
8440 make old style params without decl have int type */
8441 sym = type.ref;
8442 while ((sym = sym->next) != NULL) {
8443 if (!(sym->v & ~SYM_FIELD))
8444 expect("identifier");
8445 if (sym->type.t == VT_VOID)
8446 sym->type = int_type;
8449 /* apply post-declaraton attributes */
8450 merge_funcattr(&type.ref->f, &ad.f);
8452 /* put function symbol */
8453 type.t &= ~VT_EXTERN;
8454 sym = external_sym(v, &type, 0, &ad);
8456 /* static inline functions are just recorded as a kind
8457 of macro. Their code will be emitted at the end of
8458 the compilation unit only if they are used */
8459 if (sym->type.t & VT_INLINE) {
8460 struct InlineFunc *fn;
8461 fn = tcc_malloc(sizeof *fn + strlen(file->filename));
8462 strcpy(fn->filename, file->filename);
8463 fn->sym = sym;
8464 skip_or_save_block(&fn->func_str);
8465 dynarray_add(&tcc_state->inline_fns,
8466 &tcc_state->nb_inline_fns, fn);
8467 } else {
8468 /* compute text section */
8469 cur_text_section = ad.section;
8470 if (!cur_text_section)
8471 cur_text_section = text_section;
8472 gen_function(sym);
8474 break;
8475 } else {
8476 if (l == VT_CMP) {
8477 /* find parameter in function parameter list */
8478 for (sym = func_sym->next; sym; sym = sym->next)
8479 if ((sym->v & ~SYM_FIELD) == v)
8480 goto found;
8481 tcc_error("declaration for parameter '%s' but no such parameter",
8482 get_tok_str(v, NULL));
8483 found:
8484 if (type.t & VT_STORAGE) /* 'register' is okay */
8485 tcc_error("storage class specified for '%s'",
8486 get_tok_str(v, NULL));
8487 if (sym->type.t != VT_VOID)
8488 tcc_error("redefinition of parameter '%s'",
8489 get_tok_str(v, NULL));
8490 convert_parameter_type(&type);
8491 sym->type = type;
8492 } else if (type.t & VT_TYPEDEF) {
8493 /* save typedefed type */
8494 /* XXX: test storage specifiers ? */
8495 sym = sym_find(v);
8496 if (sym && sym->sym_scope == local_scope) {
8497 if (!is_compatible_types(&sym->type, &type)
8498 || !(sym->type.t & VT_TYPEDEF))
8499 tcc_error("incompatible redefinition of '%s'",
8500 get_tok_str(v, NULL));
8501 sym->type = type;
8502 } else {
8503 sym = sym_push(v, &type, 0, 0);
8505 sym->a = ad.a;
8506 sym->f = ad.f;
8507 if (tcc_state->do_debug)
8508 tcc_debug_typedef (tcc_state, sym);
8509 } else if ((type.t & VT_BTYPE) == VT_VOID
8510 && !(type.t & VT_EXTERN)) {
8511 tcc_error("declaration of void object");
8512 } else {
8513 r = 0;
8514 if ((type.t & VT_BTYPE) == VT_FUNC) {
8515 /* external function definition */
8516 /* specific case for func_call attribute */
8517 type.ref->f = ad.f;
8518 } else if (!(type.t & VT_ARRAY)) {
8519 /* not lvalue if array */
8520 r |= VT_LVAL;
8522 has_init = (tok == '=');
8523 if (has_init && (type.t & VT_VLA))
8524 tcc_error("variable length array cannot be initialized");
8525 if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST))
8526 || (type.t & VT_BTYPE) == VT_FUNC
8527 /* as with GCC, uninitialized global arrays with no size
8528 are considered extern: */
8529 || ((type.t & VT_ARRAY) && !has_init
8530 && l == VT_CONST && type.ref->c < 0)
8532 /* external variable or function */
8533 type.t |= VT_EXTERN;
8534 sym = external_sym(v, &type, r, &ad);
8535 if (ad.alias_target) {
8536 /* Aliases need to be emitted when their target
8537 symbol is emitted, even if perhaps unreferenced.
8538 We only support the case where the base is
8539 already defined, otherwise we would need
8540 deferring to emit the aliases until the end of
8541 the compile unit. */
8542 Sym *alias_target = sym_find(ad.alias_target);
8543 ElfSym *esym = elfsym(alias_target);
8544 if (!esym)
8545 tcc_error("unsupported forward __alias__ attribute");
8546 put_extern_sym2(sym, esym->st_shndx,
8547 esym->st_value, esym->st_size, 1);
8549 } else {
8550 if (type.t & VT_STATIC)
8551 r |= VT_CONST;
8552 else
8553 r |= l;
8554 if (has_init)
8555 next();
8556 else if (l == VT_CONST)
8557 /* uninitialized global variables may be overridden */
8558 type.t |= VT_EXTERN;
8559 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
8562 if (tok != ',') {
8563 if (is_for_loop_init)
8564 return 1;
8565 skip(';');
8566 break;
8568 next();
8572 return 0;
8575 static void decl(int l)
8577 decl0(l, 0, NULL);
8580 /* ------------------------------------------------------------------------- */
8581 #undef gjmp_addr
8582 #undef gjmp
8583 /* ------------------------------------------------------------------------- */