Workaround old GCC viz indexed string literals
[tinycc.git] / tccgen.c
blobe49407dd01be68a51376368deb4001b73beeb29f
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_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 /********************************************************/
127 /* stab debug support */
129 static const struct {
130 int type;
131 const char *name;
132 } default_debug[] = {
133 { VT_INT, "int:t1=r1;-2147483648;2147483647;" },
134 { VT_BYTE, "char:t2=r2;0;127;" },
135 #if LONG_SIZE == 4
136 { VT_LONG | VT_INT, "long int:t3=r3;-2147483648;2147483647;" },
137 #else
138 { VT_LLONG | VT_LONG, "long int:t3=r3;-9223372036854775808;9223372036854775807;" },
139 #endif
140 { VT_INT | VT_UNSIGNED, "unsigned int:t4=r4;0;037777777777;" },
141 #if LONG_SIZE == 4
142 { VT_LONG | VT_INT | VT_UNSIGNED, "long unsigned int:t5=r5;0;037777777777;" },
143 #else
144 /* use octal instead of -1 so size_t works (-gstabs+ in gcc) */
145 { VT_LLONG | VT_LONG | VT_UNSIGNED, "long unsigned int:t5=r5;0;01777777777777777777777;" },
146 #endif
147 { VT_QLONG, "__int128:t6=r6;0;-1;" },
148 { VT_QLONG | VT_UNSIGNED, "__int128 unsigned:t7=r7;0;-1;" },
149 { VT_LLONG, "long long int:t8=r8;-9223372036854775808;9223372036854775807;" },
150 { VT_LLONG | VT_UNSIGNED, "long long unsigned int:t9=r9;0;01777777777777777777777;" },
151 { VT_SHORT, "short int:t10=r10;-32768;32767;" },
152 { VT_SHORT | VT_UNSIGNED, "short unsigned int:t11=r11;0;65535;" },
153 { VT_BYTE | VT_DEFSIGN, "signed char:t12=r12;-128;127;" },
154 { VT_BYTE | VT_DEFSIGN | VT_UNSIGNED, "unsigned char:t13=r13;0;255;" },
155 { VT_FLOAT, "float:t14=r1;4;0;" },
156 { VT_DOUBLE, "double:t15=r1;8;0;" },
157 { VT_LDOUBLE, "long double:t16=r1;16;0;" },
158 { -1, "_Float32:t17=r1;4;0;" },
159 { -1, "_Float64:t18=r1;8;0;" },
160 { -1, "_Float128:t19=r1;16;0;" },
161 { -1, "_Float32x:t20=r1;8;0;" },
162 { -1, "_Float64x:t21=r1;16;0;" },
163 { -1, "_Decimal32:t22=r1;4;0;" },
164 { -1, "_Decimal64:t23=r1;8;0;" },
165 { -1, "_Decimal128:t24=r1;16;0;" },
166 /* if default char is unsigned */
167 { VT_BYTE | VT_UNSIGNED, "unsigned char:t25=r25;0;255;" },
168 { VT_VOID, "void:t26=26" },
171 static int debug_next_type;
173 static struct debug_hash {
174 int debug_type;
175 Sym *type;
176 } *debug_hash;
178 static int n_debug_hash;
180 static struct debug_info {
181 int start;
182 int end;
183 int n_sym;
184 struct debug_sym {
185 int type;
186 unsigned long value;
187 char *str;
188 Section *sec;
189 int sym_index;
190 } *sym;
191 struct debug_info *child, *next, *last, *parent;
192 } *debug_info, *debug_info_root;
194 /********************************************************/
195 #if 1
196 #define precedence_parser
197 static void init_prec(void);
198 #endif
199 /********************************************************/
200 #ifndef CONFIG_TCC_ASM
201 ST_FUNC void asm_instr(void)
203 tcc_error("inline asm() not supported");
205 ST_FUNC void asm_global_instr(void)
207 tcc_error("inline asm() not supported");
209 #endif
211 /* ------------------------------------------------------------------------- */
212 static void gen_cast(CType *type);
213 static void gen_cast_s(int t);
214 static inline CType *pointed_type(CType *type);
215 static int is_compatible_types(CType *type1, CType *type2);
216 static int parse_btype(CType *type, AttributeDef *ad);
217 static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td);
218 static void parse_expr_type(CType *type);
219 static void init_putv(CType *type, Section *sec, unsigned long c);
220 static void decl_initializer(CType *type, Section *sec, unsigned long c, int flags);
221 static void block(int is_expr);
222 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
223 static void decl(int l);
224 static int decl0(int l, int is_for_loop_init, Sym *);
225 static void expr_eq(void);
226 static void vla_runtime_type_size(CType *type, int *a);
227 static int is_compatible_unqualified_types(CType *type1, CType *type2);
228 static inline int64_t expr_const64(void);
229 static void vpush64(int ty, unsigned long long v);
230 static void vpush(CType *type);
231 static int gvtst(int inv, int t);
232 static void gen_inline_functions(TCCState *s);
233 static void free_inline_functions(TCCState *s);
234 static void skip_or_save_block(TokenString **str);
235 static void gv_dup(void);
236 static int get_temp_local_var(int size,int align);
237 static void clear_temp_local_var_list();
238 static void cast_error(CType *st, CType *dt);
240 ST_INLN int is_float(int t)
242 int bt = t & VT_BTYPE;
243 return bt == VT_LDOUBLE
244 || bt == VT_DOUBLE
245 || bt == VT_FLOAT
246 || bt == VT_QFLOAT;
249 static inline int is_integer_btype(int bt)
251 return bt == VT_BYTE
252 || bt == VT_BOOL
253 || bt == VT_SHORT
254 || bt == VT_INT
255 || bt == VT_LLONG;
258 static int btype_size(int bt)
260 return bt == VT_BYTE || bt == VT_BOOL ? 1 :
261 bt == VT_SHORT ? 2 :
262 bt == VT_INT ? 4 :
263 bt == VT_LLONG ? 8 :
264 bt == VT_PTR ? PTR_SIZE : 0;
267 /* returns function return register from type */
268 static int R_RET(int t)
270 if (!is_float(t))
271 return REG_IRET;
272 #ifdef TCC_TARGET_X86_64
273 if ((t & VT_BTYPE) == VT_LDOUBLE)
274 return TREG_ST0;
275 #elif defined TCC_TARGET_RISCV64
276 if ((t & VT_BTYPE) == VT_LDOUBLE)
277 return REG_IRET;
278 #endif
279 return REG_FRET;
282 /* returns 2nd function return register, if any */
283 static int R2_RET(int t)
285 t &= VT_BTYPE;
286 #if PTR_SIZE == 4
287 if (t == VT_LLONG)
288 return REG_IRE2;
289 #elif defined TCC_TARGET_X86_64
290 if (t == VT_QLONG)
291 return REG_IRE2;
292 if (t == VT_QFLOAT)
293 return REG_FRE2;
294 #elif defined TCC_TARGET_RISCV64
295 if (t == VT_LDOUBLE)
296 return REG_IRE2;
297 #endif
298 return VT_CONST;
301 /* returns true for two-word types */
302 #define USING_TWO_WORDS(t) (R2_RET(t) != VT_CONST)
304 /* put function return registers to stack value */
305 static void PUT_R_RET(SValue *sv, int t)
307 sv->r = R_RET(t), sv->r2 = R2_RET(t);
310 /* returns function return register class for type t */
311 static int RC_RET(int t)
313 return reg_classes[R_RET(t)] & ~(RC_FLOAT | RC_INT);
316 /* returns generic register class for type t */
317 static int RC_TYPE(int t)
319 if (!is_float(t))
320 return RC_INT;
321 #ifdef TCC_TARGET_X86_64
322 if ((t & VT_BTYPE) == VT_LDOUBLE)
323 return RC_ST0;
324 if ((t & VT_BTYPE) == VT_QFLOAT)
325 return RC_FRET;
326 #elif defined TCC_TARGET_RISCV64
327 if ((t & VT_BTYPE) == VT_LDOUBLE)
328 return RC_INT;
329 #endif
330 return RC_FLOAT;
333 /* returns 2nd register class corresponding to t and rc */
334 static int RC2_TYPE(int t, int rc)
336 if (!USING_TWO_WORDS(t))
337 return 0;
338 #ifdef RC_IRE2
339 if (rc == RC_IRET)
340 return RC_IRE2;
341 #endif
342 #ifdef RC_FRE2
343 if (rc == RC_FRET)
344 return RC_FRE2;
345 #endif
346 if (rc & RC_FLOAT)
347 return RC_FLOAT;
348 return RC_INT;
351 /* we use our own 'finite' function to avoid potential problems with
352 non standard math libs */
353 /* XXX: endianness dependent */
354 ST_FUNC int ieee_finite(double d)
356 int p[4];
357 memcpy(p, &d, sizeof(double));
358 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
361 /* compiling intel long double natively */
362 #if (defined __i386__ || defined __x86_64__) \
363 && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
364 # define TCC_IS_NATIVE_387
365 #endif
367 ST_FUNC void test_lvalue(void)
369 if (!(vtop->r & VT_LVAL))
370 expect("lvalue");
373 ST_FUNC void check_vstack(void)
375 if (vtop != vstack - 1)
376 tcc_error("internal compiler error: vstack leak (%d)",
377 (int)(vtop - vstack + 1));
380 /* ------------------------------------------------------------------------- */
381 /* vstack debugging aid */
383 #if 0
384 void pv (const char *lbl, int a, int b)
386 int i;
387 for (i = a; i < a + b; ++i) {
388 SValue *p = &vtop[-i];
389 printf("%s vtop[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n",
390 lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);
393 #endif
395 /* ------------------------------------------------------------------------- */
396 /* start of translation unit info */
397 ST_FUNC void tcc_debug_start(TCCState *s1)
399 if (s1->do_debug) {
400 int i;
401 char buf[512];
403 /* file info: full path + filename */
404 section_sym = put_elf_sym(symtab_section, 0, 0,
405 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
406 text_section->sh_num, NULL);
407 getcwd(buf, sizeof(buf));
408 #ifdef _WIN32
409 normalize_slashes(buf);
410 #endif
411 pstrcat(buf, sizeof(buf), "/");
412 put_stabs_r(s1, buf, N_SO, 0, 0,
413 text_section->data_offset, text_section, section_sym);
414 put_stabs_r(s1, file->prev->filename, N_SO, 0, 0,
415 text_section->data_offset, text_section, section_sym);
416 for (i = 0; i < sizeof (default_debug) / sizeof (default_debug[0]); i++)
417 put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0);
419 new_file = last_line_num = 0;
420 func_ind = -1;
421 debug_next_type = sizeof(default_debug) / sizeof(default_debug[0]);
422 debug_hash = NULL;
423 n_debug_hash = 0;
425 /* we're currently 'including' the <command line> */
426 tcc_debug_bincl(s1);
429 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
430 symbols can be safely used */
431 put_elf_sym(symtab_section, 0, 0,
432 ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
433 SHN_ABS, file->filename);
436 static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned long value,
437 Section *sec, int sym_index)
439 struct debug_sym *s;
441 if (debug_info) {
442 debug_info->sym =
443 (struct debug_sym *)tcc_realloc (debug_info->sym,
444 sizeof(struct debug_sym) *
445 (debug_info->n_sym + 1));
446 s = debug_info->sym + debug_info->n_sym++;
447 s->type = type;
448 s->value = value;
449 s->str = tcc_strdup(str);
450 s->sec = sec;
451 s->sym_index = sym_index;
453 else if (sec)
454 put_stabs_r (s1, str, type, 0, 0, value, sec, sym_index);
455 else
456 put_stabs (s1, str, type, 0, 0, value);
459 static void tcc_debug_stabn(int type, int value)
461 if (type == N_LBRAC) {
462 struct debug_info *info =
463 (struct debug_info *) tcc_mallocz(sizeof (*info));
465 info->start = value;
466 info->parent = debug_info;
467 if (debug_info) {
468 if (debug_info->child) {
469 if (debug_info->child->last)
470 debug_info->child->last->next = info;
471 else
472 debug_info->child->next = info;
473 debug_info->child->last = info;
475 else
476 debug_info->child = info;
478 else
479 debug_info_root = info;
480 debug_info = info;
482 else {
483 debug_info->end = value;
484 debug_info = debug_info->parent;
488 static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result)
490 int type;
491 int n = 0;
492 int debug_type = -1;
493 Sym *t = s;
494 CString str;
496 for (;;) {
497 type = t->type.t & ~(VT_EXTERN | VT_STATIC | VT_CONSTANT | VT_VOLATILE);
498 if ((type & VT_BTYPE) != VT_BYTE)
499 type &= ~VT_DEFSIGN;
500 if (type == VT_PTR || type == (VT_PTR | VT_ARRAY))
501 n++, t = t->type.ref;
502 else
503 break;
505 if ((type & VT_BTYPE) == VT_STRUCT) {
506 int i;
508 t = t->type.ref;
509 for (i = 0; i < n_debug_hash; i++) {
510 if (t == debug_hash[i].type) {
511 debug_type = debug_hash[i].debug_type;
512 break;
515 if (debug_type == -1) {
516 debug_type = ++debug_next_type;
517 debug_hash = (struct debug_hash *)
518 tcc_realloc (debug_hash,
519 (n_debug_hash + 1) * sizeof(*debug_hash));
520 debug_hash[n_debug_hash].debug_type = debug_type;
521 debug_hash[n_debug_hash++].type = t;
522 cstr_new (&str);
523 cstr_printf (&str, "%s:T%d=%c%d",
524 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
525 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL),
526 debug_type,
527 IS_UNION (t->type.t) ? 'u' : 's',
528 t->c);
529 while (t->next) {
530 int pos, size, align;
532 t = t->next;
533 cstr_printf (&str, "%s:",
534 (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
535 ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL));
536 tcc_get_debug_info (s1, t, &str);
537 if (t->type.t & VT_BITFIELD) {
538 pos = t->c * 8 + BIT_POS(t->type.t);
539 size = BIT_SIZE(t->type.t);
541 else {
542 pos = t->c * 8;
543 size = type_size(&t->type, &align) * 8;
545 cstr_printf (&str, ",%d,%d;", pos, size);
547 cstr_printf (&str, ";");
548 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0);
549 cstr_free (&str);
552 else if (IS_ENUM(type)) {
553 Sym *e = t = t->type.ref;
555 debug_type = ++debug_next_type;
556 cstr_new (&str);
557 cstr_printf (&str, "%s:T%d=e",
558 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
559 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL),
560 debug_type);
561 while (t->next) {
562 t = t->next;
563 cstr_printf (&str, "%s:",
564 (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
565 ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL));
566 cstr_printf (&str, e->type.t & VT_UNSIGNED ? "%u," : "%d,",
567 (int)t->enum_val);
569 cstr_printf (&str, ";");
570 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0);
571 cstr_free (&str);
573 else if ((type & VT_BTYPE) != VT_FUNC) {
574 type &= ~VT_STRUCT_MASK;
575 for (debug_type = 1;
576 debug_type <= sizeof(default_debug) / sizeof(default_debug[0]);
577 debug_type++)
578 if (default_debug[debug_type - 1].type == type)
579 break;
580 if (debug_type > sizeof(default_debug) / sizeof(default_debug[0]))
581 return;
583 if (n > 0)
584 cstr_printf (result, "%d=", ++debug_next_type);
585 t = s;
586 for (;;) {
587 type = t->type.t & ~(VT_EXTERN | VT_STATIC | VT_CONSTANT | VT_VOLATILE);
588 if ((type & VT_BTYPE) != VT_BYTE)
589 type &= ~VT_DEFSIGN;
590 if (type == VT_PTR)
591 cstr_printf (result, "%d=*", ++debug_next_type);
592 else if (type == (VT_PTR | VT_ARRAY))
593 cstr_printf (result, "%d=ar1;0;%d;",
594 ++debug_next_type, t->type.ref->c - 1);
595 else if (type == VT_FUNC) {
596 cstr_printf (result, "%d=f", ++debug_next_type);
597 tcc_get_debug_info (s1, t->type.ref, result);
598 return;
600 else
601 break;
602 t = t->type.ref;
604 cstr_printf (result, "%d", debug_type);
607 static void tcc_debug_finish (TCCState *s1, struct debug_info *cur)
609 while (cur) {
610 int i;
611 struct debug_info *next = cur->next;
613 for (i = 0; i < cur->n_sym; i++) {
614 struct debug_sym *s = &cur->sym[i];
616 if (s->sec)
617 put_stabs_r(s1, s->str, s->type, 0, 0, s->value,
618 s->sec, s->sym_index);
619 else
620 put_stabs(s1, s->str, s->type, 0, 0, s->value);
621 tcc_free (s->str);
623 tcc_free (cur->sym);
624 put_stabn(s1, N_LBRAC, 0, 0, cur->start);
625 tcc_debug_finish (s1, cur->child);
626 put_stabn(s1, N_RBRAC, 0, 0, cur->end);
627 tcc_free (cur);
628 cur = next;
632 static void tcc_add_debug_info(TCCState *s1, int param, Sym *s, Sym *e)
634 CString debug_str;
635 cstr_new (&debug_str);
636 for (; s != e; s = s->prev) {
637 if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL)
638 continue;
639 cstr_reset (&debug_str);
640 cstr_printf (&debug_str, "%s:%s", get_tok_str(s->v, NULL), param ? "p" : "");
641 tcc_get_debug_info(s1, s, &debug_str);
642 tcc_debug_stabs(s1, debug_str.data, param ? N_PSYM : N_LSYM, s->c, NULL, 0);
644 cstr_free (&debug_str);
647 static void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bind)
649 Section *s = s1->sections[sh_num];
650 CString str;
652 cstr_new (&str);
653 cstr_printf (&str, "%s:%c",
654 get_tok_str(sym->v, NULL),
655 sym_bind == STB_GLOBAL ? 'G' : local_scope ? 'V' : 'S'
657 tcc_get_debug_info(s1, sym, &str);
658 if (sym_bind == STB_GLOBAL)
659 tcc_debug_stabs(s1, str.data, N_GSYM, 0, NULL, 0);
660 else
661 tcc_debug_stabs(s1, str.data,
662 (sym->type.t & VT_STATIC) && data_section == s
663 ? N_STSYM : N_LCSYM, 0, s, sym->c);
664 cstr_free (&str);
667 /* put end of translation unit info */
668 ST_FUNC void tcc_debug_end(TCCState *s1)
670 if (!s1->do_debug)
671 return;
672 put_stabs_r(s1, NULL, N_SO, 0, 0,
673 text_section->data_offset, text_section, section_sym);
674 tcc_free(debug_hash);
677 static BufferedFile* put_new_file(TCCState *s1)
679 BufferedFile *f = file;
680 /* use upper file if from inline ":asm:" */
681 if (f->filename[0] == ':')
682 f = f->prev;
683 if (f && new_file) {
684 put_stabs_r(s1, f->filename, N_SOL, 0, 0, ind, text_section, section_sym);
685 new_file = last_line_num = 0;
687 return f;
690 /* generate line number info */
691 ST_FUNC void tcc_debug_line(TCCState *s1)
693 BufferedFile *f;
694 if (!s1->do_debug
695 || cur_text_section != text_section
696 || !(f = put_new_file(s1))
697 || last_line_num == f->line_num)
698 return;
699 if (func_ind != -1) {
700 put_stabn(s1, N_SLINE, 0, f->line_num, ind - func_ind);
701 } else {
702 /* from tcc_assemble */
703 put_stabs_r(s1, NULL, N_SLINE, 0, f->line_num, ind, text_section, section_sym);
705 last_line_num = f->line_num;
708 /* put function symbol */
709 ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
711 CString debug_str;
712 BufferedFile *f;
713 if (!s1->do_debug)
714 return;
715 debug_info_root = NULL;
716 debug_info = NULL;
717 tcc_debug_stabn(N_LBRAC, ind - func_ind);
718 if (!(f = put_new_file(s1)))
719 return;
720 cstr_new (&debug_str);
721 cstr_printf(&debug_str, "%s:%c", funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
722 tcc_get_debug_info(s1, sym->type.ref, &debug_str);
723 put_stabs_r(s1, debug_str.data, N_FUN, 0, f->line_num, 0, cur_text_section, sym->c);
724 cstr_free (&debug_str);
726 tcc_debug_line(s1);
729 /* put function size */
730 ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
732 if (!s1->do_debug)
733 return;
734 tcc_debug_stabn(N_RBRAC, size);
735 tcc_debug_finish (s1, debug_info_root);
738 /* put alternative filename */
739 ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename)
741 if (0 == strcmp(file->filename, filename))
742 return;
743 pstrcpy(file->filename, sizeof(file->filename), filename);
744 new_file = 1;
747 /* begin of #include */
748 ST_FUNC void tcc_debug_bincl(TCCState *s1)
750 if (!s1->do_debug)
751 return;
752 put_stabs(s1, file->filename, N_BINCL, 0, 0, 0);
753 new_file = 1;
756 /* end of #include */
757 ST_FUNC void tcc_debug_eincl(TCCState *s1)
759 if (!s1->do_debug)
760 return;
761 put_stabn(s1, N_EINCL, 0, 0, 0);
762 new_file = 1;
765 /* ------------------------------------------------------------------------- */
766 /* initialize vstack and types. This must be done also for tcc -E */
767 ST_FUNC void tccgen_init(TCCState *s1)
769 vtop = vstack - 1;
770 memset(vtop, 0, sizeof *vtop);
772 /* define some often used types */
773 int_type.t = VT_INT;
774 char_pointer_type.t = VT_BYTE;
775 mk_pointer(&char_pointer_type);
776 func_old_type.t = VT_FUNC;
777 func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);
778 func_old_type.ref->f.func_call = FUNC_CDECL;
779 func_old_type.ref->f.func_type = FUNC_OLD;
780 #ifdef precedence_parser
781 init_prec();
782 #endif
783 cstr_new(&initstr);
786 ST_FUNC int tccgen_compile(TCCState *s1)
788 cur_text_section = NULL;
789 funcname = "";
790 anon_sym = SYM_FIRST_ANOM;
791 section_sym = 0;
792 const_wanted = 0;
793 nocode_wanted = 0x80000000;
794 local_scope = 0;
796 tcc_debug_start(s1);
797 #ifdef TCC_TARGET_ARM
798 arm_init(s1);
799 #endif
800 #ifdef INC_DEBUG
801 printf("%s: **** new file\n", file->filename);
802 #endif
803 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
804 next();
805 decl(VT_CONST);
806 gen_inline_functions(s1);
807 check_vstack();
808 /* end of translation unit info */
809 tcc_debug_end(s1);
810 return 0;
813 ST_FUNC void tccgen_finish(TCCState *s1)
815 cstr_free(&initstr);
816 free_inline_functions(s1);
817 sym_pop(&global_stack, NULL, 0);
818 sym_pop(&local_stack, NULL, 0);
819 /* free preprocessor macros */
820 free_defines(NULL);
821 /* free sym_pools */
822 dynarray_reset(&sym_pools, &nb_sym_pools);
823 sym_free_first = NULL;
826 /* ------------------------------------------------------------------------- */
827 ST_FUNC ElfSym *elfsym(Sym *s)
829 if (!s || !s->c)
830 return NULL;
831 return &((ElfSym *)symtab_section->data)[s->c];
834 /* apply storage attributes to Elf symbol */
835 ST_FUNC void update_storage(Sym *sym)
837 ElfSym *esym;
838 int sym_bind, old_sym_bind;
840 esym = elfsym(sym);
841 if (!esym)
842 return;
844 if (sym->a.visibility)
845 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
846 | sym->a.visibility;
848 if (sym->type.t & (VT_STATIC | VT_INLINE))
849 sym_bind = STB_LOCAL;
850 else if (sym->a.weak)
851 sym_bind = STB_WEAK;
852 else
853 sym_bind = STB_GLOBAL;
854 old_sym_bind = ELFW(ST_BIND)(esym->st_info);
855 if (sym_bind != old_sym_bind) {
856 esym->st_info = ELFW(ST_INFO)(sym_bind, ELFW(ST_TYPE)(esym->st_info));
859 #ifdef TCC_TARGET_PE
860 if (sym->a.dllimport)
861 esym->st_other |= ST_PE_IMPORT;
862 if (sym->a.dllexport)
863 esym->st_other |= ST_PE_EXPORT;
864 #endif
866 #if 0
867 printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n",
868 get_tok_str(sym->v, NULL),
869 sym_bind == STB_WEAK ? 'w' : sym_bind == STB_LOCAL ? 'l' : 'g',
870 sym->a.visibility,
871 sym->a.dllexport,
872 sym->a.dllimport
874 #endif
877 /* ------------------------------------------------------------------------- */
878 /* update sym->c so that it points to an external symbol in section
879 'section' with value 'value' */
881 ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
882 addr_t value, unsigned long size,
883 int can_add_underscore)
885 int sym_type, sym_bind, info, other, t;
886 ElfSym *esym;
887 const char *name;
888 char buf1[256];
889 #ifdef CONFIG_TCC_BCHECK
890 char buf[32];
891 #endif
892 if (!sym->c) {
893 name = get_tok_str(sym->v, NULL);
894 #ifdef CONFIG_TCC_BCHECK
895 if (tcc_state->do_bounds_check) {
896 /* XXX: avoid doing that for statics ? */
897 /* if bound checking is activated, we change some function
898 names by adding the "__bound" prefix */
899 #if defined(TCC_TARGET_ARM) && defined(TCC_ARM_EABI)
900 if (strcmp (name, "memcpy") == 0 ||
901 strcmp (name, "memmove") == 0 ||
902 strcmp (name, "memset") == 0)
903 goto add_bound;
904 #endif
905 switch(sym->v) {
906 #ifdef TCC_TARGET_PE
907 /* XXX: we rely only on malloc hooks */
908 case TOK_malloc:
909 case TOK_free:
910 case TOK_realloc:
911 case TOK_memalign:
912 case TOK_calloc:
913 #endif
914 case TOK_memcpy:
915 case TOK_memmove:
916 #if defined(TCC_TARGET_ARM) && defined(TCC_ARM_EABI)
917 case TOK_memmove4:
918 case TOK_memmove8:
919 #endif
920 case TOK_memset:
921 case TOK_memcmp:
922 case TOK_strlen:
923 case TOK_strcpy:
924 case TOK_strncpy:
925 case TOK_strcmp:
926 case TOK_strncmp:
927 case TOK_strcat:
928 case TOK_strchr:
929 case TOK_strdup:
930 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
931 case TOK_alloca:
932 #endif
933 case TOK_mmap:
934 case TOK_munmap:
935 case TOK_longjmp:
936 #ifndef TCC_TARGET_PE
937 case TOK_siglongjmp:
938 #endif
939 #if defined(TCC_TARGET_ARM) && defined(TCC_ARM_EABI)
940 add_bound:
941 #endif
942 strcpy(buf, "__bound_");
943 strcat(buf, name);
944 name = buf;
945 break;
948 #endif
949 t = sym->type.t;
950 if ((t & VT_BTYPE) == VT_FUNC) {
951 sym_type = STT_FUNC;
952 } else if ((t & VT_BTYPE) == VT_VOID) {
953 sym_type = STT_NOTYPE;
954 } else {
955 sym_type = STT_OBJECT;
957 if (t & (VT_STATIC | VT_INLINE))
958 sym_bind = STB_LOCAL;
959 else
960 sym_bind = STB_GLOBAL;
961 other = 0;
962 #ifdef TCC_TARGET_PE
963 if (sym_type == STT_FUNC && sym->type.ref) {
964 Sym *ref = sym->type.ref;
965 if (ref->a.nodecorate) {
966 can_add_underscore = 0;
968 if (ref->f.func_call == FUNC_STDCALL && can_add_underscore) {
969 sprintf(buf1, "_%s@%d", name, ref->f.func_args * PTR_SIZE);
970 name = buf1;
971 other |= ST_PE_STDCALL;
972 can_add_underscore = 0;
975 #endif
976 if (tcc_state->leading_underscore && can_add_underscore) {
977 buf1[0] = '_';
978 pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
979 name = buf1;
981 if (sym->asm_label)
982 name = get_tok_str(sym->asm_label, NULL);
983 info = ELFW(ST_INFO)(sym_bind, sym_type);
984 sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name);
986 if (tcc_state->do_debug
987 && sym_type != STT_FUNC
988 && sym->v < SYM_FIRST_ANOM)
989 tcc_debug_extern_sym(tcc_state, sym, sh_num, sym_bind);
991 } else {
992 esym = elfsym(sym);
993 esym->st_value = value;
994 esym->st_size = size;
995 esym->st_shndx = sh_num;
997 update_storage(sym);
1000 ST_FUNC void put_extern_sym(Sym *sym, Section *section,
1001 addr_t value, unsigned long size)
1003 int sh_num = section ? section->sh_num : SHN_UNDEF;
1004 put_extern_sym2(sym, sh_num, value, size, 1);
1007 /* add a new relocation entry to symbol 'sym' in section 's' */
1008 ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
1009 addr_t addend)
1011 int c = 0;
1013 if (nocode_wanted && s == cur_text_section)
1014 return;
1016 if (sym) {
1017 if (0 == sym->c)
1018 put_extern_sym(sym, NULL, 0, 0);
1019 c = sym->c;
1022 /* now we can add ELF relocation info */
1023 put_elf_reloca(symtab_section, s, offset, type, c, addend);
1026 #if PTR_SIZE == 4
1027 ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
1029 greloca(s, sym, offset, type, 0);
1031 #endif
1033 /* ------------------------------------------------------------------------- */
1034 /* symbol allocator */
1035 static Sym *__sym_malloc(void)
1037 Sym *sym_pool, *sym, *last_sym;
1038 int i;
1040 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
1041 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
1043 last_sym = sym_free_first;
1044 sym = sym_pool;
1045 for(i = 0; i < SYM_POOL_NB; i++) {
1046 sym->next = last_sym;
1047 last_sym = sym;
1048 sym++;
1050 sym_free_first = last_sym;
1051 return last_sym;
1054 static inline Sym *sym_malloc(void)
1056 Sym *sym;
1057 #ifndef SYM_DEBUG
1058 sym = sym_free_first;
1059 if (!sym)
1060 sym = __sym_malloc();
1061 sym_free_first = sym->next;
1062 return sym;
1063 #else
1064 sym = tcc_malloc(sizeof(Sym));
1065 return sym;
1066 #endif
1069 ST_INLN void sym_free(Sym *sym)
1071 #ifndef SYM_DEBUG
1072 sym->next = sym_free_first;
1073 sym_free_first = sym;
1074 #else
1075 tcc_free(sym);
1076 #endif
1079 /* push, without hashing */
1080 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c)
1082 Sym *s;
1084 s = sym_malloc();
1085 memset(s, 0, sizeof *s);
1086 s->v = v;
1087 s->type.t = t;
1088 s->c = c;
1089 /* add in stack */
1090 s->prev = *ps;
1091 *ps = s;
1092 return s;
1095 /* find a symbol and return its associated structure. 's' is the top
1096 of the symbol stack */
1097 ST_FUNC Sym *sym_find2(Sym *s, int v)
1099 while (s) {
1100 if (s->v == v)
1101 return s;
1102 else if (s->v == -1)
1103 return NULL;
1104 s = s->prev;
1106 return NULL;
1109 /* structure lookup */
1110 ST_INLN Sym *struct_find(int v)
1112 v -= TOK_IDENT;
1113 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1114 return NULL;
1115 return table_ident[v]->sym_struct;
1118 /* find an identifier */
1119 ST_INLN Sym *sym_find(int v)
1121 v -= TOK_IDENT;
1122 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1123 return NULL;
1124 return table_ident[v]->sym_identifier;
1127 static int sym_scope(Sym *s)
1129 if (IS_ENUM_VAL (s->type.t))
1130 return s->type.ref->sym_scope;
1131 else
1132 return s->sym_scope;
1135 /* push a given symbol on the symbol stack */
1136 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
1138 Sym *s, **ps;
1139 TokenSym *ts;
1141 if (local_stack)
1142 ps = &local_stack;
1143 else
1144 ps = &global_stack;
1145 s = sym_push2(ps, v, type->t, c);
1146 s->type.ref = type->ref;
1147 s->r = r;
1148 /* don't record fields or anonymous symbols */
1149 /* XXX: simplify */
1150 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1151 /* record symbol in token array */
1152 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1153 if (v & SYM_STRUCT)
1154 ps = &ts->sym_struct;
1155 else
1156 ps = &ts->sym_identifier;
1157 s->prev_tok = *ps;
1158 *ps = s;
1159 s->sym_scope = local_scope;
1160 if (s->prev_tok && sym_scope(s->prev_tok) == s->sym_scope)
1161 tcc_error("redeclaration of '%s'",
1162 get_tok_str(v & ~SYM_STRUCT, NULL));
1164 return s;
1167 /* push a global identifier */
1168 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
1170 Sym *s, **ps;
1171 s = sym_push2(&global_stack, v, t, c);
1172 s->r = VT_CONST | VT_SYM;
1173 /* don't record anonymous symbol */
1174 if (v < SYM_FIRST_ANOM) {
1175 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
1176 /* modify the top most local identifier, so that sym_identifier will
1177 point to 's' when popped; happens when called from inline asm */
1178 while (*ps != NULL && (*ps)->sym_scope)
1179 ps = &(*ps)->prev_tok;
1180 s->prev_tok = *ps;
1181 *ps = s;
1183 return s;
1186 /* pop symbols until top reaches 'b'. If KEEP is non-zero don't really
1187 pop them yet from the list, but do remove them from the token array. */
1188 ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep)
1190 Sym *s, *ss, **ps;
1191 TokenSym *ts;
1192 int v;
1194 s = *ptop;
1195 while(s != b) {
1196 ss = s->prev;
1197 v = s->v;
1198 /* remove symbol in token array */
1199 /* XXX: simplify */
1200 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1201 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1202 if (v & SYM_STRUCT)
1203 ps = &ts->sym_struct;
1204 else
1205 ps = &ts->sym_identifier;
1206 *ps = s->prev_tok;
1208 if (!keep)
1209 sym_free(s);
1210 s = ss;
1212 if (!keep)
1213 *ptop = b;
1216 /* ------------------------------------------------------------------------- */
1217 static void vcheck_cmp(void)
1219 /* cannot let cpu flags if other instruction are generated. Also
1220 avoid leaving VT_JMP anywhere except on the top of the stack
1221 because it would complicate the code generator.
1223 Don't do this when nocode_wanted. vtop might come from
1224 !nocode_wanted regions (see 88_codeopt.c) and transforming
1225 it to a register without actually generating code is wrong
1226 as their value might still be used for real. All values
1227 we push under nocode_wanted will eventually be popped
1228 again, so that the VT_CMP/VT_JMP value will be in vtop
1229 when code is unsuppressed again. */
1231 if (vtop->r == VT_CMP && !nocode_wanted)
1232 gv(RC_INT);
1235 static void vsetc(CType *type, int r, CValue *vc)
1237 if (vtop >= vstack + (VSTACK_SIZE - 1))
1238 tcc_error("memory full (vstack)");
1239 vcheck_cmp();
1240 vtop++;
1241 vtop->type = *type;
1242 vtop->r = r;
1243 vtop->r2 = VT_CONST;
1244 vtop->c = *vc;
1245 vtop->sym = NULL;
1248 ST_FUNC void vswap(void)
1250 SValue tmp;
1252 vcheck_cmp();
1253 tmp = vtop[0];
1254 vtop[0] = vtop[-1];
1255 vtop[-1] = tmp;
1258 /* pop stack value */
1259 ST_FUNC void vpop(void)
1261 int v;
1262 v = vtop->r & VT_VALMASK;
1263 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1264 /* for x86, we need to pop the FP stack */
1265 if (v == TREG_ST0) {
1266 o(0xd8dd); /* fstp %st(0) */
1267 } else
1268 #endif
1269 if (v == VT_CMP) {
1270 /* need to put correct jump if && or || without test */
1271 gsym(vtop->jtrue);
1272 gsym(vtop->jfalse);
1274 vtop--;
1277 /* push constant of type "type" with useless value */
1278 static void vpush(CType *type)
1280 vset(type, VT_CONST, 0);
1283 /* push arbitrary 64bit constant */
1284 static void vpush64(int ty, unsigned long long v)
1286 CValue cval;
1287 CType ctype;
1288 ctype.t = ty;
1289 ctype.ref = NULL;
1290 cval.i = v;
1291 vsetc(&ctype, VT_CONST, &cval);
1294 /* push integer constant */
1295 ST_FUNC void vpushi(int v)
1297 vpush64(VT_INT, v);
1300 /* push a pointer sized constant */
1301 static void vpushs(addr_t v)
1303 vpush64(VT_SIZE_T, v);
1306 /* push long long constant */
1307 static inline void vpushll(long long v)
1309 vpush64(VT_LLONG, v);
1312 ST_FUNC void vset(CType *type, int r, int v)
1314 CValue cval;
1315 cval.i = v;
1316 vsetc(type, r, &cval);
1319 static void vseti(int r, int v)
1321 CType type;
1322 type.t = VT_INT;
1323 type.ref = NULL;
1324 vset(&type, r, v);
1327 ST_FUNC void vpushv(SValue *v)
1329 if (vtop >= vstack + (VSTACK_SIZE - 1))
1330 tcc_error("memory full (vstack)");
1331 vtop++;
1332 *vtop = *v;
1335 static void vdup(void)
1337 vpushv(vtop);
1340 /* rotate n first stack elements to the bottom
1341 I1 ... In -> I2 ... In I1 [top is right]
1343 ST_FUNC void vrotb(int n)
1345 int i;
1346 SValue tmp;
1348 vcheck_cmp();
1349 tmp = vtop[-n + 1];
1350 for(i=-n+1;i!=0;i++)
1351 vtop[i] = vtop[i+1];
1352 vtop[0] = tmp;
1355 /* rotate the n elements before entry e towards the top
1356 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1358 ST_FUNC void vrote(SValue *e, int n)
1360 int i;
1361 SValue tmp;
1363 vcheck_cmp();
1364 tmp = *e;
1365 for(i = 0;i < n - 1; i++)
1366 e[-i] = e[-i - 1];
1367 e[-n + 1] = tmp;
1370 /* rotate n first stack elements to the top
1371 I1 ... In -> In I1 ... I(n-1) [top is right]
1373 ST_FUNC void vrott(int n)
1375 vrote(vtop, n);
1378 /* ------------------------------------------------------------------------- */
1379 /* vtop->r = VT_CMP means CPU-flags have been set from comparison or test. */
1381 /* called from generators to set the result from relational ops */
1382 ST_FUNC void vset_VT_CMP(int op)
1384 vtop->r = VT_CMP;
1385 vtop->cmp_op = op;
1386 vtop->jfalse = 0;
1387 vtop->jtrue = 0;
1390 /* called once before asking generators to load VT_CMP to a register */
1391 static void vset_VT_JMP(void)
1393 int op = vtop->cmp_op;
1395 if (vtop->jtrue || vtop->jfalse) {
1396 /* we need to jump to 'mov $0,%R' or 'mov $1,%R' */
1397 int inv = op & (op < 2); /* small optimization */
1398 vseti(VT_JMP+inv, gvtst(inv, 0));
1399 } else {
1400 /* otherwise convert flags (rsp. 0/1) to register */
1401 vtop->c.i = op;
1402 if (op < 2) /* doesn't seem to happen */
1403 vtop->r = VT_CONST;
1407 /* Set CPU Flags, doesn't yet jump */
1408 static void gvtst_set(int inv, int t)
1410 int *p;
1412 if (vtop->r != VT_CMP) {
1413 vpushi(0);
1414 gen_op(TOK_NE);
1415 if (vtop->r != VT_CMP) /* must be VT_CONST then */
1416 vset_VT_CMP(vtop->c.i != 0);
1419 p = inv ? &vtop->jfalse : &vtop->jtrue;
1420 *p = gjmp_append(*p, t);
1423 /* Generate value test
1425 * Generate a test for any value (jump, comparison and integers) */
1426 static int gvtst(int inv, int t)
1428 int op, x, u;
1430 gvtst_set(inv, t);
1431 t = vtop->jtrue, u = vtop->jfalse;
1432 if (inv)
1433 x = u, u = t, t = x;
1434 op = vtop->cmp_op;
1436 /* jump to the wanted target */
1437 if (op > 1)
1438 t = gjmp_cond(op ^ inv, t);
1439 else if (op != inv)
1440 t = gjmp(t);
1441 /* resolve complementary jumps to here */
1442 gsym(u);
1444 vtop--;
1445 return t;
1448 /* generate a zero or nozero test */
1449 static void gen_test_zero(int op)
1451 if (vtop->r == VT_CMP) {
1452 int j;
1453 if (op == TOK_EQ) {
1454 j = vtop->jfalse;
1455 vtop->jfalse = vtop->jtrue;
1456 vtop->jtrue = j;
1457 vtop->cmp_op ^= 1;
1459 } else {
1460 vpushi(0);
1461 gen_op(op);
1465 /* ------------------------------------------------------------------------- */
1466 /* push a symbol value of TYPE */
1467 static inline void vpushsym(CType *type, Sym *sym)
1469 CValue cval;
1470 cval.i = 0;
1471 vsetc(type, VT_CONST | VT_SYM, &cval);
1472 vtop->sym = sym;
1475 /* Return a static symbol pointing to a section */
1476 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
1478 int v;
1479 Sym *sym;
1481 v = anon_sym++;
1482 sym = sym_push(v, type, VT_CONST | VT_SYM, 0);
1483 sym->type.t |= VT_STATIC;
1484 put_extern_sym(sym, sec, offset, size);
1485 return sym;
1488 /* push a reference to a section offset by adding a dummy symbol */
1489 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
1491 vpushsym(type, get_sym_ref(type, sec, offset, size));
1494 /* define a new external reference to a symbol 'v' of type 'u' */
1495 ST_FUNC Sym *external_global_sym(int v, CType *type)
1497 Sym *s;
1499 s = sym_find(v);
1500 if (!s) {
1501 /* push forward reference */
1502 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
1503 s->type.ref = type->ref;
1504 } else if (IS_ASM_SYM(s)) {
1505 s->type.t = type->t | (s->type.t & VT_EXTERN);
1506 s->type.ref = type->ref;
1507 update_storage(s);
1509 return s;
1512 /* Merge symbol attributes. */
1513 static void merge_symattr(struct SymAttr *sa, struct SymAttr *sa1)
1515 if (sa1->aligned && !sa->aligned)
1516 sa->aligned = sa1->aligned;
1517 sa->packed |= sa1->packed;
1518 sa->weak |= sa1->weak;
1519 if (sa1->visibility != STV_DEFAULT) {
1520 int vis = sa->visibility;
1521 if (vis == STV_DEFAULT
1522 || vis > sa1->visibility)
1523 vis = sa1->visibility;
1524 sa->visibility = vis;
1526 sa->dllexport |= sa1->dllexport;
1527 sa->nodecorate |= sa1->nodecorate;
1528 sa->dllimport |= sa1->dllimport;
1531 /* Merge function attributes. */
1532 static void merge_funcattr(struct FuncAttr *fa, struct FuncAttr *fa1)
1534 if (fa1->func_call && !fa->func_call)
1535 fa->func_call = fa1->func_call;
1536 if (fa1->func_type && !fa->func_type)
1537 fa->func_type = fa1->func_type;
1538 if (fa1->func_args && !fa->func_args)
1539 fa->func_args = fa1->func_args;
1540 if (fa1->func_noreturn)
1541 fa->func_noreturn = 1;
1542 if (fa1->func_ctor)
1543 fa->func_ctor = 1;
1544 if (fa1->func_dtor)
1545 fa->func_dtor = 1;
1548 /* Merge attributes. */
1549 static void merge_attr(AttributeDef *ad, AttributeDef *ad1)
1551 merge_symattr(&ad->a, &ad1->a);
1552 merge_funcattr(&ad->f, &ad1->f);
1554 if (ad1->section)
1555 ad->section = ad1->section;
1556 if (ad1->alias_target)
1557 ad->alias_target = ad1->alias_target;
1558 if (ad1->asm_label)
1559 ad->asm_label = ad1->asm_label;
1560 if (ad1->attr_mode)
1561 ad->attr_mode = ad1->attr_mode;
1564 /* Merge some type attributes. */
1565 static void patch_type(Sym *sym, CType *type)
1567 if (!(type->t & VT_EXTERN) || IS_ENUM_VAL(sym->type.t)) {
1568 if (!(sym->type.t & VT_EXTERN))
1569 tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL));
1570 sym->type.t &= ~VT_EXTERN;
1573 if (IS_ASM_SYM(sym)) {
1574 /* stay static if both are static */
1575 sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
1576 sym->type.ref = type->ref;
1579 if (!is_compatible_types(&sym->type, type)) {
1580 tcc_error("incompatible types for redefinition of '%s'",
1581 get_tok_str(sym->v, NULL));
1583 } else if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
1584 int static_proto = sym->type.t & VT_STATIC;
1585 /* warn if static follows non-static function declaration */
1586 if ((type->t & VT_STATIC) && !static_proto
1587 /* XXX this test for inline shouldn't be here. Until we
1588 implement gnu-inline mode again it silences a warning for
1589 mingw caused by our workarounds. */
1590 && !((type->t | sym->type.t) & VT_INLINE))
1591 tcc_warning("static storage ignored for redefinition of '%s'",
1592 get_tok_str(sym->v, NULL));
1594 /* set 'inline' if both agree or if one has static */
1595 if ((type->t | sym->type.t) & VT_INLINE) {
1596 if (!((type->t ^ sym->type.t) & VT_INLINE)
1597 || ((type->t | sym->type.t) & VT_STATIC))
1598 static_proto |= VT_INLINE;
1601 if (0 == (type->t & VT_EXTERN)) {
1602 struct FuncAttr f = sym->type.ref->f;
1603 /* put complete type, use static from prototype */
1604 sym->type.t = (type->t & ~(VT_STATIC|VT_INLINE)) | static_proto;
1605 sym->type.ref = type->ref;
1606 merge_funcattr(&sym->type.ref->f, &f);
1607 } else {
1608 sym->type.t &= ~VT_INLINE | static_proto;
1611 if (sym->type.ref->f.func_type == FUNC_OLD
1612 && type->ref->f.func_type != FUNC_OLD) {
1613 sym->type.ref = type->ref;
1616 } else {
1617 if ((sym->type.t & VT_ARRAY) && type->ref->c >= 0) {
1618 /* set array size if it was omitted in extern declaration */
1619 sym->type.ref->c = type->ref->c;
1621 if ((type->t ^ sym->type.t) & VT_STATIC)
1622 tcc_warning("storage mismatch for redefinition of '%s'",
1623 get_tok_str(sym->v, NULL));
1627 /* Merge some storage attributes. */
1628 static void patch_storage(Sym *sym, AttributeDef *ad, CType *type)
1630 if (type)
1631 patch_type(sym, type);
1633 #ifdef TCC_TARGET_PE
1634 if (sym->a.dllimport != ad->a.dllimport)
1635 tcc_error("incompatible dll linkage for redefinition of '%s'",
1636 get_tok_str(sym->v, NULL));
1637 #endif
1638 merge_symattr(&sym->a, &ad->a);
1639 if (ad->asm_label)
1640 sym->asm_label = ad->asm_label;
1641 update_storage(sym);
1644 /* copy sym to other stack */
1645 static Sym *sym_copy(Sym *s0, Sym **ps)
1647 Sym *s;
1648 s = sym_malloc(), *s = *s0;
1649 s->prev = *ps, *ps = s;
1650 if (s->v < SYM_FIRST_ANOM) {
1651 ps = &table_ident[s->v - TOK_IDENT]->sym_identifier;
1652 s->prev_tok = *ps, *ps = s;
1654 return s;
1657 /* copy s->type.ref to stack 'ps' for VT_FUNC and VT_PTR */
1658 static void sym_copy_ref(Sym *s, Sym **ps)
1660 int bt = s->type.t & VT_BTYPE;
1661 if (bt == VT_FUNC || bt == VT_PTR) {
1662 Sym **sp = &s->type.ref;
1663 for (s = *sp, *sp = NULL; s; s = s->next) {
1664 Sym *s2 = sym_copy(s, ps);
1665 sp = &(*sp = s2)->next;
1666 sym_copy_ref(s2, ps);
1671 /* define a new external reference to a symbol 'v' */
1672 static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad)
1674 Sym *s;
1676 /* look for global symbol */
1677 s = sym_find(v);
1678 while (s && s->sym_scope)
1679 s = s->prev_tok;
1681 if (!s) {
1682 /* push forward reference */
1683 s = global_identifier_push(v, type->t, 0);
1684 s->r |= r;
1685 s->a = ad->a;
1686 s->asm_label = ad->asm_label;
1687 s->type.ref = type->ref;
1688 /* copy type to the global stack */
1689 if (local_stack)
1690 sym_copy_ref(s, &global_stack);
1691 } else {
1692 patch_storage(s, ad, type);
1694 /* push variables on local_stack if any */
1695 if (local_stack && (s->type.t & VT_BTYPE) != VT_FUNC)
1696 s = sym_copy(s, &local_stack);
1697 return s;
1700 /* push a reference to global symbol v */
1701 ST_FUNC void vpush_global_sym(CType *type, int v)
1703 vpushsym(type, external_global_sym(v, type));
1706 /* save registers up to (vtop - n) stack entry */
1707 ST_FUNC void save_regs(int n)
1709 SValue *p, *p1;
1710 for(p = vstack, p1 = vtop - n; p <= p1; p++)
1711 save_reg(p->r);
1714 /* save r to the memory stack, and mark it as being free */
1715 ST_FUNC void save_reg(int r)
1717 save_reg_upstack(r, 0);
1720 /* save r to the memory stack, and mark it as being free,
1721 if seen up to (vtop - n) stack entry */
1722 ST_FUNC void save_reg_upstack(int r, int n)
1724 int l, size, align, bt;
1725 SValue *p, *p1, sv;
1727 if ((r &= VT_VALMASK) >= VT_CONST)
1728 return;
1729 if (nocode_wanted)
1730 return;
1731 l = 0;
1732 for(p = vstack, p1 = vtop - n; p <= p1; p++) {
1733 if ((p->r & VT_VALMASK) == r || p->r2 == r) {
1734 /* must save value on stack if not already done */
1735 if (!l) {
1736 bt = p->type.t & VT_BTYPE;
1737 if (bt == VT_VOID)
1738 continue;
1739 if ((p->r & VT_LVAL) || bt == VT_FUNC)
1740 bt = VT_PTR;
1741 sv.type.t = bt;
1742 size = type_size(&sv.type, &align);
1743 l = get_temp_local_var(size,align);
1744 sv.r = VT_LOCAL | VT_LVAL;
1745 sv.c.i = l;
1746 store(p->r & VT_VALMASK, &sv);
1747 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1748 /* x86 specific: need to pop fp register ST0 if saved */
1749 if (r == TREG_ST0) {
1750 o(0xd8dd); /* fstp %st(0) */
1752 #endif
1753 /* special long long case */
1754 if (p->r2 < VT_CONST && USING_TWO_WORDS(bt)) {
1755 sv.c.i += PTR_SIZE;
1756 store(p->r2, &sv);
1759 /* mark that stack entry as being saved on the stack */
1760 if (p->r & VT_LVAL) {
1761 /* also clear the bounded flag because the
1762 relocation address of the function was stored in
1763 p->c.i */
1764 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
1765 } else {
1766 p->r = VT_LVAL | VT_LOCAL;
1768 p->r2 = VT_CONST;
1769 p->c.i = l;
1774 #ifdef TCC_TARGET_ARM
1775 /* find a register of class 'rc2' with at most one reference on stack.
1776 * If none, call get_reg(rc) */
1777 ST_FUNC int get_reg_ex(int rc, int rc2)
1779 int r;
1780 SValue *p;
1782 for(r=0;r<NB_REGS;r++) {
1783 if (reg_classes[r] & rc2) {
1784 int n;
1785 n=0;
1786 for(p = vstack; p <= vtop; p++) {
1787 if ((p->r & VT_VALMASK) == r ||
1788 p->r2 == r)
1789 n++;
1791 if (n <= 1)
1792 return r;
1795 return get_reg(rc);
1797 #endif
1799 /* find a free register of class 'rc'. If none, save one register */
1800 ST_FUNC int get_reg(int rc)
1802 int r;
1803 SValue *p;
1805 /* find a free register */
1806 for(r=0;r<NB_REGS;r++) {
1807 if (reg_classes[r] & rc) {
1808 if (nocode_wanted)
1809 return r;
1810 for(p=vstack;p<=vtop;p++) {
1811 if ((p->r & VT_VALMASK) == r ||
1812 p->r2 == r)
1813 goto notfound;
1815 return r;
1817 notfound: ;
1820 /* no register left : free the first one on the stack (VERY
1821 IMPORTANT to start from the bottom to ensure that we don't
1822 spill registers used in gen_opi()) */
1823 for(p=vstack;p<=vtop;p++) {
1824 /* look at second register (if long long) */
1825 r = p->r2;
1826 if (r < VT_CONST && (reg_classes[r] & rc))
1827 goto save_found;
1828 r = p->r & VT_VALMASK;
1829 if (r < VT_CONST && (reg_classes[r] & rc)) {
1830 save_found:
1831 save_reg(r);
1832 return r;
1835 /* Should never comes here */
1836 return -1;
1839 /* find a free temporary local variable (return the offset on stack) match the size and align. If none, add new temporary stack variable*/
1840 static int get_temp_local_var(int size,int align){
1841 int i;
1842 struct temp_local_variable *temp_var;
1843 int found_var;
1844 SValue *p;
1845 int r;
1846 char free;
1847 char found;
1848 found=0;
1849 for(i=0;i<nb_temp_local_vars;i++){
1850 temp_var=&arr_temp_local_vars[i];
1851 if(temp_var->size<size||align!=temp_var->align){
1852 continue;
1854 /*check if temp_var is free*/
1855 free=1;
1856 for(p=vstack;p<=vtop;p++) {
1857 r=p->r&VT_VALMASK;
1858 if(r==VT_LOCAL||r==VT_LLOCAL){
1859 if(p->c.i==temp_var->location){
1860 free=0;
1861 break;
1865 if(free){
1866 found_var=temp_var->location;
1867 found=1;
1868 break;
1871 if(!found){
1872 loc = (loc - size) & -align;
1873 if(nb_temp_local_vars<MAX_TEMP_LOCAL_VARIABLE_NUMBER){
1874 temp_var=&arr_temp_local_vars[i];
1875 temp_var->location=loc;
1876 temp_var->size=size;
1877 temp_var->align=align;
1878 nb_temp_local_vars++;
1880 found_var=loc;
1882 return found_var;
1885 static void clear_temp_local_var_list(){
1886 nb_temp_local_vars=0;
1889 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
1890 if needed */
1891 static void move_reg(int r, int s, int t)
1893 SValue sv;
1895 if (r != s) {
1896 save_reg(r);
1897 sv.type.t = t;
1898 sv.type.ref = NULL;
1899 sv.r = s;
1900 sv.c.i = 0;
1901 load(r, &sv);
1905 /* get address of vtop (vtop MUST BE an lvalue) */
1906 ST_FUNC void gaddrof(void)
1908 vtop->r &= ~VT_LVAL;
1909 /* tricky: if saved lvalue, then we can go back to lvalue */
1910 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
1911 vtop->r = (vtop->r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
1914 #ifdef CONFIG_TCC_BCHECK
1915 /* generate lvalue bound code */
1916 static void gbound(void)
1918 CType type1;
1920 vtop->r &= ~VT_MUSTBOUND;
1921 /* if lvalue, then use checking code before dereferencing */
1922 if (vtop->r & VT_LVAL) {
1923 /* if not VT_BOUNDED value, then make one */
1924 if (!(vtop->r & VT_BOUNDED)) {
1925 /* must save type because we must set it to int to get pointer */
1926 type1 = vtop->type;
1927 vtop->type.t = VT_PTR;
1928 gaddrof();
1929 vpushi(0);
1930 gen_bounded_ptr_add();
1931 vtop->r |= VT_LVAL;
1932 vtop->type = type1;
1934 /* then check for dereferencing */
1935 gen_bounded_ptr_deref();
1939 /* we need to call __bound_ptr_add before we start to load function
1940 args into registers */
1941 ST_FUNC void gbound_args(int nb_args)
1943 int i;
1944 for (i = 1; i <= nb_args; ++i)
1945 if (vtop[1 - i].r & VT_MUSTBOUND) {
1946 vrotb(i);
1947 gbound();
1948 vrott(i);
1952 /* Add bounds for local symbols from S to E (via ->prev) */
1953 static void add_local_bounds(Sym *s, Sym *e)
1955 for (; s != e; s = s->prev) {
1956 if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL)
1957 continue;
1958 /* Add arrays/structs/unions because we always take address */
1959 if ((s->type.t & VT_ARRAY)
1960 || (s->type.t & VT_BTYPE) == VT_STRUCT
1961 || s->a.addrtaken) {
1962 /* add local bound info */
1963 int align, size = type_size(&s->type, &align);
1964 addr_t *bounds_ptr = section_ptr_add(lbounds_section,
1965 2 * sizeof(addr_t));
1966 bounds_ptr[0] = s->c;
1967 bounds_ptr[1] = size;
1971 #endif
1973 /* Wrapper around sym_pop, that potentially also registers local bounds. */
1974 static void pop_local_syms(Sym **ptop, Sym *b, int keep, int ellipsis)
1976 #ifdef CONFIG_TCC_BCHECK
1977 if (tcc_state->do_bounds_check && !ellipsis && !keep)
1978 add_local_bounds(*ptop, b);
1979 #endif
1980 if (tcc_state->do_debug)
1981 tcc_add_debug_info (tcc_state, !local_scope, *ptop, b);
1982 sym_pop(ptop, b, keep);
1985 static void incr_bf_adr(int o)
1987 vtop->type = char_pointer_type;
1988 gaddrof();
1989 vpushs(o);
1990 gen_op('+');
1991 vtop->type.t = VT_BYTE | VT_UNSIGNED;
1992 vtop->r |= VT_LVAL;
1995 /* single-byte load mode for packed or otherwise unaligned bitfields */
1996 static void load_packed_bf(CType *type, int bit_pos, int bit_size)
1998 int n, o, bits;
1999 save_reg_upstack(vtop->r, 1);
2000 vpush64(type->t & VT_BTYPE, 0); // B X
2001 bits = 0, o = bit_pos >> 3, bit_pos &= 7;
2002 do {
2003 vswap(); // X B
2004 incr_bf_adr(o);
2005 vdup(); // X B B
2006 n = 8 - bit_pos;
2007 if (n > bit_size)
2008 n = bit_size;
2009 if (bit_pos)
2010 vpushi(bit_pos), gen_op(TOK_SHR), bit_pos = 0; // X B Y
2011 if (n < 8)
2012 vpushi((1 << n) - 1), gen_op('&');
2013 gen_cast(type);
2014 if (bits)
2015 vpushi(bits), gen_op(TOK_SHL);
2016 vrotb(3); // B Y X
2017 gen_op('|'); // B X
2018 bits += n, bit_size -= n, o = 1;
2019 } while (bit_size);
2020 vswap(), vpop();
2021 if (!(type->t & VT_UNSIGNED)) {
2022 n = ((type->t & VT_BTYPE) == VT_LLONG ? 64 : 32) - bits;
2023 vpushi(n), gen_op(TOK_SHL);
2024 vpushi(n), gen_op(TOK_SAR);
2028 /* single-byte store mode for packed or otherwise unaligned bitfields */
2029 static void store_packed_bf(int bit_pos, int bit_size)
2031 int bits, n, o, m, c;
2033 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2034 vswap(); // X B
2035 save_reg_upstack(vtop->r, 1);
2036 bits = 0, o = bit_pos >> 3, bit_pos &= 7;
2037 do {
2038 incr_bf_adr(o); // X B
2039 vswap(); //B X
2040 c ? vdup() : gv_dup(); // B V X
2041 vrott(3); // X B V
2042 if (bits)
2043 vpushi(bits), gen_op(TOK_SHR);
2044 if (bit_pos)
2045 vpushi(bit_pos), gen_op(TOK_SHL);
2046 n = 8 - bit_pos;
2047 if (n > bit_size)
2048 n = bit_size;
2049 if (n < 8) {
2050 m = ((1 << n) - 1) << bit_pos;
2051 vpushi(m), gen_op('&'); // X B V1
2052 vpushv(vtop-1); // X B V1 B
2053 vpushi(m & 0x80 ? ~m & 0x7f : ~m);
2054 gen_op('&'); // X B V1 B1
2055 gen_op('|'); // X B V2
2057 vdup(), vtop[-1] = vtop[-2]; // X B B V2
2058 vstore(), vpop(); // X B
2059 bits += n, bit_size -= n, bit_pos = 0, o = 1;
2060 } while (bit_size);
2061 vpop(), vpop();
2064 static int adjust_bf(SValue *sv, int bit_pos, int bit_size)
2066 int t;
2067 if (0 == sv->type.ref)
2068 return 0;
2069 t = sv->type.ref->auxtype;
2070 if (t != -1 && t != VT_STRUCT) {
2071 sv->type.t = (sv->type.t & ~VT_BTYPE) | t;
2072 sv->r |= VT_LVAL;
2074 return t;
2077 /* store vtop a register belonging to class 'rc'. lvalues are
2078 converted to values. Cannot be used if cannot be converted to
2079 register value (such as structures). */
2080 ST_FUNC int gv(int rc)
2082 int r, r2, r_ok, r2_ok, rc2, bt;
2083 int bit_pos, bit_size, size, align;
2085 /* NOTE: get_reg can modify vstack[] */
2086 if (vtop->type.t & VT_BITFIELD) {
2087 CType type;
2089 bit_pos = BIT_POS(vtop->type.t);
2090 bit_size = BIT_SIZE(vtop->type.t);
2091 /* remove bit field info to avoid loops */
2092 vtop->type.t &= ~VT_STRUCT_MASK;
2094 type.ref = NULL;
2095 type.t = vtop->type.t & VT_UNSIGNED;
2096 if ((vtop->type.t & VT_BTYPE) == VT_BOOL)
2097 type.t |= VT_UNSIGNED;
2099 r = adjust_bf(vtop, bit_pos, bit_size);
2101 if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
2102 type.t |= VT_LLONG;
2103 else
2104 type.t |= VT_INT;
2106 if (r == VT_STRUCT) {
2107 load_packed_bf(&type, bit_pos, bit_size);
2108 } else {
2109 int bits = (type.t & VT_BTYPE) == VT_LLONG ? 64 : 32;
2110 /* cast to int to propagate signedness in following ops */
2111 gen_cast(&type);
2112 /* generate shifts */
2113 vpushi(bits - (bit_pos + bit_size));
2114 gen_op(TOK_SHL);
2115 vpushi(bits - bit_size);
2116 /* NOTE: transformed to SHR if unsigned */
2117 gen_op(TOK_SAR);
2119 r = gv(rc);
2120 } else {
2121 if (is_float(vtop->type.t) &&
2122 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2123 unsigned long offset;
2124 /* CPUs usually cannot use float constants, so we store them
2125 generically in data segment */
2126 size = type_size(&vtop->type, &align);
2127 if (NODATA_WANTED)
2128 size = 0, align = 1;
2129 offset = section_add(data_section, size, align);
2130 vpush_ref(&vtop->type, data_section, offset, size);
2131 vswap();
2132 init_putv(&vtop->type, data_section, offset);
2133 vtop->r |= VT_LVAL;
2135 #ifdef CONFIG_TCC_BCHECK
2136 if (vtop->r & VT_MUSTBOUND)
2137 gbound();
2138 #endif
2140 bt = vtop->type.t & VT_BTYPE;
2142 #ifdef TCC_TARGET_RISCV64
2143 /* XXX mega hack */
2144 if (bt == VT_LDOUBLE && rc == RC_FLOAT)
2145 rc = RC_INT;
2146 #endif
2147 rc2 = RC2_TYPE(bt, rc);
2149 /* need to reload if:
2150 - constant
2151 - lvalue (need to dereference pointer)
2152 - already a register, but not in the right class */
2153 r = vtop->r & VT_VALMASK;
2154 r_ok = !(vtop->r & VT_LVAL) && (r < VT_CONST) && (reg_classes[r] & rc);
2155 r2_ok = !rc2 || ((vtop->r2 < VT_CONST) && (reg_classes[vtop->r2] & rc2));
2157 if (!r_ok || !r2_ok) {
2158 if (!r_ok)
2159 r = get_reg(rc);
2160 if (rc2) {
2161 int load_type = (bt == VT_QFLOAT) ? VT_DOUBLE : VT_PTRDIFF_T;
2162 int original_type = vtop->type.t;
2164 /* two register type load :
2165 expand to two words temporarily */
2166 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2167 /* load constant */
2168 unsigned long long ll = vtop->c.i;
2169 vtop->c.i = ll; /* first word */
2170 load(r, vtop);
2171 vtop->r = r; /* save register value */
2172 vpushi(ll >> 32); /* second word */
2173 } else if (vtop->r & VT_LVAL) {
2174 /* We do not want to modifier the long long pointer here.
2175 So we save any other instances down the stack */
2176 save_reg_upstack(vtop->r, 1);
2177 /* load from memory */
2178 vtop->type.t = load_type;
2179 load(r, vtop);
2180 vdup();
2181 vtop[-1].r = r; /* save register value */
2182 /* increment pointer to get second word */
2183 vtop->type.t = VT_PTRDIFF_T;
2184 gaddrof();
2185 vpushs(PTR_SIZE);
2186 gen_op('+');
2187 vtop->r |= VT_LVAL;
2188 vtop->type.t = load_type;
2189 } else {
2190 /* move registers */
2191 if (!r_ok)
2192 load(r, vtop);
2193 if (r2_ok && vtop->r2 < VT_CONST)
2194 goto done;
2195 vdup();
2196 vtop[-1].r = r; /* save register value */
2197 vtop->r = vtop[-1].r2;
2199 /* Allocate second register. Here we rely on the fact that
2200 get_reg() tries first to free r2 of an SValue. */
2201 r2 = get_reg(rc2);
2202 load(r2, vtop);
2203 vpop();
2204 /* write second register */
2205 vtop->r2 = r2;
2206 done:
2207 vtop->type.t = original_type;
2208 } else {
2209 if (vtop->r == VT_CMP)
2210 vset_VT_JMP();
2211 /* one register type load */
2212 load(r, vtop);
2215 vtop->r = r;
2216 #ifdef TCC_TARGET_C67
2217 /* uses register pairs for doubles */
2218 if (bt == VT_DOUBLE)
2219 vtop->r2 = r+1;
2220 #endif
2222 return r;
2225 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2226 ST_FUNC void gv2(int rc1, int rc2)
2228 /* generate more generic register first. But VT_JMP or VT_CMP
2229 values must be generated first in all cases to avoid possible
2230 reload errors */
2231 if (vtop->r != VT_CMP && rc1 <= rc2) {
2232 vswap();
2233 gv(rc1);
2234 vswap();
2235 gv(rc2);
2236 /* test if reload is needed for first register */
2237 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2238 vswap();
2239 gv(rc1);
2240 vswap();
2242 } else {
2243 gv(rc2);
2244 vswap();
2245 gv(rc1);
2246 vswap();
2247 /* test if reload is needed for first register */
2248 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
2249 gv(rc2);
2254 #if PTR_SIZE == 4
2255 /* expand 64bit on stack in two ints */
2256 ST_FUNC void lexpand(void)
2258 int u, v;
2259 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
2260 v = vtop->r & (VT_VALMASK | VT_LVAL);
2261 if (v == VT_CONST) {
2262 vdup();
2263 vtop[0].c.i >>= 32;
2264 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
2265 vdup();
2266 vtop[0].c.i += 4;
2267 } else {
2268 gv(RC_INT);
2269 vdup();
2270 vtop[0].r = vtop[-1].r2;
2271 vtop[0].r2 = vtop[-1].r2 = VT_CONST;
2273 vtop[0].type.t = vtop[-1].type.t = VT_INT | u;
2275 #endif
2277 #if PTR_SIZE == 4
2278 /* build a long long from two ints */
2279 static void lbuild(int t)
2281 gv2(RC_INT, RC_INT);
2282 vtop[-1].r2 = vtop[0].r;
2283 vtop[-1].type.t = t;
2284 vpop();
2286 #endif
2288 /* convert stack entry to register and duplicate its value in another
2289 register */
2290 static void gv_dup(void)
2292 int t, rc, r;
2294 t = vtop->type.t;
2295 #if PTR_SIZE == 4
2296 if ((t & VT_BTYPE) == VT_LLONG) {
2297 if (t & VT_BITFIELD) {
2298 gv(RC_INT);
2299 t = vtop->type.t;
2301 lexpand();
2302 gv_dup();
2303 vswap();
2304 vrotb(3);
2305 gv_dup();
2306 vrotb(4);
2307 /* stack: H L L1 H1 */
2308 lbuild(t);
2309 vrotb(3);
2310 vrotb(3);
2311 vswap();
2312 lbuild(t);
2313 vswap();
2314 return;
2316 #endif
2317 /* duplicate value */
2318 rc = RC_TYPE(t);
2319 gv(rc);
2320 r = get_reg(rc);
2321 vdup();
2322 load(r, vtop);
2323 vtop->r = r;
2326 #if PTR_SIZE == 4
2327 /* generate CPU independent (unsigned) long long operations */
2328 static void gen_opl(int op)
2330 int t, a, b, op1, c, i;
2331 int func;
2332 unsigned short reg_iret = REG_IRET;
2333 unsigned short reg_lret = REG_IRE2;
2334 SValue tmp;
2336 switch(op) {
2337 case '/':
2338 case TOK_PDIV:
2339 func = TOK___divdi3;
2340 goto gen_func;
2341 case TOK_UDIV:
2342 func = TOK___udivdi3;
2343 goto gen_func;
2344 case '%':
2345 func = TOK___moddi3;
2346 goto gen_mod_func;
2347 case TOK_UMOD:
2348 func = TOK___umoddi3;
2349 gen_mod_func:
2350 #ifdef TCC_ARM_EABI
2351 reg_iret = TREG_R2;
2352 reg_lret = TREG_R3;
2353 #endif
2354 gen_func:
2355 /* call generic long long function */
2356 vpush_global_sym(&func_old_type, func);
2357 vrott(3);
2358 gfunc_call(2);
2359 vpushi(0);
2360 vtop->r = reg_iret;
2361 vtop->r2 = reg_lret;
2362 break;
2363 case '^':
2364 case '&':
2365 case '|':
2366 case '*':
2367 case '+':
2368 case '-':
2369 //pv("gen_opl A",0,2);
2370 t = vtop->type.t;
2371 vswap();
2372 lexpand();
2373 vrotb(3);
2374 lexpand();
2375 /* stack: L1 H1 L2 H2 */
2376 tmp = vtop[0];
2377 vtop[0] = vtop[-3];
2378 vtop[-3] = tmp;
2379 tmp = vtop[-2];
2380 vtop[-2] = vtop[-3];
2381 vtop[-3] = tmp;
2382 vswap();
2383 /* stack: H1 H2 L1 L2 */
2384 //pv("gen_opl B",0,4);
2385 if (op == '*') {
2386 vpushv(vtop - 1);
2387 vpushv(vtop - 1);
2388 gen_op(TOK_UMULL);
2389 lexpand();
2390 /* stack: H1 H2 L1 L2 ML MH */
2391 for(i=0;i<4;i++)
2392 vrotb(6);
2393 /* stack: ML MH H1 H2 L1 L2 */
2394 tmp = vtop[0];
2395 vtop[0] = vtop[-2];
2396 vtop[-2] = tmp;
2397 /* stack: ML MH H1 L2 H2 L1 */
2398 gen_op('*');
2399 vrotb(3);
2400 vrotb(3);
2401 gen_op('*');
2402 /* stack: ML MH M1 M2 */
2403 gen_op('+');
2404 gen_op('+');
2405 } else if (op == '+' || op == '-') {
2406 /* XXX: add non carry method too (for MIPS or alpha) */
2407 if (op == '+')
2408 op1 = TOK_ADDC1;
2409 else
2410 op1 = TOK_SUBC1;
2411 gen_op(op1);
2412 /* stack: H1 H2 (L1 op L2) */
2413 vrotb(3);
2414 vrotb(3);
2415 gen_op(op1 + 1); /* TOK_xxxC2 */
2416 } else {
2417 gen_op(op);
2418 /* stack: H1 H2 (L1 op L2) */
2419 vrotb(3);
2420 vrotb(3);
2421 /* stack: (L1 op L2) H1 H2 */
2422 gen_op(op);
2423 /* stack: (L1 op L2) (H1 op H2) */
2425 /* stack: L H */
2426 lbuild(t);
2427 break;
2428 case TOK_SAR:
2429 case TOK_SHR:
2430 case TOK_SHL:
2431 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
2432 t = vtop[-1].type.t;
2433 vswap();
2434 lexpand();
2435 vrotb(3);
2436 /* stack: L H shift */
2437 c = (int)vtop->c.i;
2438 /* constant: simpler */
2439 /* NOTE: all comments are for SHL. the other cases are
2440 done by swapping words */
2441 vpop();
2442 if (op != TOK_SHL)
2443 vswap();
2444 if (c >= 32) {
2445 /* stack: L H */
2446 vpop();
2447 if (c > 32) {
2448 vpushi(c - 32);
2449 gen_op(op);
2451 if (op != TOK_SAR) {
2452 vpushi(0);
2453 } else {
2454 gv_dup();
2455 vpushi(31);
2456 gen_op(TOK_SAR);
2458 vswap();
2459 } else {
2460 vswap();
2461 gv_dup();
2462 /* stack: H L L */
2463 vpushi(c);
2464 gen_op(op);
2465 vswap();
2466 vpushi(32 - c);
2467 if (op == TOK_SHL)
2468 gen_op(TOK_SHR);
2469 else
2470 gen_op(TOK_SHL);
2471 vrotb(3);
2472 /* stack: L L H */
2473 vpushi(c);
2474 if (op == TOK_SHL)
2475 gen_op(TOK_SHL);
2476 else
2477 gen_op(TOK_SHR);
2478 gen_op('|');
2480 if (op != TOK_SHL)
2481 vswap();
2482 lbuild(t);
2483 } else {
2484 /* XXX: should provide a faster fallback on x86 ? */
2485 switch(op) {
2486 case TOK_SAR:
2487 func = TOK___ashrdi3;
2488 goto gen_func;
2489 case TOK_SHR:
2490 func = TOK___lshrdi3;
2491 goto gen_func;
2492 case TOK_SHL:
2493 func = TOK___ashldi3;
2494 goto gen_func;
2497 break;
2498 default:
2499 /* compare operations */
2500 t = vtop->type.t;
2501 vswap();
2502 lexpand();
2503 vrotb(3);
2504 lexpand();
2505 /* stack: L1 H1 L2 H2 */
2506 tmp = vtop[-1];
2507 vtop[-1] = vtop[-2];
2508 vtop[-2] = tmp;
2509 /* stack: L1 L2 H1 H2 */
2510 save_regs(4);
2511 /* compare high */
2512 op1 = op;
2513 /* when values are equal, we need to compare low words. since
2514 the jump is inverted, we invert the test too. */
2515 if (op1 == TOK_LT)
2516 op1 = TOK_LE;
2517 else if (op1 == TOK_GT)
2518 op1 = TOK_GE;
2519 else if (op1 == TOK_ULT)
2520 op1 = TOK_ULE;
2521 else if (op1 == TOK_UGT)
2522 op1 = TOK_UGE;
2523 a = 0;
2524 b = 0;
2525 gen_op(op1);
2526 if (op == TOK_NE) {
2527 b = gvtst(0, 0);
2528 } else {
2529 a = gvtst(1, 0);
2530 if (op != TOK_EQ) {
2531 /* generate non equal test */
2532 vpushi(0);
2533 vset_VT_CMP(TOK_NE);
2534 b = gvtst(0, 0);
2537 /* compare low. Always unsigned */
2538 op1 = op;
2539 if (op1 == TOK_LT)
2540 op1 = TOK_ULT;
2541 else if (op1 == TOK_LE)
2542 op1 = TOK_ULE;
2543 else if (op1 == TOK_GT)
2544 op1 = TOK_UGT;
2545 else if (op1 == TOK_GE)
2546 op1 = TOK_UGE;
2547 gen_op(op1);
2548 #if 0//def TCC_TARGET_I386
2549 if (op == TOK_NE) { gsym(b); break; }
2550 if (op == TOK_EQ) { gsym(a); break; }
2551 #endif
2552 gvtst_set(1, a);
2553 gvtst_set(0, b);
2554 break;
2557 #endif
2559 static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
2561 uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
2562 return (a ^ b) >> 63 ? -x : x;
2565 static int gen_opic_lt(uint64_t a, uint64_t b)
2567 return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
2570 /* handle integer constant optimizations and various machine
2571 independent opt */
2572 static void gen_opic(int op)
2574 SValue *v1 = vtop - 1;
2575 SValue *v2 = vtop;
2576 int t1 = v1->type.t & VT_BTYPE;
2577 int t2 = v2->type.t & VT_BTYPE;
2578 int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2579 int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2580 uint64_t l1 = c1 ? v1->c.i : 0;
2581 uint64_t l2 = c2 ? v2->c.i : 0;
2582 int shm = (t1 == VT_LLONG) ? 63 : 31;
2584 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
2585 l1 = ((uint32_t)l1 |
2586 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
2587 if (t2 != VT_LLONG && (PTR_SIZE != 8 || t2 != VT_PTR))
2588 l2 = ((uint32_t)l2 |
2589 (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
2591 if (c1 && c2) {
2592 switch(op) {
2593 case '+': l1 += l2; break;
2594 case '-': l1 -= l2; break;
2595 case '&': l1 &= l2; break;
2596 case '^': l1 ^= l2; break;
2597 case '|': l1 |= l2; break;
2598 case '*': l1 *= l2; break;
2600 case TOK_PDIV:
2601 case '/':
2602 case '%':
2603 case TOK_UDIV:
2604 case TOK_UMOD:
2605 /* if division by zero, generate explicit division */
2606 if (l2 == 0) {
2607 if (const_wanted && !(nocode_wanted & unevalmask))
2608 tcc_error("division by zero in constant");
2609 goto general_case;
2611 switch(op) {
2612 default: l1 = gen_opic_sdiv(l1, l2); break;
2613 case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
2614 case TOK_UDIV: l1 = l1 / l2; break;
2615 case TOK_UMOD: l1 = l1 % l2; break;
2617 break;
2618 case TOK_SHL: l1 <<= (l2 & shm); break;
2619 case TOK_SHR: l1 >>= (l2 & shm); break;
2620 case TOK_SAR:
2621 l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
2622 break;
2623 /* tests */
2624 case TOK_ULT: l1 = l1 < l2; break;
2625 case TOK_UGE: l1 = l1 >= l2; break;
2626 case TOK_EQ: l1 = l1 == l2; break;
2627 case TOK_NE: l1 = l1 != l2; break;
2628 case TOK_ULE: l1 = l1 <= l2; break;
2629 case TOK_UGT: l1 = l1 > l2; break;
2630 case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
2631 case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
2632 case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
2633 case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
2634 /* logical */
2635 case TOK_LAND: l1 = l1 && l2; break;
2636 case TOK_LOR: l1 = l1 || l2; break;
2637 default:
2638 goto general_case;
2640 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
2641 l1 = ((uint32_t)l1 |
2642 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
2643 v1->c.i = l1;
2644 vtop--;
2645 } else {
2646 /* if commutative ops, put c2 as constant */
2647 if (c1 && (op == '+' || op == '&' || op == '^' ||
2648 op == '|' || op == '*' || op == TOK_EQ || op == TOK_NE)) {
2649 vswap();
2650 c2 = c1; //c = c1, c1 = c2, c2 = c;
2651 l2 = l1; //l = l1, l1 = l2, l2 = l;
2653 if (!const_wanted &&
2654 c1 && ((l1 == 0 &&
2655 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
2656 (l1 == -1 && op == TOK_SAR))) {
2657 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
2658 vtop--;
2659 } else if (!const_wanted &&
2660 c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
2661 (op == '|' &&
2662 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||
2663 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
2664 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
2665 if (l2 == 1)
2666 vtop->c.i = 0;
2667 vswap();
2668 vtop--;
2669 } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
2670 op == TOK_PDIV) &&
2671 l2 == 1) ||
2672 ((op == '+' || op == '-' || op == '|' || op == '^' ||
2673 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
2674 l2 == 0) ||
2675 (op == '&' &&
2676 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {
2677 /* filter out NOP operations like x*1, x-0, x&-1... */
2678 vtop--;
2679 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
2680 /* try to use shifts instead of muls or divs */
2681 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
2682 int n = -1;
2683 while (l2) {
2684 l2 >>= 1;
2685 n++;
2687 vtop->c.i = n;
2688 if (op == '*')
2689 op = TOK_SHL;
2690 else if (op == TOK_PDIV)
2691 op = TOK_SAR;
2692 else
2693 op = TOK_SHR;
2695 goto general_case;
2696 } else if (c2 && (op == '+' || op == '-') &&
2697 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
2698 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
2699 /* symbol + constant case */
2700 if (op == '-')
2701 l2 = -l2;
2702 l2 += vtop[-1].c.i;
2703 /* The backends can't always deal with addends to symbols
2704 larger than +-1<<31. Don't construct such. */
2705 if ((int)l2 != l2)
2706 goto general_case;
2707 vtop--;
2708 vtop->c.i = l2;
2709 } else {
2710 general_case:
2711 /* call low level op generator */
2712 if (t1 == VT_LLONG || t2 == VT_LLONG ||
2713 (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
2714 gen_opl(op);
2715 else
2716 gen_opi(op);
2721 /* generate a floating point operation with constant propagation */
2722 static void gen_opif(int op)
2724 int c1, c2;
2725 SValue *v1, *v2;
2726 #if defined _MSC_VER && defined __x86_64__
2727 /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
2728 volatile
2729 #endif
2730 long double f1, f2;
2732 v1 = vtop - 1;
2733 v2 = vtop;
2734 /* currently, we cannot do computations with forward symbols */
2735 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2736 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2737 if (c1 && c2) {
2738 if (v1->type.t == VT_FLOAT) {
2739 f1 = v1->c.f;
2740 f2 = v2->c.f;
2741 } else if (v1->type.t == VT_DOUBLE) {
2742 f1 = v1->c.d;
2743 f2 = v2->c.d;
2744 } else {
2745 f1 = v1->c.ld;
2746 f2 = v2->c.ld;
2749 /* NOTE: we only do constant propagation if finite number (not
2750 NaN or infinity) (ANSI spec) */
2751 if (!ieee_finite(f1) || !ieee_finite(f2))
2752 goto general_case;
2754 switch(op) {
2755 case '+': f1 += f2; break;
2756 case '-': f1 -= f2; break;
2757 case '*': f1 *= f2; break;
2758 case '/':
2759 if (f2 == 0.0) {
2760 /* If not in initializer we need to potentially generate
2761 FP exceptions at runtime, otherwise we want to fold. */
2762 if (!const_wanted)
2763 goto general_case;
2765 f1 /= f2;
2766 break;
2767 /* XXX: also handles tests ? */
2768 default:
2769 goto general_case;
2771 /* XXX: overflow test ? */
2772 if (v1->type.t == VT_FLOAT) {
2773 v1->c.f = f1;
2774 } else if (v1->type.t == VT_DOUBLE) {
2775 v1->c.d = f1;
2776 } else {
2777 v1->c.ld = f1;
2779 vtop--;
2780 } else {
2781 general_case:
2782 gen_opf(op);
2786 /* print a type. If 'varstr' is not NULL, then the variable is also
2787 printed in the type */
2788 /* XXX: union */
2789 /* XXX: add array and function pointers */
2790 static void type_to_str(char *buf, int buf_size,
2791 CType *type, const char *varstr)
2793 int bt, v, t;
2794 Sym *s, *sa;
2795 char buf1[256];
2796 const char *tstr;
2798 t = type->t;
2799 bt = t & VT_BTYPE;
2800 buf[0] = '\0';
2802 if (t & VT_EXTERN)
2803 pstrcat(buf, buf_size, "extern ");
2804 if (t & VT_STATIC)
2805 pstrcat(buf, buf_size, "static ");
2806 if (t & VT_TYPEDEF)
2807 pstrcat(buf, buf_size, "typedef ");
2808 if (t & VT_INLINE)
2809 pstrcat(buf, buf_size, "inline ");
2810 if (t & VT_VOLATILE)
2811 pstrcat(buf, buf_size, "volatile ");
2812 if (t & VT_CONSTANT)
2813 pstrcat(buf, buf_size, "const ");
2815 if (((t & VT_DEFSIGN) && bt == VT_BYTE)
2816 || ((t & VT_UNSIGNED)
2817 && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
2818 && !IS_ENUM(t)
2820 pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed ");
2822 buf_size -= strlen(buf);
2823 buf += strlen(buf);
2825 switch(bt) {
2826 case VT_VOID:
2827 tstr = "void";
2828 goto add_tstr;
2829 case VT_BOOL:
2830 tstr = "_Bool";
2831 goto add_tstr;
2832 case VT_BYTE:
2833 tstr = "char";
2834 goto add_tstr;
2835 case VT_SHORT:
2836 tstr = "short";
2837 goto add_tstr;
2838 case VT_INT:
2839 tstr = "int";
2840 goto maybe_long;
2841 case VT_LLONG:
2842 tstr = "long long";
2843 maybe_long:
2844 if (t & VT_LONG)
2845 tstr = "long";
2846 if (!IS_ENUM(t))
2847 goto add_tstr;
2848 tstr = "enum ";
2849 goto tstruct;
2850 case VT_FLOAT:
2851 tstr = "float";
2852 goto add_tstr;
2853 case VT_DOUBLE:
2854 tstr = "double";
2855 if (!(t & VT_LONG))
2856 goto add_tstr;
2857 case VT_LDOUBLE:
2858 tstr = "long double";
2859 add_tstr:
2860 pstrcat(buf, buf_size, tstr);
2861 break;
2862 case VT_STRUCT:
2863 tstr = "struct ";
2864 if (IS_UNION(t))
2865 tstr = "union ";
2866 tstruct:
2867 pstrcat(buf, buf_size, tstr);
2868 v = type->ref->v & ~SYM_STRUCT;
2869 if (v >= SYM_FIRST_ANOM)
2870 pstrcat(buf, buf_size, "<anonymous>");
2871 else
2872 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2873 break;
2874 case VT_FUNC:
2875 s = type->ref;
2876 buf1[0]=0;
2877 if (varstr && '*' == *varstr) {
2878 pstrcat(buf1, sizeof(buf1), "(");
2879 pstrcat(buf1, sizeof(buf1), varstr);
2880 pstrcat(buf1, sizeof(buf1), ")");
2882 pstrcat(buf1, buf_size, "(");
2883 sa = s->next;
2884 while (sa != NULL) {
2885 char buf2[256];
2886 type_to_str(buf2, sizeof(buf2), &sa->type, NULL);
2887 pstrcat(buf1, sizeof(buf1), buf2);
2888 sa = sa->next;
2889 if (sa)
2890 pstrcat(buf1, sizeof(buf1), ", ");
2892 if (s->f.func_type == FUNC_ELLIPSIS)
2893 pstrcat(buf1, sizeof(buf1), ", ...");
2894 pstrcat(buf1, sizeof(buf1), ")");
2895 type_to_str(buf, buf_size, &s->type, buf1);
2896 goto no_var;
2897 case VT_PTR:
2898 s = type->ref;
2899 if (t & VT_ARRAY) {
2900 if (varstr && '*' == *varstr)
2901 snprintf(buf1, sizeof(buf1), "(%s)[%d]", varstr, s->c);
2902 else
2903 snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c);
2904 type_to_str(buf, buf_size, &s->type, buf1);
2905 goto no_var;
2907 pstrcpy(buf1, sizeof(buf1), "*");
2908 if (t & VT_CONSTANT)
2909 pstrcat(buf1, buf_size, "const ");
2910 if (t & VT_VOLATILE)
2911 pstrcat(buf1, buf_size, "volatile ");
2912 if (varstr)
2913 pstrcat(buf1, sizeof(buf1), varstr);
2914 type_to_str(buf, buf_size, &s->type, buf1);
2915 goto no_var;
2917 if (varstr) {
2918 pstrcat(buf, buf_size, " ");
2919 pstrcat(buf, buf_size, varstr);
2921 no_var: ;
2924 static void type_incompatibility_error(CType* st, CType* dt, const char* fmt)
2926 char buf1[256], buf2[256];
2927 type_to_str(buf1, sizeof(buf1), st, NULL);
2928 type_to_str(buf2, sizeof(buf2), dt, NULL);
2929 tcc_error(fmt, buf1, buf2);
2932 static void type_incompatibility_warning(CType* st, CType* dt, const char* fmt)
2934 char buf1[256], buf2[256];
2935 type_to_str(buf1, sizeof(buf1), st, NULL);
2936 type_to_str(buf2, sizeof(buf2), dt, NULL);
2937 tcc_warning(fmt, buf1, buf2);
2940 static int pointed_size(CType *type)
2942 int align;
2943 return type_size(pointed_type(type), &align);
2946 static void vla_runtime_pointed_size(CType *type)
2948 int align;
2949 vla_runtime_type_size(pointed_type(type), &align);
2952 static inline int is_null_pointer(SValue *p)
2954 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
2955 return 0;
2956 return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
2957 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
2958 ((p->type.t & VT_BTYPE) == VT_PTR &&
2959 (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0) &&
2960 ((pointed_type(&p->type)->t & VT_BTYPE) == VT_VOID) &&
2961 0 == (pointed_type(&p->type)->t & (VT_CONSTANT | VT_VOLATILE))
2965 /* compare function types. OLD functions match any new functions */
2966 static int is_compatible_func(CType *type1, CType *type2)
2968 Sym *s1, *s2;
2970 s1 = type1->ref;
2971 s2 = type2->ref;
2972 if (s1->f.func_call != s2->f.func_call)
2973 return 0;
2974 if (s1->f.func_type != s2->f.func_type
2975 && s1->f.func_type != FUNC_OLD
2976 && s2->f.func_type != FUNC_OLD)
2977 return 0;
2978 /* we should check the function return type for FUNC_OLD too
2979 but that causes problems with the internally used support
2980 functions such as TOK_memmove */
2981 if (s1->f.func_type == FUNC_OLD && !s1->next)
2982 return 1;
2983 if (s2->f.func_type == FUNC_OLD && !s2->next)
2984 return 1;
2985 for (;;) {
2986 if (!is_compatible_unqualified_types(&s1->type, &s2->type))
2987 return 0;
2988 s1 = s1->next;
2989 s2 = s2->next;
2990 if (!s1)
2991 return !s2;
2992 if (!s2)
2993 return 0;
2997 /* return true if type1 and type2 are the same. If unqualified is
2998 true, qualifiers on the types are ignored.
3000 static int compare_types(CType *type1, CType *type2, int unqualified)
3002 int bt1, t1, t2;
3004 t1 = type1->t & VT_TYPE;
3005 t2 = type2->t & VT_TYPE;
3006 if (unqualified) {
3007 /* strip qualifiers before comparing */
3008 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
3009 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
3012 /* Default Vs explicit signedness only matters for char */
3013 if ((t1 & VT_BTYPE) != VT_BYTE) {
3014 t1 &= ~VT_DEFSIGN;
3015 t2 &= ~VT_DEFSIGN;
3017 /* XXX: bitfields ? */
3018 if (t1 != t2)
3019 return 0;
3021 if ((t1 & VT_ARRAY)
3022 && !(type1->ref->c < 0
3023 || type2->ref->c < 0
3024 || type1->ref->c == type2->ref->c))
3025 return 0;
3027 /* test more complicated cases */
3028 bt1 = t1 & VT_BTYPE;
3029 if (bt1 == VT_PTR) {
3030 type1 = pointed_type(type1);
3031 type2 = pointed_type(type2);
3032 return is_compatible_types(type1, type2);
3033 } else if (bt1 == VT_STRUCT) {
3034 return (type1->ref == type2->ref);
3035 } else if (bt1 == VT_FUNC) {
3036 return is_compatible_func(type1, type2);
3037 } else if (IS_ENUM(type1->t) && IS_ENUM(type2->t)) {
3038 /* If both are enums then they must be the same, if only one is then
3039 t1 and t2 must be equal, which was checked above already. */
3040 return type1->ref == type2->ref;
3041 } else {
3042 return 1;
3046 /* Check if OP1 and OP2 can be "combined" with operation OP, the combined
3047 type is stored in DEST if non-null (except for pointer plus/minus) . */
3048 static int combine_types(CType *dest, SValue *op1, SValue *op2, int op)
3050 CType *type1 = &op1->type, *type2 = &op2->type, type;
3051 int t1 = type1->t, t2 = type2->t, bt1 = t1 & VT_BTYPE, bt2 = t2 & VT_BTYPE;
3052 int ret = 1;
3054 type.t = VT_VOID;
3055 type.ref = NULL;
3057 if (bt1 == VT_VOID || bt2 == VT_VOID) {
3058 ret = op == '?' ? 1 : 0;
3059 /* NOTE: as an extension, we accept void on only one side */
3060 type.t = VT_VOID;
3061 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
3062 if (op == '+') ; /* Handled in caller */
3063 /* http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6 */
3064 /* If one is a null ptr constant the result type is the other. */
3065 else if (is_null_pointer (op2)) type = *type1;
3066 else if (is_null_pointer (op1)) type = *type2;
3067 else if (bt1 != bt2) {
3068 /* accept comparison or cond-expr between pointer and integer
3069 with a warning */
3070 if ((op == '?' || TOK_ISCOND(op))
3071 && (is_integer_btype(bt1) || is_integer_btype(bt2)))
3072 tcc_warning("pointer/integer mismatch in %s",
3073 op == '?' ? "conditional expression" : "comparison");
3074 else if (op != '-' || !is_integer_btype(bt2))
3075 ret = 0;
3076 type = *(bt1 == VT_PTR ? type1 : type2);
3077 } else {
3078 CType *pt1 = pointed_type(type1);
3079 CType *pt2 = pointed_type(type2);
3080 int pbt1 = pt1->t & VT_BTYPE;
3081 int pbt2 = pt2->t & VT_BTYPE;
3082 int newquals, copied = 0;
3083 if (pbt1 != VT_VOID && pbt2 != VT_VOID
3084 && !compare_types(pt1, pt2, 1/*unqualif*/)) {
3085 if (op != '?' && !TOK_ISCOND(op))
3086 ret = 0;
3087 else
3088 type_incompatibility_warning(type1, type2,
3089 op == '?'
3090 ? "pointer type mismatch in conditional expression ('%s' and '%s')"
3091 : "pointer type mismatch in comparison('%s' and '%s')");
3093 if (op == '?') {
3094 /* pointers to void get preferred, otherwise the
3095 pointed to types minus qualifs should be compatible */
3096 type = *((pbt1 == VT_VOID) ? type1 : type2);
3097 /* combine qualifs */
3098 newquals = ((pt1->t | pt2->t) & (VT_CONSTANT | VT_VOLATILE));
3099 if ((~pointed_type(&type)->t & (VT_CONSTANT | VT_VOLATILE))
3100 & newquals)
3102 /* copy the pointer target symbol */
3103 type.ref = sym_push(SYM_FIELD, &type.ref->type,
3104 0, type.ref->c);
3105 copied = 1;
3106 pointed_type(&type)->t |= newquals;
3108 /* pointers to incomplete arrays get converted to
3109 pointers to completed ones if possible */
3110 if (pt1->t & VT_ARRAY
3111 && pt2->t & VT_ARRAY
3112 && pointed_type(&type)->ref->c < 0
3113 && (pt1->ref->c > 0 || pt2->ref->c > 0))
3115 if (!copied)
3116 type.ref = sym_push(SYM_FIELD, &type.ref->type,
3117 0, type.ref->c);
3118 pointed_type(&type)->ref =
3119 sym_push(SYM_FIELD, &pointed_type(&type)->ref->type,
3120 0, pointed_type(&type)->ref->c);
3121 pointed_type(&type)->ref->c =
3122 0 < pt1->ref->c ? pt1->ref->c : pt2->ref->c;
3126 if (TOK_ISCOND(op))
3127 type.t = VT_SIZE_T;
3128 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
3129 if (op != '?' || !compare_types(type1, type2, 1))
3130 ret = 0;
3131 type = *type1;
3132 } else if (is_float(bt1) || is_float(bt2)) {
3133 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3134 type.t = VT_LDOUBLE;
3135 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3136 type.t = VT_DOUBLE;
3137 } else {
3138 type.t = VT_FLOAT;
3140 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3141 /* cast to biggest op */
3142 type.t = VT_LLONG | VT_LONG;
3143 if (bt1 == VT_LLONG)
3144 type.t &= t1;
3145 if (bt2 == VT_LLONG)
3146 type.t &= t2;
3147 /* convert to unsigned if it does not fit in a long long */
3148 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
3149 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
3150 type.t |= VT_UNSIGNED;
3151 } else {
3152 /* integer operations */
3153 type.t = VT_INT | (VT_LONG & (t1 | t2));
3154 /* convert to unsigned if it does not fit in an integer */
3155 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
3156 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
3157 type.t |= VT_UNSIGNED;
3159 if (dest)
3160 *dest = type;
3161 return ret;
3164 /* generic gen_op: handles types problems */
3165 ST_FUNC void gen_op(int op)
3167 int u, t1, t2, bt1, bt2, t;
3168 CType type1, combtype;
3170 redo:
3171 t1 = vtop[-1].type.t;
3172 t2 = vtop[0].type.t;
3173 bt1 = t1 & VT_BTYPE;
3174 bt2 = t2 & VT_BTYPE;
3176 if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
3177 if (bt2 == VT_FUNC) {
3178 mk_pointer(&vtop->type);
3179 gaddrof();
3181 if (bt1 == VT_FUNC) {
3182 vswap();
3183 mk_pointer(&vtop->type);
3184 gaddrof();
3185 vswap();
3187 goto redo;
3188 } else if (!combine_types(&combtype, vtop - 1, vtop, op)) {
3189 tcc_error_noabort("invalid operand types for binary operation");
3190 vpop();
3191 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
3192 /* at least one operand is a pointer */
3193 /* relational op: must be both pointers */
3194 if (TOK_ISCOND(op))
3195 goto std_op;
3196 /* if both pointers, then it must be the '-' op */
3197 if (bt1 == VT_PTR && bt2 == VT_PTR) {
3198 if (op != '-')
3199 tcc_error("cannot use pointers here");
3200 if (vtop[-1].type.t & VT_VLA) {
3201 vla_runtime_pointed_size(&vtop[-1].type);
3202 } else {
3203 vpushi(pointed_size(&vtop[-1].type));
3205 vrott(3);
3206 gen_opic(op);
3207 vtop->type.t = VT_PTRDIFF_T;
3208 vswap();
3209 gen_op(TOK_PDIV);
3210 } else {
3211 /* exactly one pointer : must be '+' or '-'. */
3212 if (op != '-' && op != '+')
3213 tcc_error("cannot use pointers here");
3214 /* Put pointer as first operand */
3215 if (bt2 == VT_PTR) {
3216 vswap();
3217 t = t1, t1 = t2, t2 = t;
3219 #if PTR_SIZE == 4
3220 if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG)
3221 /* XXX: truncate here because gen_opl can't handle ptr + long long */
3222 gen_cast_s(VT_INT);
3223 #endif
3224 type1 = vtop[-1].type;
3225 if (vtop[-1].type.t & VT_VLA)
3226 vla_runtime_pointed_size(&vtop[-1].type);
3227 else {
3228 u = pointed_size(&vtop[-1].type);
3229 if (u < 0)
3230 tcc_error("unknown array element size");
3231 #if PTR_SIZE == 8
3232 vpushll(u);
3233 #else
3234 /* XXX: cast to int ? (long long case) */
3235 vpushi(u);
3236 #endif
3238 gen_op('*');
3239 #ifdef CONFIG_TCC_BCHECK
3240 if (tcc_state->do_bounds_check && !const_wanted) {
3241 /* if bounded pointers, we generate a special code to
3242 test bounds */
3243 if (op == '-') {
3244 vpushi(0);
3245 vswap();
3246 gen_op('-');
3248 gen_bounded_ptr_add();
3249 } else
3250 #endif
3252 gen_opic(op);
3254 type1.t &= ~VT_ARRAY;
3255 /* put again type if gen_opic() swaped operands */
3256 vtop->type = type1;
3258 } else {
3259 /* floats can only be used for a few operations */
3260 if (is_float(combtype.t)
3261 && op != '+' && op != '-' && op != '*' && op != '/'
3262 && !TOK_ISCOND(op))
3263 tcc_error("invalid operands for binary operation");
3264 else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
3265 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
3266 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))
3267 t |= VT_UNSIGNED;
3268 t |= (VT_LONG & t1);
3269 combtype.t = t;
3271 std_op:
3272 t = t2 = combtype.t;
3273 /* XXX: currently, some unsigned operations are explicit, so
3274 we modify them here */
3275 if (t & VT_UNSIGNED) {
3276 if (op == TOK_SAR)
3277 op = TOK_SHR;
3278 else if (op == '/')
3279 op = TOK_UDIV;
3280 else if (op == '%')
3281 op = TOK_UMOD;
3282 else if (op == TOK_LT)
3283 op = TOK_ULT;
3284 else if (op == TOK_GT)
3285 op = TOK_UGT;
3286 else if (op == TOK_LE)
3287 op = TOK_ULE;
3288 else if (op == TOK_GE)
3289 op = TOK_UGE;
3291 vswap();
3292 gen_cast_s(t);
3293 vswap();
3294 /* special case for shifts and long long: we keep the shift as
3295 an integer */
3296 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
3297 t2 = VT_INT;
3298 gen_cast_s(t2);
3299 if (is_float(t))
3300 gen_opif(op);
3301 else
3302 gen_opic(op);
3303 if (TOK_ISCOND(op)) {
3304 /* relational op: the result is an int */
3305 vtop->type.t = VT_INT;
3306 } else {
3307 vtop->type.t = t;
3310 // Make sure that we have converted to an rvalue:
3311 if (vtop->r & VT_LVAL)
3312 gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
3315 #if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 || defined TCC_TARGET_ARM
3316 #define gen_cvt_itof1 gen_cvt_itof
3317 #else
3318 /* generic itof for unsigned long long case */
3319 static void gen_cvt_itof1(int t)
3321 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
3322 (VT_LLONG | VT_UNSIGNED)) {
3324 if (t == VT_FLOAT)
3325 vpush_global_sym(&func_old_type, TOK___floatundisf);
3326 #if LDOUBLE_SIZE != 8
3327 else if (t == VT_LDOUBLE)
3328 vpush_global_sym(&func_old_type, TOK___floatundixf);
3329 #endif
3330 else
3331 vpush_global_sym(&func_old_type, TOK___floatundidf);
3332 vrott(2);
3333 gfunc_call(1);
3334 vpushi(0);
3335 PUT_R_RET(vtop, t);
3336 } else {
3337 gen_cvt_itof(t);
3340 #endif
3342 #if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
3343 #define gen_cvt_ftoi1 gen_cvt_ftoi
3344 #else
3345 /* generic ftoi for unsigned long long case */
3346 static void gen_cvt_ftoi1(int t)
3348 int st;
3349 if (t == (VT_LLONG | VT_UNSIGNED)) {
3350 /* not handled natively */
3351 st = vtop->type.t & VT_BTYPE;
3352 if (st == VT_FLOAT)
3353 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
3354 #if LDOUBLE_SIZE != 8
3355 else if (st == VT_LDOUBLE)
3356 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
3357 #endif
3358 else
3359 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
3360 vrott(2);
3361 gfunc_call(1);
3362 vpushi(0);
3363 PUT_R_RET(vtop, t);
3364 } else {
3365 gen_cvt_ftoi(t);
3368 #endif
3370 /* special delayed cast for char/short */
3371 static void force_charshort_cast(void)
3373 int sbt = BFGET(vtop->r, VT_MUSTCAST) == 2 ? VT_LLONG : VT_INT;
3374 int dbt = vtop->type.t;
3375 vtop->r &= ~VT_MUSTCAST;
3376 vtop->type.t = sbt;
3377 gen_cast_s(dbt == VT_BOOL ? VT_BYTE|VT_UNSIGNED : dbt);
3378 vtop->type.t = dbt;
3381 static void gen_cast_s(int t)
3383 CType type;
3384 type.t = t;
3385 type.ref = NULL;
3386 gen_cast(&type);
3389 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
3390 static void gen_cast(CType *type)
3392 int sbt, dbt, sf, df, c;
3393 int dbt_bt, sbt_bt, ds, ss, bits, trunc;
3395 /* special delayed cast for char/short */
3396 if (vtop->r & VT_MUSTCAST)
3397 force_charshort_cast();
3399 /* bitfields first get cast to ints */
3400 if (vtop->type.t & VT_BITFIELD)
3401 gv(RC_INT);
3403 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
3404 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3405 if (sbt == VT_FUNC)
3406 sbt = VT_PTR;
3408 again:
3409 if (sbt != dbt) {
3410 sf = is_float(sbt);
3411 df = is_float(dbt);
3412 dbt_bt = dbt & VT_BTYPE;
3413 sbt_bt = sbt & VT_BTYPE;
3415 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3416 #if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
3417 c &= (dbt != VT_LDOUBLE) | !!nocode_wanted;
3418 #endif
3419 if (c) {
3420 /* constant case: we can do it now */
3421 /* XXX: in ISOC, cannot do it if error in convert */
3422 if (sbt == VT_FLOAT)
3423 vtop->c.ld = vtop->c.f;
3424 else if (sbt == VT_DOUBLE)
3425 vtop->c.ld = vtop->c.d;
3427 if (df) {
3428 if (sbt_bt == VT_LLONG) {
3429 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
3430 vtop->c.ld = vtop->c.i;
3431 else
3432 vtop->c.ld = -(long double)-vtop->c.i;
3433 } else if(!sf) {
3434 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
3435 vtop->c.ld = (uint32_t)vtop->c.i;
3436 else
3437 vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
3440 if (dbt == VT_FLOAT)
3441 vtop->c.f = (float)vtop->c.ld;
3442 else if (dbt == VT_DOUBLE)
3443 vtop->c.d = (double)vtop->c.ld;
3444 } else if (sf && dbt == VT_BOOL) {
3445 vtop->c.i = (vtop->c.ld != 0);
3446 } else {
3447 if(sf)
3448 vtop->c.i = vtop->c.ld;
3449 else if (sbt_bt == VT_LLONG || (PTR_SIZE == 8 && sbt == VT_PTR))
3451 else if (sbt & VT_UNSIGNED)
3452 vtop->c.i = (uint32_t)vtop->c.i;
3453 else
3454 vtop->c.i = ((uint32_t)vtop->c.i | -(vtop->c.i & 0x80000000));
3456 if (dbt_bt == VT_LLONG || (PTR_SIZE == 8 && dbt == VT_PTR))
3458 else if (dbt == VT_BOOL)
3459 vtop->c.i = (vtop->c.i != 0);
3460 else {
3461 uint32_t m = dbt_bt == VT_BYTE ? 0xff :
3462 dbt_bt == VT_SHORT ? 0xffff :
3463 0xffffffff;
3464 vtop->c.i &= m;
3465 if (!(dbt & VT_UNSIGNED))
3466 vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
3469 goto done;
3471 } else if (dbt == VT_BOOL
3472 && (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM))
3473 == (VT_CONST | VT_SYM)) {
3474 /* addresses are considered non-zero (see tcctest.c:sinit23) */
3475 vtop->r = VT_CONST;
3476 vtop->c.i = 1;
3477 goto done;
3480 /* cannot generate code for global or static initializers */
3481 if (STATIC_DATA_WANTED)
3482 goto done;
3484 /* non constant case: generate code */
3485 if (dbt == VT_BOOL) {
3486 gen_test_zero(TOK_NE);
3487 goto done;
3490 if (sf || df) {
3491 if (sf && df) {
3492 /* convert from fp to fp */
3493 gen_cvt_ftof(dbt);
3494 } else if (df) {
3495 /* convert int to fp */
3496 gen_cvt_itof1(dbt);
3497 } else {
3498 /* convert fp to int */
3499 sbt = dbt;
3500 if (dbt_bt != VT_LLONG && dbt_bt != VT_INT)
3501 sbt = VT_INT;
3502 gen_cvt_ftoi1(sbt);
3503 goto again; /* may need char/short cast */
3505 goto done;
3508 ds = btype_size(dbt_bt);
3509 ss = btype_size(sbt_bt);
3510 if (ds == 0 || ss == 0) {
3511 if (dbt_bt == VT_VOID)
3512 goto done;
3513 cast_error(&vtop->type, type);
3515 if (IS_ENUM(type->t) && type->ref->c < 0)
3516 tcc_error("cast to incomplete type");
3518 /* same size and no sign conversion needed */
3519 if (ds == ss && ds >= 4)
3520 goto done;
3521 if (dbt_bt == VT_PTR || sbt_bt == VT_PTR) {
3522 tcc_warning("cast between pointer and integer of different size");
3523 if (sbt_bt == VT_PTR) {
3524 /* put integer type to allow logical operations below */
3525 vtop->type.t = (PTR_SIZE == 8 ? VT_LLONG : VT_INT);
3529 /* processor allows { int a = 0, b = *(char*)&a; }
3530 That means that if we cast to less width, we can just
3531 change the type and read it still later. */
3532 #define ALLOW_SUBTYPE_ACCESS 1
3534 if (ALLOW_SUBTYPE_ACCESS && (vtop->r & VT_LVAL)) {
3535 /* value still in memory */
3536 if (ds <= ss)
3537 goto done;
3538 /* ss <= 4 here */
3539 if (ds <= 4) {
3540 gv(RC_INT);
3541 goto done; /* no 64bit envolved */
3544 gv(RC_INT);
3546 trunc = 0;
3547 #if PTR_SIZE == 4
3548 if (ds == 8) {
3549 /* generate high word */
3550 if (sbt & VT_UNSIGNED) {
3551 vpushi(0);
3552 gv(RC_INT);
3553 } else {
3554 gv_dup();
3555 vpushi(31);
3556 gen_op(TOK_SAR);
3558 lbuild(dbt);
3559 } else if (ss == 8) {
3560 /* from long long: just take low order word */
3561 lexpand();
3562 vpop();
3564 ss = 4;
3566 #elif PTR_SIZE == 8
3567 if (ds == 8) {
3568 /* need to convert from 32bit to 64bit */
3569 if (sbt & VT_UNSIGNED) {
3570 #if defined(TCC_TARGET_RISCV64)
3571 /* RISC-V keeps 32bit vals in registers sign-extended.
3572 So here we need a zero-extension. */
3573 trunc = 32;
3574 #else
3575 goto done;
3576 #endif
3577 } else {
3578 gen_cvt_sxtw();
3579 goto done;
3581 ss = ds, ds = 4, dbt = sbt;
3582 } else if (ss == 8) {
3583 /* XXX some architectures (e.g. risc-v) would like it
3584 better for this merely being a 32-to-64 sign or zero-
3585 extension. */
3586 trunc = 32; /* zero upper 32 bits */
3587 } else {
3588 ss = 4;
3590 #endif
3592 if (ds >= ss)
3593 goto done;
3594 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM64
3595 if (ss == 4) {
3596 gen_cvt_csti(dbt);
3597 goto done;
3599 #endif
3600 bits = (ss - ds) * 8;
3601 /* for unsigned, gen_op will convert SAR to SHR */
3602 vtop->type.t = (ss == 8 ? VT_LLONG : VT_INT) | (dbt & VT_UNSIGNED);
3603 vpushi(bits);
3604 gen_op(TOK_SHL);
3605 vpushi(bits - trunc);
3606 gen_op(TOK_SAR);
3607 vpushi(trunc);
3608 gen_op(TOK_SHR);
3610 done:
3611 vtop->type = *type;
3612 vtop->type.t &= ~ ( VT_CONSTANT | VT_VOLATILE | VT_ARRAY );
3615 /* return type size as known at compile time. Put alignment at 'a' */
3616 ST_FUNC int type_size(CType *type, int *a)
3618 Sym *s;
3619 int bt;
3621 bt = type->t & VT_BTYPE;
3622 if (bt == VT_STRUCT) {
3623 /* struct/union */
3624 s = type->ref;
3625 *a = s->r;
3626 return s->c;
3627 } else if (bt == VT_PTR) {
3628 if (type->t & VT_ARRAY) {
3629 int ts;
3631 s = type->ref;
3632 ts = type_size(&s->type, a);
3634 if (ts < 0 && s->c < 0)
3635 ts = -ts;
3637 return ts * s->c;
3638 } else {
3639 *a = PTR_SIZE;
3640 return PTR_SIZE;
3642 } else if (IS_ENUM(type->t) && type->ref->c < 0) {
3643 return -1; /* incomplete enum */
3644 } else if (bt == VT_LDOUBLE) {
3645 *a = LDOUBLE_ALIGN;
3646 return LDOUBLE_SIZE;
3647 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
3648 #ifdef TCC_TARGET_I386
3649 #ifdef TCC_TARGET_PE
3650 *a = 8;
3651 #else
3652 *a = 4;
3653 #endif
3654 #elif defined(TCC_TARGET_ARM)
3655 #ifdef TCC_ARM_EABI
3656 *a = 8;
3657 #else
3658 *a = 4;
3659 #endif
3660 #else
3661 *a = 8;
3662 #endif
3663 return 8;
3664 } else if (bt == VT_INT || bt == VT_FLOAT) {
3665 *a = 4;
3666 return 4;
3667 } else if (bt == VT_SHORT) {
3668 *a = 2;
3669 return 2;
3670 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
3671 *a = 8;
3672 return 16;
3673 } else {
3674 /* char, void, function, _Bool */
3675 *a = 1;
3676 return 1;
3680 /* push type size as known at runtime time on top of value stack. Put
3681 alignment at 'a' */
3682 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
3684 if (type->t & VT_VLA) {
3685 type_size(&type->ref->type, a);
3686 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
3687 } else {
3688 vpushi(type_size(type, a));
3692 /* return the pointed type of t */
3693 static inline CType *pointed_type(CType *type)
3695 return &type->ref->type;
3698 /* modify type so that its it is a pointer to type. */
3699 ST_FUNC void mk_pointer(CType *type)
3701 Sym *s;
3702 s = sym_push(SYM_FIELD, type, 0, -1);
3703 type->t = VT_PTR | (type->t & VT_STORAGE);
3704 type->ref = s;
3707 /* return true if type1 and type2 are exactly the same (including
3708 qualifiers).
3710 static int is_compatible_types(CType *type1, CType *type2)
3712 return compare_types(type1,type2,0);
3715 /* return true if type1 and type2 are the same (ignoring qualifiers).
3717 static int is_compatible_unqualified_types(CType *type1, CType *type2)
3719 return compare_types(type1,type2,1);
3722 static void cast_error(CType *st, CType *dt)
3724 type_incompatibility_error(st, dt, "cannot convert '%s' to '%s'");
3727 /* verify type compatibility to store vtop in 'dt' type */
3728 static void verify_assign_cast(CType *dt)
3730 CType *st, *type1, *type2;
3731 int dbt, sbt, qualwarn, lvl;
3733 st = &vtop->type; /* source type */
3734 dbt = dt->t & VT_BTYPE;
3735 sbt = st->t & VT_BTYPE;
3736 if (dt->t & VT_CONSTANT)
3737 tcc_warning("assignment of read-only location");
3738 switch(dbt) {
3739 case VT_VOID:
3740 if (sbt != dbt)
3741 tcc_error("assignment to void expression");
3742 break;
3743 case VT_PTR:
3744 /* special cases for pointers */
3745 /* '0' can also be a pointer */
3746 if (is_null_pointer(vtop))
3747 break;
3748 /* accept implicit pointer to integer cast with warning */
3749 if (is_integer_btype(sbt)) {
3750 tcc_warning("assignment makes pointer from integer without a cast");
3751 break;
3753 type1 = pointed_type(dt);
3754 if (sbt == VT_PTR)
3755 type2 = pointed_type(st);
3756 else if (sbt == VT_FUNC)
3757 type2 = st; /* a function is implicitly a function pointer */
3758 else
3759 goto error;
3760 if (is_compatible_types(type1, type2))
3761 break;
3762 for (qualwarn = lvl = 0;; ++lvl) {
3763 if (((type2->t & VT_CONSTANT) && !(type1->t & VT_CONSTANT)) ||
3764 ((type2->t & VT_VOLATILE) && !(type1->t & VT_VOLATILE)))
3765 qualwarn = 1;
3766 dbt = type1->t & (VT_BTYPE|VT_LONG);
3767 sbt = type2->t & (VT_BTYPE|VT_LONG);
3768 if (dbt != VT_PTR || sbt != VT_PTR)
3769 break;
3770 type1 = pointed_type(type1);
3771 type2 = pointed_type(type2);
3773 if (!is_compatible_unqualified_types(type1, type2)) {
3774 if ((dbt == VT_VOID || sbt == VT_VOID) && lvl == 0) {
3775 /* void * can match anything */
3776 } else if (dbt == sbt
3777 && is_integer_btype(sbt & VT_BTYPE)
3778 && IS_ENUM(type1->t) + IS_ENUM(type2->t)
3779 + !!((type1->t ^ type2->t) & VT_UNSIGNED) < 2) {
3780 /* Like GCC don't warn by default for merely changes
3781 in pointer target signedness. Do warn for different
3782 base types, though, in particular for unsigned enums
3783 and signed int targets. */
3784 } else {
3785 tcc_warning("assignment from incompatible pointer type");
3786 break;
3789 if (qualwarn)
3790 tcc_warning("assignment discards qualifiers from pointer target type");
3791 break;
3792 case VT_BYTE:
3793 case VT_SHORT:
3794 case VT_INT:
3795 case VT_LLONG:
3796 if (sbt == VT_PTR || sbt == VT_FUNC) {
3797 tcc_warning("assignment makes integer from pointer without a cast");
3798 } else if (sbt == VT_STRUCT) {
3799 goto case_VT_STRUCT;
3801 /* XXX: more tests */
3802 break;
3803 case VT_STRUCT:
3804 case_VT_STRUCT:
3805 if (!is_compatible_unqualified_types(dt, st)) {
3806 error:
3807 cast_error(st, dt);
3809 break;
3813 static void gen_assign_cast(CType *dt)
3815 verify_assign_cast(dt);
3816 gen_cast(dt);
3819 /* store vtop in lvalue pushed on stack */
3820 ST_FUNC void vstore(void)
3822 int sbt, dbt, ft, r, size, align, bit_size, bit_pos, delayed_cast;
3824 ft = vtop[-1].type.t;
3825 sbt = vtop->type.t & VT_BTYPE;
3826 dbt = ft & VT_BTYPE;
3828 verify_assign_cast(&vtop[-1].type);
3830 if (sbt == VT_STRUCT) {
3831 /* if structure, only generate pointer */
3832 /* structure assignment : generate memcpy */
3833 /* XXX: optimize if small size */
3834 size = type_size(&vtop->type, &align);
3836 /* destination */
3837 vswap();
3838 #ifdef CONFIG_TCC_BCHECK
3839 if (vtop->r & VT_MUSTBOUND)
3840 gbound(); /* check would be wrong after gaddrof() */
3841 #endif
3842 vtop->type.t = VT_PTR;
3843 gaddrof();
3845 /* address of memcpy() */
3846 #ifdef TCC_ARM_EABI
3847 if(!(align & 7))
3848 vpush_global_sym(&func_old_type, TOK_memmove8);
3849 else if(!(align & 3))
3850 vpush_global_sym(&func_old_type, TOK_memmove4);
3851 else
3852 #endif
3853 /* Use memmove, rather than memcpy, as dest and src may be same: */
3854 vpush_global_sym(&func_old_type, TOK_memmove);
3856 vswap();
3857 /* source */
3858 vpushv(vtop - 2);
3859 #ifdef CONFIG_TCC_BCHECK
3860 if (vtop->r & VT_MUSTBOUND)
3861 gbound();
3862 #endif
3863 vtop->type.t = VT_PTR;
3864 gaddrof();
3865 /* type size */
3866 vpushi(size);
3867 gfunc_call(3);
3868 /* leave source on stack */
3870 } else if (ft & VT_BITFIELD) {
3871 /* bitfield store handling */
3873 /* save lvalue as expression result (example: s.b = s.a = n;) */
3874 vdup(), vtop[-1] = vtop[-2];
3876 bit_pos = BIT_POS(ft);
3877 bit_size = BIT_SIZE(ft);
3878 /* remove bit field info to avoid loops */
3879 vtop[-1].type.t = ft & ~VT_STRUCT_MASK;
3881 if (dbt == VT_BOOL) {
3882 gen_cast(&vtop[-1].type);
3883 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
3885 r = adjust_bf(vtop - 1, bit_pos, bit_size);
3886 if (dbt != VT_BOOL) {
3887 gen_cast(&vtop[-1].type);
3888 dbt = vtop[-1].type.t & VT_BTYPE;
3890 if (r == VT_STRUCT) {
3891 store_packed_bf(bit_pos, bit_size);
3892 } else {
3893 unsigned long long mask = (1ULL << bit_size) - 1;
3894 if (dbt != VT_BOOL) {
3895 /* mask source */
3896 if (dbt == VT_LLONG)
3897 vpushll(mask);
3898 else
3899 vpushi((unsigned)mask);
3900 gen_op('&');
3902 /* shift source */
3903 vpushi(bit_pos);
3904 gen_op(TOK_SHL);
3905 vswap();
3906 /* duplicate destination */
3907 vdup();
3908 vrott(3);
3909 /* load destination, mask and or with source */
3910 if (dbt == VT_LLONG)
3911 vpushll(~(mask << bit_pos));
3912 else
3913 vpushi(~((unsigned)mask << bit_pos));
3914 gen_op('&');
3915 gen_op('|');
3916 /* store result */
3917 vstore();
3918 /* ... and discard */
3919 vpop();
3921 } else if (dbt == VT_VOID) {
3922 --vtop;
3923 } else {
3924 /* optimize char/short casts */
3925 delayed_cast = 0;
3926 if ((dbt == VT_BYTE || dbt == VT_SHORT)
3927 && is_integer_btype(sbt)
3929 if ((vtop->r & VT_MUSTCAST)
3930 && btype_size(dbt) > btype_size(sbt)
3932 force_charshort_cast();
3933 delayed_cast = 1;
3934 } else {
3935 gen_cast(&vtop[-1].type);
3938 #ifdef CONFIG_TCC_BCHECK
3939 /* bound check case */
3940 if (vtop[-1].r & VT_MUSTBOUND) {
3941 vswap();
3942 gbound();
3943 vswap();
3945 #endif
3946 gv(RC_TYPE(dbt)); /* generate value */
3948 if (delayed_cast) {
3949 vtop->r |= BFVAL(VT_MUSTCAST, (sbt == VT_LLONG) + 1);
3950 //tcc_warning("deley cast %x -> %x", sbt, dbt);
3951 vtop->type.t = ft & VT_TYPE;
3954 /* if lvalue was saved on stack, must read it */
3955 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
3956 SValue sv;
3957 r = get_reg(RC_INT);
3958 sv.type.t = VT_PTRDIFF_T;
3959 sv.r = VT_LOCAL | VT_LVAL;
3960 sv.c.i = vtop[-1].c.i;
3961 load(r, &sv);
3962 vtop[-1].r = r | VT_LVAL;
3965 r = vtop->r & VT_VALMASK;
3966 /* two word case handling :
3967 store second register at word + 4 (or +8 for x86-64) */
3968 if (USING_TWO_WORDS(dbt)) {
3969 int load_type = (dbt == VT_QFLOAT) ? VT_DOUBLE : VT_PTRDIFF_T;
3970 vtop[-1].type.t = load_type;
3971 store(r, vtop - 1);
3972 vswap();
3973 /* convert to int to increment easily */
3974 vtop->type.t = VT_PTRDIFF_T;
3975 gaddrof();
3976 vpushs(PTR_SIZE);
3977 gen_op('+');
3978 vtop->r |= VT_LVAL;
3979 vswap();
3980 vtop[-1].type.t = load_type;
3981 /* XXX: it works because r2 is spilled last ! */
3982 store(vtop->r2, vtop - 1);
3983 } else {
3984 /* single word */
3985 store(r, vtop - 1);
3987 vswap();
3988 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
3992 /* post defines POST/PRE add. c is the token ++ or -- */
3993 ST_FUNC void inc(int post, int c)
3995 test_lvalue();
3996 vdup(); /* save lvalue */
3997 if (post) {
3998 gv_dup(); /* duplicate value */
3999 vrotb(3);
4000 vrotb(3);
4002 /* add constant */
4003 vpushi(c - TOK_MID);
4004 gen_op('+');
4005 vstore(); /* store value */
4006 if (post)
4007 vpop(); /* if post op, return saved value */
4010 ST_FUNC void parse_mult_str (CString *astr, const char *msg)
4012 /* read the string */
4013 if (tok != TOK_STR)
4014 expect(msg);
4015 cstr_new(astr);
4016 while (tok == TOK_STR) {
4017 /* XXX: add \0 handling too ? */
4018 cstr_cat(astr, tokc.str.data, -1);
4019 next();
4021 cstr_ccat(astr, '\0');
4024 /* If I is >= 1 and a power of two, returns log2(i)+1.
4025 If I is 0 returns 0. */
4026 ST_FUNC int exact_log2p1(int i)
4028 int ret;
4029 if (!i)
4030 return 0;
4031 for (ret = 1; i >= 1 << 8; ret += 8)
4032 i >>= 8;
4033 if (i >= 1 << 4)
4034 ret += 4, i >>= 4;
4035 if (i >= 1 << 2)
4036 ret += 2, i >>= 2;
4037 if (i >= 1 << 1)
4038 ret++;
4039 return ret;
4042 /* Parse __attribute__((...)) GNUC extension. */
4043 static void parse_attribute(AttributeDef *ad)
4045 int t, n;
4046 CString astr;
4048 redo:
4049 if (tok != TOK_ATTRIBUTE1 && tok != TOK_ATTRIBUTE2)
4050 return;
4051 next();
4052 skip('(');
4053 skip('(');
4054 while (tok != ')') {
4055 if (tok < TOK_IDENT)
4056 expect("attribute name");
4057 t = tok;
4058 next();
4059 switch(t) {
4060 case TOK_CLEANUP1:
4061 case TOK_CLEANUP2:
4063 Sym *s;
4065 skip('(');
4066 s = sym_find(tok);
4067 if (!s) {
4068 tcc_warning("implicit declaration of function '%s'",
4069 get_tok_str(tok, &tokc));
4070 s = external_global_sym(tok, &func_old_type);
4071 } else if ((s->type.t & VT_BTYPE) != VT_FUNC)
4072 tcc_error("'%s' is not declared as function", get_tok_str(tok, &tokc));
4073 ad->cleanup_func = s;
4074 next();
4075 skip(')');
4076 break;
4078 case TOK_CONSTRUCTOR1:
4079 case TOK_CONSTRUCTOR2:
4080 ad->f.func_ctor = 1;
4081 break;
4082 case TOK_DESTRUCTOR1:
4083 case TOK_DESTRUCTOR2:
4084 ad->f.func_dtor = 1;
4085 break;
4086 case TOK_ALWAYS_INLINE1:
4087 case TOK_ALWAYS_INLINE2:
4088 ad->f.func_alwinl = 1;
4089 break;
4090 case TOK_SECTION1:
4091 case TOK_SECTION2:
4092 skip('(');
4093 parse_mult_str(&astr, "section name");
4094 ad->section = find_section(tcc_state, (char *)astr.data);
4095 skip(')');
4096 cstr_free(&astr);
4097 break;
4098 case TOK_ALIAS1:
4099 case TOK_ALIAS2:
4100 skip('(');
4101 parse_mult_str(&astr, "alias(\"target\")");
4102 ad->alias_target = /* save string as token, for later */
4103 tok_alloc((char*)astr.data, astr.size-1)->tok;
4104 skip(')');
4105 cstr_free(&astr);
4106 break;
4107 case TOK_VISIBILITY1:
4108 case TOK_VISIBILITY2:
4109 skip('(');
4110 parse_mult_str(&astr,
4111 "visibility(\"default|hidden|internal|protected\")");
4112 if (!strcmp (astr.data, "default"))
4113 ad->a.visibility = STV_DEFAULT;
4114 else if (!strcmp (astr.data, "hidden"))
4115 ad->a.visibility = STV_HIDDEN;
4116 else if (!strcmp (astr.data, "internal"))
4117 ad->a.visibility = STV_INTERNAL;
4118 else if (!strcmp (astr.data, "protected"))
4119 ad->a.visibility = STV_PROTECTED;
4120 else
4121 expect("visibility(\"default|hidden|internal|protected\")");
4122 skip(')');
4123 cstr_free(&astr);
4124 break;
4125 case TOK_ALIGNED1:
4126 case TOK_ALIGNED2:
4127 if (tok == '(') {
4128 next();
4129 n = expr_const();
4130 if (n <= 0 || (n & (n - 1)) != 0)
4131 tcc_error("alignment must be a positive power of two");
4132 skip(')');
4133 } else {
4134 n = MAX_ALIGN;
4136 ad->a.aligned = exact_log2p1(n);
4137 if (n != 1 << (ad->a.aligned - 1))
4138 tcc_error("alignment of %d is larger than implemented", n);
4139 break;
4140 case TOK_PACKED1:
4141 case TOK_PACKED2:
4142 ad->a.packed = 1;
4143 break;
4144 case TOK_WEAK1:
4145 case TOK_WEAK2:
4146 ad->a.weak = 1;
4147 break;
4148 case TOK_UNUSED1:
4149 case TOK_UNUSED2:
4150 /* currently, no need to handle it because tcc does not
4151 track unused objects */
4152 break;
4153 case TOK_NORETURN1:
4154 case TOK_NORETURN2:
4155 ad->f.func_noreturn = 1;
4156 break;
4157 case TOK_CDECL1:
4158 case TOK_CDECL2:
4159 case TOK_CDECL3:
4160 ad->f.func_call = FUNC_CDECL;
4161 break;
4162 case TOK_STDCALL1:
4163 case TOK_STDCALL2:
4164 case TOK_STDCALL3:
4165 ad->f.func_call = FUNC_STDCALL;
4166 break;
4167 #ifdef TCC_TARGET_I386
4168 case TOK_REGPARM1:
4169 case TOK_REGPARM2:
4170 skip('(');
4171 n = expr_const();
4172 if (n > 3)
4173 n = 3;
4174 else if (n < 0)
4175 n = 0;
4176 if (n > 0)
4177 ad->f.func_call = FUNC_FASTCALL1 + n - 1;
4178 skip(')');
4179 break;
4180 case TOK_FASTCALL1:
4181 case TOK_FASTCALL2:
4182 case TOK_FASTCALL3:
4183 ad->f.func_call = FUNC_FASTCALLW;
4184 break;
4185 #endif
4186 case TOK_MODE:
4187 skip('(');
4188 switch(tok) {
4189 case TOK_MODE_DI:
4190 ad->attr_mode = VT_LLONG + 1;
4191 break;
4192 case TOK_MODE_QI:
4193 ad->attr_mode = VT_BYTE + 1;
4194 break;
4195 case TOK_MODE_HI:
4196 ad->attr_mode = VT_SHORT + 1;
4197 break;
4198 case TOK_MODE_SI:
4199 case TOK_MODE_word:
4200 ad->attr_mode = VT_INT + 1;
4201 break;
4202 default:
4203 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
4204 break;
4206 next();
4207 skip(')');
4208 break;
4209 case TOK_DLLEXPORT:
4210 ad->a.dllexport = 1;
4211 break;
4212 case TOK_NODECORATE:
4213 ad->a.nodecorate = 1;
4214 break;
4215 case TOK_DLLIMPORT:
4216 ad->a.dllimport = 1;
4217 break;
4218 default:
4219 if (tcc_state->warn_unsupported)
4220 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
4221 /* skip parameters */
4222 if (tok == '(') {
4223 int parenthesis = 0;
4224 do {
4225 if (tok == '(')
4226 parenthesis++;
4227 else if (tok == ')')
4228 parenthesis--;
4229 next();
4230 } while (parenthesis && tok != -1);
4232 break;
4234 if (tok != ',')
4235 break;
4236 next();
4238 skip(')');
4239 skip(')');
4240 goto redo;
4243 static Sym * find_field (CType *type, int v, int *cumofs)
4245 Sym *s = type->ref;
4246 v |= SYM_FIELD;
4247 while ((s = s->next) != NULL) {
4248 if ((s->v & SYM_FIELD) &&
4249 (s->type.t & VT_BTYPE) == VT_STRUCT &&
4250 (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
4251 Sym *ret = find_field (&s->type, v, cumofs);
4252 if (ret) {
4253 *cumofs += s->c;
4254 return ret;
4257 if (s->v == v)
4258 break;
4260 return s;
4263 static void struct_layout(CType *type, AttributeDef *ad)
4265 int size, align, maxalign, offset, c, bit_pos, bit_size;
4266 int packed, a, bt, prevbt, prev_bit_size;
4267 int pcc = !tcc_state->ms_bitfields;
4268 int pragma_pack = *tcc_state->pack_stack_ptr;
4269 Sym *f;
4271 maxalign = 1;
4272 offset = 0;
4273 c = 0;
4274 bit_pos = 0;
4275 prevbt = VT_STRUCT; /* make it never match */
4276 prev_bit_size = 0;
4278 //#define BF_DEBUG
4280 for (f = type->ref->next; f; f = f->next) {
4281 if (f->type.t & VT_BITFIELD)
4282 bit_size = BIT_SIZE(f->type.t);
4283 else
4284 bit_size = -1;
4285 size = type_size(&f->type, &align);
4286 a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0;
4287 packed = 0;
4289 if (pcc && bit_size == 0) {
4290 /* in pcc mode, packing does not affect zero-width bitfields */
4292 } else {
4293 /* in pcc mode, attribute packed overrides if set. */
4294 if (pcc && (f->a.packed || ad->a.packed))
4295 align = packed = 1;
4297 /* pragma pack overrides align if lesser and packs bitfields always */
4298 if (pragma_pack) {
4299 packed = 1;
4300 if (pragma_pack < align)
4301 align = pragma_pack;
4302 /* in pcc mode pragma pack also overrides individual align */
4303 if (pcc && pragma_pack < a)
4304 a = 0;
4307 /* some individual align was specified */
4308 if (a)
4309 align = a;
4311 if (type->ref->type.t == VT_UNION) {
4312 if (pcc && bit_size >= 0)
4313 size = (bit_size + 7) >> 3;
4314 offset = 0;
4315 if (size > c)
4316 c = size;
4318 } else if (bit_size < 0) {
4319 if (pcc)
4320 c += (bit_pos + 7) >> 3;
4321 c = (c + align - 1) & -align;
4322 offset = c;
4323 if (size > 0)
4324 c += size;
4325 bit_pos = 0;
4326 prevbt = VT_STRUCT;
4327 prev_bit_size = 0;
4329 } else {
4330 /* A bit-field. Layout is more complicated. There are two
4331 options: PCC (GCC) compatible and MS compatible */
4332 if (pcc) {
4333 /* In PCC layout a bit-field is placed adjacent to the
4334 preceding bit-fields, except if:
4335 - it has zero-width
4336 - an individual alignment was given
4337 - it would overflow its base type container and
4338 there is no packing */
4339 if (bit_size == 0) {
4340 new_field:
4341 c = (c + ((bit_pos + 7) >> 3) + align - 1) & -align;
4342 bit_pos = 0;
4343 } else if (f->a.aligned) {
4344 goto new_field;
4345 } else if (!packed) {
4346 int a8 = align * 8;
4347 int ofs = ((c * 8 + bit_pos) % a8 + bit_size + a8 - 1) / a8;
4348 if (ofs > size / align)
4349 goto new_field;
4352 /* in pcc mode, long long bitfields have type int if they fit */
4353 if (size == 8 && bit_size <= 32)
4354 f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT, size = 4;
4356 while (bit_pos >= align * 8)
4357 c += align, bit_pos -= align * 8;
4358 offset = c;
4360 /* In PCC layout named bit-fields influence the alignment
4361 of the containing struct using the base types alignment,
4362 except for packed fields (which here have correct align). */
4363 if (f->v & SYM_FIRST_ANOM
4364 // && bit_size // ??? gcc on ARM/rpi does that
4366 align = 1;
4368 } else {
4369 bt = f->type.t & VT_BTYPE;
4370 if ((bit_pos + bit_size > size * 8)
4371 || (bit_size > 0) == (bt != prevbt)
4373 c = (c + align - 1) & -align;
4374 offset = c;
4375 bit_pos = 0;
4376 /* In MS bitfield mode a bit-field run always uses
4377 at least as many bits as the underlying type.
4378 To start a new run it's also required that this
4379 or the last bit-field had non-zero width. */
4380 if (bit_size || prev_bit_size)
4381 c += size;
4383 /* In MS layout the records alignment is normally
4384 influenced by the field, except for a zero-width
4385 field at the start of a run (but by further zero-width
4386 fields it is again). */
4387 if (bit_size == 0 && prevbt != bt)
4388 align = 1;
4389 prevbt = bt;
4390 prev_bit_size = bit_size;
4393 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
4394 | (bit_pos << VT_STRUCT_SHIFT);
4395 bit_pos += bit_size;
4397 if (align > maxalign)
4398 maxalign = align;
4400 #ifdef BF_DEBUG
4401 printf("set field %s offset %-2d size %-2d align %-2d",
4402 get_tok_str(f->v & ~SYM_FIELD, NULL), offset, size, align);
4403 if (f->type.t & VT_BITFIELD) {
4404 printf(" pos %-2d bits %-2d",
4405 BIT_POS(f->type.t),
4406 BIT_SIZE(f->type.t)
4409 printf("\n");
4410 #endif
4412 f->c = offset;
4413 f->r = 0;
4416 if (pcc)
4417 c += (bit_pos + 7) >> 3;
4419 /* store size and alignment */
4420 a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1;
4421 if (a < maxalign)
4422 a = maxalign;
4423 type->ref->r = a;
4424 if (pragma_pack && pragma_pack < maxalign && 0 == pcc) {
4425 /* can happen if individual align for some member was given. In
4426 this case MSVC ignores maxalign when aligning the size */
4427 a = pragma_pack;
4428 if (a < bt)
4429 a = bt;
4431 c = (c + a - 1) & -a;
4432 type->ref->c = c;
4434 #ifdef BF_DEBUG
4435 printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout);
4436 #endif
4438 /* check whether we can access bitfields by their type */
4439 for (f = type->ref->next; f; f = f->next) {
4440 int s, px, cx, c0;
4441 CType t;
4443 if (0 == (f->type.t & VT_BITFIELD))
4444 continue;
4445 f->type.ref = f;
4446 f->auxtype = -1;
4447 bit_size = BIT_SIZE(f->type.t);
4448 if (bit_size == 0)
4449 continue;
4450 bit_pos = BIT_POS(f->type.t);
4451 size = type_size(&f->type, &align);
4452 if (bit_pos + bit_size <= size * 8 && f->c + size <= c)
4453 continue;
4455 /* try to access the field using a different type */
4456 c0 = -1, s = align = 1;
4457 t.t = VT_BYTE;
4458 for (;;) {
4459 px = f->c * 8 + bit_pos;
4460 cx = (px >> 3) & -align;
4461 px = px - (cx << 3);
4462 if (c0 == cx)
4463 break;
4464 s = (px + bit_size + 7) >> 3;
4465 if (s > 4) {
4466 t.t = VT_LLONG;
4467 } else if (s > 2) {
4468 t.t = VT_INT;
4469 } else if (s > 1) {
4470 t.t = VT_SHORT;
4471 } else {
4472 t.t = VT_BYTE;
4474 s = type_size(&t, &align);
4475 c0 = cx;
4478 if (px + bit_size <= s * 8 && cx + s <= c) {
4479 /* update offset and bit position */
4480 f->c = cx;
4481 bit_pos = px;
4482 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
4483 | (bit_pos << VT_STRUCT_SHIFT);
4484 if (s != size)
4485 f->auxtype = t.t;
4486 #ifdef BF_DEBUG
4487 printf("FIX field %s offset %-2d size %-2d align %-2d "
4488 "pos %-2d bits %-2d\n",
4489 get_tok_str(f->v & ~SYM_FIELD, NULL),
4490 cx, s, align, px, bit_size);
4491 #endif
4492 } else {
4493 /* fall back to load/store single-byte wise */
4494 f->auxtype = VT_STRUCT;
4495 #ifdef BF_DEBUG
4496 printf("FIX field %s : load byte-wise\n",
4497 get_tok_str(f->v & ~SYM_FIELD, NULL));
4498 #endif
4503 /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
4504 static void struct_decl(CType *type, int u)
4506 int v, c, size, align, flexible;
4507 int bit_size, bsize, bt;
4508 Sym *s, *ss, **ps;
4509 AttributeDef ad, ad1;
4510 CType type1, btype;
4512 memset(&ad, 0, sizeof ad);
4513 next();
4514 parse_attribute(&ad);
4515 if (tok != '{') {
4516 v = tok;
4517 next();
4518 /* struct already defined ? return it */
4519 if (v < TOK_IDENT)
4520 expect("struct/union/enum name");
4521 s = struct_find(v);
4522 if (s && (s->sym_scope == local_scope || tok != '{')) {
4523 if (u == s->type.t)
4524 goto do_decl;
4525 if (u == VT_ENUM && IS_ENUM(s->type.t))
4526 goto do_decl;
4527 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
4529 } else {
4530 v = anon_sym++;
4532 /* Record the original enum/struct/union token. */
4533 type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u;
4534 type1.ref = NULL;
4535 /* we put an undefined size for struct/union */
4536 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
4537 s->r = 0; /* default alignment is zero as gcc */
4538 do_decl:
4539 type->t = s->type.t;
4540 type->ref = s;
4542 if (tok == '{') {
4543 next();
4544 if (s->c != -1)
4545 tcc_error("struct/union/enum already defined");
4546 s->c = -2;
4547 /* cannot be empty */
4548 /* non empty enums are not allowed */
4549 ps = &s->next;
4550 if (u == VT_ENUM) {
4551 long long ll = 0, pl = 0, nl = 0;
4552 CType t;
4553 t.ref = s;
4554 /* enum symbols have static storage */
4555 t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;
4556 for(;;) {
4557 v = tok;
4558 if (v < TOK_UIDENT)
4559 expect("identifier");
4560 ss = sym_find(v);
4561 if (ss && !local_stack)
4562 tcc_error("redefinition of enumerator '%s'",
4563 get_tok_str(v, NULL));
4564 next();
4565 if (tok == '=') {
4566 next();
4567 ll = expr_const64();
4569 ss = sym_push(v, &t, VT_CONST, 0);
4570 ss->enum_val = ll;
4571 *ps = ss, ps = &ss->next;
4572 if (ll < nl)
4573 nl = ll;
4574 if (ll > pl)
4575 pl = ll;
4576 if (tok != ',')
4577 break;
4578 next();
4579 ll++;
4580 /* NOTE: we accept a trailing comma */
4581 if (tok == '}')
4582 break;
4584 skip('}');
4585 /* set integral type of the enum */
4586 t.t = VT_INT;
4587 if (nl >= 0) {
4588 if (pl != (unsigned)pl)
4589 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
4590 t.t |= VT_UNSIGNED;
4591 } else if (pl != (int)pl || nl != (int)nl)
4592 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
4593 s->type.t = type->t = t.t | VT_ENUM;
4594 s->c = 0;
4595 /* set type for enum members */
4596 for (ss = s->next; ss; ss = ss->next) {
4597 ll = ss->enum_val;
4598 if (ll == (int)ll) /* default is int if it fits */
4599 continue;
4600 if (t.t & VT_UNSIGNED) {
4601 ss->type.t |= VT_UNSIGNED;
4602 if (ll == (unsigned)ll)
4603 continue;
4605 ss->type.t = (ss->type.t & ~VT_BTYPE)
4606 | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
4608 } else {
4609 c = 0;
4610 flexible = 0;
4611 while (tok != '}') {
4612 if (!parse_btype(&btype, &ad1)) {
4613 skip(';');
4614 continue;
4616 while (1) {
4617 if (flexible)
4618 tcc_error("flexible array member '%s' not at the end of struct",
4619 get_tok_str(v, NULL));
4620 bit_size = -1;
4621 v = 0;
4622 type1 = btype;
4623 if (tok != ':') {
4624 if (tok != ';')
4625 type_decl(&type1, &ad1, &v, TYPE_DIRECT);
4626 if (v == 0) {
4627 if ((type1.t & VT_BTYPE) != VT_STRUCT)
4628 expect("identifier");
4629 else {
4630 int v = btype.ref->v;
4631 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
4632 if (tcc_state->ms_extensions == 0)
4633 expect("identifier");
4637 if (type_size(&type1, &align) < 0) {
4638 if ((u == VT_STRUCT) && (type1.t & VT_ARRAY) && c)
4639 flexible = 1;
4640 else
4641 tcc_error("field '%s' has incomplete type",
4642 get_tok_str(v, NULL));
4644 if ((type1.t & VT_BTYPE) == VT_FUNC ||
4645 (type1.t & VT_BTYPE) == VT_VOID ||
4646 (type1.t & VT_STORAGE))
4647 tcc_error("invalid type for '%s'",
4648 get_tok_str(v, NULL));
4650 if (tok == ':') {
4651 next();
4652 bit_size = expr_const();
4653 /* XXX: handle v = 0 case for messages */
4654 if (bit_size < 0)
4655 tcc_error("negative width in bit-field '%s'",
4656 get_tok_str(v, NULL));
4657 if (v && bit_size == 0)
4658 tcc_error("zero width for bit-field '%s'",
4659 get_tok_str(v, NULL));
4660 parse_attribute(&ad1);
4662 size = type_size(&type1, &align);
4663 if (bit_size >= 0) {
4664 bt = type1.t & VT_BTYPE;
4665 if (bt != VT_INT &&
4666 bt != VT_BYTE &&
4667 bt != VT_SHORT &&
4668 bt != VT_BOOL &&
4669 bt != VT_LLONG)
4670 tcc_error("bitfields must have scalar type");
4671 bsize = size * 8;
4672 if (bit_size > bsize) {
4673 tcc_error("width of '%s' exceeds its type",
4674 get_tok_str(v, NULL));
4675 } else if (bit_size == bsize
4676 && !ad.a.packed && !ad1.a.packed) {
4677 /* no need for bit fields */
4679 } else if (bit_size == 64) {
4680 tcc_error("field width 64 not implemented");
4681 } else {
4682 type1.t = (type1.t & ~VT_STRUCT_MASK)
4683 | VT_BITFIELD
4684 | (bit_size << (VT_STRUCT_SHIFT + 6));
4687 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
4688 /* Remember we've seen a real field to check
4689 for placement of flexible array member. */
4690 c = 1;
4692 /* If member is a struct or bit-field, enforce
4693 placing into the struct (as anonymous). */
4694 if (v == 0 &&
4695 ((type1.t & VT_BTYPE) == VT_STRUCT ||
4696 bit_size >= 0)) {
4697 v = anon_sym++;
4699 if (v) {
4700 ss = sym_push(v | SYM_FIELD, &type1, 0, 0);
4701 ss->a = ad1.a;
4702 *ps = ss;
4703 ps = &ss->next;
4705 if (tok == ';' || tok == TOK_EOF)
4706 break;
4707 skip(',');
4709 skip(';');
4711 skip('}');
4712 parse_attribute(&ad);
4713 if (ad.cleanup_func) {
4714 tcc_warning("attribute '__cleanup__' ignored on type");
4716 struct_layout(type, &ad);
4721 static void sym_to_attr(AttributeDef *ad, Sym *s)
4723 merge_symattr(&ad->a, &s->a);
4724 merge_funcattr(&ad->f, &s->f);
4727 /* Add type qualifiers to a type. If the type is an array then the qualifiers
4728 are added to the element type, copied because it could be a typedef. */
4729 static void parse_btype_qualify(CType *type, int qualifiers)
4731 while (type->t & VT_ARRAY) {
4732 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
4733 type = &type->ref->type;
4735 type->t |= qualifiers;
4738 /* return 0 if no type declaration. otherwise, return the basic type
4739 and skip it.
4741 static int parse_btype(CType *type, AttributeDef *ad)
4743 int t, u, bt, st, type_found, typespec_found, g, n;
4744 Sym *s;
4745 CType type1;
4747 memset(ad, 0, sizeof(AttributeDef));
4748 type_found = 0;
4749 typespec_found = 0;
4750 t = VT_INT;
4751 bt = st = -1;
4752 type->ref = NULL;
4754 while(1) {
4755 switch(tok) {
4756 case TOK_EXTENSION:
4757 /* currently, we really ignore extension */
4758 next();
4759 continue;
4761 /* basic types */
4762 case TOK_CHAR:
4763 u = VT_BYTE;
4764 basic_type:
4765 next();
4766 basic_type1:
4767 if (u == VT_SHORT || u == VT_LONG) {
4768 if (st != -1 || (bt != -1 && bt != VT_INT))
4769 tmbt: tcc_error("too many basic types");
4770 st = u;
4771 } else {
4772 if (bt != -1 || (st != -1 && u != VT_INT))
4773 goto tmbt;
4774 bt = u;
4776 if (u != VT_INT)
4777 t = (t & ~(VT_BTYPE|VT_LONG)) | u;
4778 typespec_found = 1;
4779 break;
4780 case TOK_VOID:
4781 u = VT_VOID;
4782 goto basic_type;
4783 case TOK_SHORT:
4784 u = VT_SHORT;
4785 goto basic_type;
4786 case TOK_INT:
4787 u = VT_INT;
4788 goto basic_type;
4789 case TOK_ALIGNAS:
4790 { int n;
4791 AttributeDef ad1;
4792 next();
4793 skip('(');
4794 memset(&ad1, 0, sizeof(AttributeDef));
4795 if (parse_btype(&type1, &ad1)) {
4796 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
4797 if (ad1.a.aligned)
4798 n = 1 << (ad1.a.aligned - 1);
4799 else
4800 type_size(&type1, &n);
4801 } else {
4802 n = expr_const();
4803 if (n <= 0 || (n & (n - 1)) != 0)
4804 tcc_error("alignment must be a positive power of two");
4806 skip(')');
4807 ad->a.aligned = exact_log2p1(n);
4809 continue;
4810 case TOK_LONG:
4811 if ((t & VT_BTYPE) == VT_DOUBLE) {
4812 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
4813 } else if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
4814 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LLONG;
4815 } else {
4816 u = VT_LONG;
4817 goto basic_type;
4819 next();
4820 break;
4821 #ifdef TCC_TARGET_ARM64
4822 case TOK_UINT128:
4823 /* GCC's __uint128_t appears in some Linux header files. Make it a
4824 synonym for long double to get the size and alignment right. */
4825 u = VT_LDOUBLE;
4826 goto basic_type;
4827 #endif
4828 case TOK_BOOL:
4829 u = VT_BOOL;
4830 goto basic_type;
4831 case TOK_FLOAT:
4832 u = VT_FLOAT;
4833 goto basic_type;
4834 case TOK_DOUBLE:
4835 if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
4836 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
4837 } else {
4838 u = VT_DOUBLE;
4839 goto basic_type;
4841 next();
4842 break;
4843 case TOK_ENUM:
4844 struct_decl(&type1, VT_ENUM);
4845 basic_type2:
4846 u = type1.t;
4847 type->ref = type1.ref;
4848 goto basic_type1;
4849 case TOK_STRUCT:
4850 struct_decl(&type1, VT_STRUCT);
4851 goto basic_type2;
4852 case TOK_UNION:
4853 struct_decl(&type1, VT_UNION);
4854 goto basic_type2;
4856 /* type modifiers */
4857 case TOK_CONST1:
4858 case TOK_CONST2:
4859 case TOK_CONST3:
4860 type->t = t;
4861 parse_btype_qualify(type, VT_CONSTANT);
4862 t = type->t;
4863 next();
4864 break;
4865 case TOK_VOLATILE1:
4866 case TOK_VOLATILE2:
4867 case TOK_VOLATILE3:
4868 type->t = t;
4869 parse_btype_qualify(type, VT_VOLATILE);
4870 t = type->t;
4871 next();
4872 break;
4873 case TOK_SIGNED1:
4874 case TOK_SIGNED2:
4875 case TOK_SIGNED3:
4876 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
4877 tcc_error("signed and unsigned modifier");
4878 t |= VT_DEFSIGN;
4879 next();
4880 typespec_found = 1;
4881 break;
4882 case TOK_REGISTER:
4883 case TOK_AUTO:
4884 case TOK_RESTRICT1:
4885 case TOK_RESTRICT2:
4886 case TOK_RESTRICT3:
4887 next();
4888 break;
4889 case TOK_UNSIGNED:
4890 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
4891 tcc_error("signed and unsigned modifier");
4892 t |= VT_DEFSIGN | VT_UNSIGNED;
4893 next();
4894 typespec_found = 1;
4895 break;
4897 /* storage */
4898 case TOK_EXTERN:
4899 g = VT_EXTERN;
4900 goto storage;
4901 case TOK_STATIC:
4902 g = VT_STATIC;
4903 goto storage;
4904 case TOK_TYPEDEF:
4905 g = VT_TYPEDEF;
4906 goto storage;
4907 storage:
4908 if (t & (VT_EXTERN|VT_STATIC|VT_TYPEDEF) & ~g)
4909 tcc_error("multiple storage classes");
4910 t |= g;
4911 next();
4912 break;
4913 case TOK_INLINE1:
4914 case TOK_INLINE2:
4915 case TOK_INLINE3:
4916 t |= VT_INLINE;
4917 next();
4918 break;
4919 case TOK_NORETURN3:
4920 next();
4921 ad->f.func_noreturn = 1;
4922 break;
4923 /* GNUC attribute */
4924 case TOK_ATTRIBUTE1:
4925 case TOK_ATTRIBUTE2:
4926 parse_attribute(ad);
4927 if (ad->attr_mode) {
4928 u = ad->attr_mode -1;
4929 t = (t & ~(VT_BTYPE|VT_LONG)) | u;
4931 continue;
4932 /* GNUC typeof */
4933 case TOK_TYPEOF1:
4934 case TOK_TYPEOF2:
4935 case TOK_TYPEOF3:
4936 next();
4937 parse_expr_type(&type1);
4938 /* remove all storage modifiers except typedef */
4939 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
4940 if (type1.ref)
4941 sym_to_attr(ad, type1.ref);
4942 goto basic_type2;
4943 default:
4944 if (typespec_found)
4945 goto the_end;
4946 s = sym_find(tok);
4947 if (!s || !(s->type.t & VT_TYPEDEF))
4948 goto the_end;
4950 n = tok, next();
4951 if (tok == ':' && !in_generic) {
4952 /* ignore if it's a label */
4953 unget_tok(n);
4954 goto the_end;
4957 t &= ~(VT_BTYPE|VT_LONG);
4958 u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u;
4959 type->t = (s->type.t & ~VT_TYPEDEF) | u;
4960 type->ref = s->type.ref;
4961 if (t)
4962 parse_btype_qualify(type, t);
4963 t = type->t;
4964 /* get attributes from typedef */
4965 sym_to_attr(ad, s);
4966 typespec_found = 1;
4967 st = bt = -2;
4968 break;
4970 type_found = 1;
4972 the_end:
4973 if (tcc_state->char_is_unsigned) {
4974 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
4975 t |= VT_UNSIGNED;
4977 /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
4978 bt = t & (VT_BTYPE|VT_LONG);
4979 if (bt == VT_LONG)
4980 t |= LONG_SIZE == 8 ? VT_LLONG : VT_INT;
4981 #ifdef TCC_TARGET_PE
4982 if (bt == VT_LDOUBLE)
4983 t = (t & ~(VT_BTYPE|VT_LONG)) | (VT_DOUBLE|VT_LONG);
4984 #endif
4985 type->t = t;
4986 return type_found;
4989 /* convert a function parameter type (array to pointer and function to
4990 function pointer) */
4991 static inline void convert_parameter_type(CType *pt)
4993 /* remove const and volatile qualifiers (XXX: const could be used
4994 to indicate a const function parameter */
4995 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
4996 /* array must be transformed to pointer according to ANSI C */
4997 pt->t &= ~VT_ARRAY;
4998 if ((pt->t & VT_BTYPE) == VT_FUNC) {
4999 mk_pointer(pt);
5003 ST_FUNC void parse_asm_str(CString *astr)
5005 skip('(');
5006 parse_mult_str(astr, "string constant");
5009 /* Parse an asm label and return the token */
5010 static int asm_label_instr(void)
5012 int v;
5013 CString astr;
5015 next();
5016 parse_asm_str(&astr);
5017 skip(')');
5018 #ifdef ASM_DEBUG
5019 printf("asm_alias: \"%s\"\n", (char *)astr.data);
5020 #endif
5021 v = tok_alloc(astr.data, astr.size - 1)->tok;
5022 cstr_free(&astr);
5023 return v;
5026 static int post_type(CType *type, AttributeDef *ad, int storage, int td)
5028 int n, l, t1, arg_size, align, unused_align;
5029 Sym **plast, *s, *first;
5030 AttributeDef ad1;
5031 CType pt;
5033 if (tok == '(') {
5034 /* function type, or recursive declarator (return if so) */
5035 next();
5036 if (td && !(td & TYPE_ABSTRACT))
5037 return 0;
5038 if (tok == ')')
5039 l = 0;
5040 else if (parse_btype(&pt, &ad1))
5041 l = FUNC_NEW;
5042 else if (td) {
5043 merge_attr (ad, &ad1);
5044 return 0;
5045 } else
5046 l = FUNC_OLD;
5047 first = NULL;
5048 plast = &first;
5049 arg_size = 0;
5050 if (l) {
5051 for(;;) {
5052 /* read param name and compute offset */
5053 if (l != FUNC_OLD) {
5054 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
5055 break;
5056 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
5057 if ((pt.t & VT_BTYPE) == VT_VOID)
5058 tcc_error("parameter declared as void");
5059 } else {
5060 n = tok;
5061 if (n < TOK_UIDENT)
5062 expect("identifier");
5063 pt.t = VT_VOID; /* invalid type */
5064 pt.ref = NULL;
5065 next();
5067 convert_parameter_type(&pt);
5068 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
5069 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
5070 *plast = s;
5071 plast = &s->next;
5072 if (tok == ')')
5073 break;
5074 skip(',');
5075 if (l == FUNC_NEW && tok == TOK_DOTS) {
5076 l = FUNC_ELLIPSIS;
5077 next();
5078 break;
5080 if (l == FUNC_NEW && !parse_btype(&pt, &ad1))
5081 tcc_error("invalid type");
5083 } else
5084 /* if no parameters, then old type prototype */
5085 l = FUNC_OLD;
5086 skip(')');
5087 /* NOTE: const is ignored in returned type as it has a special
5088 meaning in gcc / C++ */
5089 type->t &= ~VT_CONSTANT;
5090 /* some ancient pre-K&R C allows a function to return an array
5091 and the array brackets to be put after the arguments, such
5092 that "int c()[]" means something like "int[] c()" */
5093 if (tok == '[') {
5094 next();
5095 skip(']'); /* only handle simple "[]" */
5096 mk_pointer(type);
5098 /* we push a anonymous symbol which will contain the function prototype */
5099 ad->f.func_args = arg_size;
5100 ad->f.func_type = l;
5101 s = sym_push(SYM_FIELD, type, 0, 0);
5102 s->a = ad->a;
5103 s->f = ad->f;
5104 s->next = first;
5105 type->t = VT_FUNC;
5106 type->ref = s;
5107 } else if (tok == '[') {
5108 int saved_nocode_wanted = nocode_wanted;
5109 /* array definition */
5110 next();
5111 while (1) {
5112 /* XXX The optional type-quals and static should only be accepted
5113 in parameter decls. The '*' as well, and then even only
5114 in prototypes (not function defs). */
5115 switch (tok) {
5116 case TOK_RESTRICT1: case TOK_RESTRICT2: case TOK_RESTRICT3:
5117 case TOK_CONST1:
5118 case TOK_VOLATILE1:
5119 case TOK_STATIC:
5120 case '*':
5121 next();
5122 continue;
5123 default:
5124 break;
5126 break;
5128 n = -1;
5129 t1 = 0;
5130 if (tok != ']') {
5131 if (!local_stack || (storage & VT_STATIC))
5132 vpushi(expr_const());
5133 else {
5134 /* VLAs (which can only happen with local_stack && !VT_STATIC)
5135 length must always be evaluated, even under nocode_wanted,
5136 so that its size slot is initialized (e.g. under sizeof
5137 or typeof). */
5138 nocode_wanted = 0;
5139 gexpr();
5141 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
5142 n = vtop->c.i;
5143 if (n < 0)
5144 tcc_error("invalid array size");
5145 } else {
5146 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
5147 tcc_error("size of variable length array should be an integer");
5148 n = 0;
5149 t1 = VT_VLA;
5152 skip(']');
5153 /* parse next post type */
5154 post_type(type, ad, storage, 0);
5156 if ((type->t & VT_BTYPE) == VT_FUNC)
5157 tcc_error("declaration of an array of functions");
5158 if ((type->t & VT_BTYPE) == VT_VOID
5159 || type_size(type, &unused_align) < 0)
5160 tcc_error("declaration of an array of incomplete type elements");
5162 t1 |= type->t & VT_VLA;
5164 if (t1 & VT_VLA) {
5165 if (n < 0)
5166 tcc_error("need explicit inner array size in VLAs");
5167 loc -= type_size(&int_type, &align);
5168 loc &= -align;
5169 n = loc;
5171 vla_runtime_type_size(type, &align);
5172 gen_op('*');
5173 vset(&int_type, VT_LOCAL|VT_LVAL, n);
5174 vswap();
5175 vstore();
5177 if (n != -1)
5178 vpop();
5179 nocode_wanted = saved_nocode_wanted;
5181 /* we push an anonymous symbol which will contain the array
5182 element type */
5183 s = sym_push(SYM_FIELD, type, 0, n);
5184 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
5185 type->ref = s;
5187 return 1;
5190 /* Parse a type declarator (except basic type), and return the type
5191 in 'type'. 'td' is a bitmask indicating which kind of type decl is
5192 expected. 'type' should contain the basic type. 'ad' is the
5193 attribute definition of the basic type. It can be modified by
5194 type_decl(). If this (possibly abstract) declarator is a pointer chain
5195 it returns the innermost pointed to type (equals *type, but is a different
5196 pointer), otherwise returns type itself, that's used for recursive calls. */
5197 static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td)
5199 CType *post, *ret;
5200 int qualifiers, storage;
5202 /* recursive type, remove storage bits first, apply them later again */
5203 storage = type->t & VT_STORAGE;
5204 type->t &= ~VT_STORAGE;
5205 post = ret = type;
5207 while (tok == '*') {
5208 qualifiers = 0;
5209 redo:
5210 next();
5211 switch(tok) {
5212 case TOK_CONST1:
5213 case TOK_CONST2:
5214 case TOK_CONST3:
5215 qualifiers |= VT_CONSTANT;
5216 goto redo;
5217 case TOK_VOLATILE1:
5218 case TOK_VOLATILE2:
5219 case TOK_VOLATILE3:
5220 qualifiers |= VT_VOLATILE;
5221 goto redo;
5222 case TOK_RESTRICT1:
5223 case TOK_RESTRICT2:
5224 case TOK_RESTRICT3:
5225 goto redo;
5226 /* XXX: clarify attribute handling */
5227 case TOK_ATTRIBUTE1:
5228 case TOK_ATTRIBUTE2:
5229 parse_attribute(ad);
5230 break;
5232 mk_pointer(type);
5233 type->t |= qualifiers;
5234 if (ret == type)
5235 /* innermost pointed to type is the one for the first derivation */
5236 ret = pointed_type(type);
5239 if (tok == '(') {
5240 /* This is possibly a parameter type list for abstract declarators
5241 ('int ()'), use post_type for testing this. */
5242 if (!post_type(type, ad, 0, td)) {
5243 /* It's not, so it's a nested declarator, and the post operations
5244 apply to the innermost pointed to type (if any). */
5245 /* XXX: this is not correct to modify 'ad' at this point, but
5246 the syntax is not clear */
5247 parse_attribute(ad);
5248 post = type_decl(type, ad, v, td);
5249 skip(')');
5250 } else
5251 goto abstract;
5252 } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
5253 /* type identifier */
5254 *v = tok;
5255 next();
5256 } else {
5257 abstract:
5258 if (!(td & TYPE_ABSTRACT))
5259 expect("identifier");
5260 *v = 0;
5262 post_type(post, ad, storage, 0);
5263 parse_attribute(ad);
5264 type->t |= storage;
5265 return ret;
5268 /* indirection with full error checking and bound check */
5269 ST_FUNC void indir(void)
5271 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
5272 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
5273 return;
5274 expect("pointer");
5276 if (vtop->r & VT_LVAL)
5277 gv(RC_INT);
5278 vtop->type = *pointed_type(&vtop->type);
5279 /* Arrays and functions are never lvalues */
5280 if (!(vtop->type.t & (VT_ARRAY | VT_VLA))
5281 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
5282 vtop->r |= VT_LVAL;
5283 /* if bound checking, the referenced pointer must be checked */
5284 #ifdef CONFIG_TCC_BCHECK
5285 if (tcc_state->do_bounds_check)
5286 vtop->r |= VT_MUSTBOUND;
5287 #endif
5291 /* pass a parameter to a function and do type checking and casting */
5292 static void gfunc_param_typed(Sym *func, Sym *arg)
5294 int func_type;
5295 CType type;
5297 func_type = func->f.func_type;
5298 if (func_type == FUNC_OLD ||
5299 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
5300 /* default casting : only need to convert float to double */
5301 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
5302 gen_cast_s(VT_DOUBLE);
5303 } else if (vtop->type.t & VT_BITFIELD) {
5304 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
5305 type.ref = vtop->type.ref;
5306 gen_cast(&type);
5307 } else if (vtop->r & VT_MUSTCAST) {
5308 force_charshort_cast();
5310 } else if (arg == NULL) {
5311 tcc_error("too many arguments to function");
5312 } else {
5313 type = arg->type;
5314 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
5315 gen_assign_cast(&type);
5319 /* parse an expression and return its type without any side effect. */
5320 static void expr_type(CType *type, void (*expr_fn)(void))
5322 nocode_wanted++;
5323 expr_fn();
5324 *type = vtop->type;
5325 vpop();
5326 nocode_wanted--;
5329 /* parse an expression of the form '(type)' or '(expr)' and return its
5330 type */
5331 static void parse_expr_type(CType *type)
5333 int n;
5334 AttributeDef ad;
5336 skip('(');
5337 if (parse_btype(type, &ad)) {
5338 type_decl(type, &ad, &n, TYPE_ABSTRACT);
5339 } else {
5340 expr_type(type, gexpr);
5342 skip(')');
5345 static void parse_type(CType *type)
5347 AttributeDef ad;
5348 int n;
5350 if (!parse_btype(type, &ad)) {
5351 expect("type");
5353 type_decl(type, &ad, &n, TYPE_ABSTRACT);
5356 static void parse_builtin_params(int nc, const char *args)
5358 char c, sep = '(';
5359 CType t;
5360 if (nc)
5361 nocode_wanted++;
5362 next();
5363 while ((c = *args++)) {
5364 skip(sep);
5365 sep = ',';
5366 switch (c) {
5367 case 'e': expr_eq(); continue;
5368 case 't': parse_type(&t); vpush(&t); continue;
5369 default: tcc_error("internal error"); break;
5372 skip(')');
5373 if (nc)
5374 nocode_wanted--;
5377 ST_FUNC void unary(void)
5379 int n, t, align, size, r, sizeof_caller;
5380 CType type;
5381 Sym *s;
5382 AttributeDef ad;
5384 /* generate line number info */
5385 if (tcc_state->do_debug)
5386 tcc_debug_line(tcc_state);
5388 sizeof_caller = in_sizeof;
5389 in_sizeof = 0;
5390 type.ref = NULL;
5391 /* XXX: GCC 2.95.3 does not generate a table although it should be
5392 better here */
5393 tok_next:
5394 switch(tok) {
5395 case TOK_EXTENSION:
5396 next();
5397 goto tok_next;
5398 case TOK_LCHAR:
5399 #ifdef TCC_TARGET_PE
5400 t = VT_SHORT|VT_UNSIGNED;
5401 goto push_tokc;
5402 #endif
5403 case TOK_CINT:
5404 case TOK_CCHAR:
5405 t = VT_INT;
5406 push_tokc:
5407 type.t = t;
5408 vsetc(&type, VT_CONST, &tokc);
5409 next();
5410 break;
5411 case TOK_CUINT:
5412 t = VT_INT | VT_UNSIGNED;
5413 goto push_tokc;
5414 case TOK_CLLONG:
5415 t = VT_LLONG;
5416 goto push_tokc;
5417 case TOK_CULLONG:
5418 t = VT_LLONG | VT_UNSIGNED;
5419 goto push_tokc;
5420 case TOK_CFLOAT:
5421 t = VT_FLOAT;
5422 goto push_tokc;
5423 case TOK_CDOUBLE:
5424 t = VT_DOUBLE;
5425 goto push_tokc;
5426 case TOK_CLDOUBLE:
5427 t = VT_LDOUBLE;
5428 goto push_tokc;
5429 case TOK_CLONG:
5430 t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG;
5431 goto push_tokc;
5432 case TOK_CULONG:
5433 t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG | VT_UNSIGNED;
5434 goto push_tokc;
5435 case TOK___FUNCTION__:
5436 if (!gnu_ext)
5437 goto tok_identifier;
5438 /* fall thru */
5439 case TOK___FUNC__:
5441 void *ptr;
5442 int len;
5443 /* special function name identifier */
5444 len = strlen(funcname) + 1;
5445 /* generate char[len] type */
5446 type.t = VT_BYTE;
5447 mk_pointer(&type);
5448 type.t |= VT_ARRAY;
5449 type.ref->c = len;
5450 vpush_ref(&type, data_section, data_section->data_offset, len);
5451 if (!NODATA_WANTED) {
5452 ptr = section_ptr_add(data_section, len);
5453 memcpy(ptr, funcname, len);
5455 next();
5457 break;
5458 case TOK_LSTR:
5459 #ifdef TCC_TARGET_PE
5460 t = VT_SHORT | VT_UNSIGNED;
5461 #else
5462 t = VT_INT;
5463 #endif
5464 goto str_init;
5465 case TOK_STR:
5466 /* string parsing */
5467 t = VT_BYTE;
5468 if (tcc_state->char_is_unsigned)
5469 t = VT_BYTE | VT_UNSIGNED;
5470 str_init:
5471 if (tcc_state->warn_write_strings)
5472 t |= VT_CONSTANT;
5473 type.t = t;
5474 mk_pointer(&type);
5475 type.t |= VT_ARRAY;
5476 memset(&ad, 0, sizeof(AttributeDef));
5477 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
5478 break;
5479 case '(':
5480 next();
5481 /* cast ? */
5482 if (parse_btype(&type, &ad)) {
5483 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
5484 skip(')');
5485 /* check ISOC99 compound literal */
5486 if (tok == '{') {
5487 /* data is allocated locally by default */
5488 if (global_expr)
5489 r = VT_CONST;
5490 else
5491 r = VT_LOCAL;
5492 /* all except arrays are lvalues */
5493 if (!(type.t & VT_ARRAY))
5494 r |= VT_LVAL;
5495 memset(&ad, 0, sizeof(AttributeDef));
5496 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
5497 } else {
5498 if (sizeof_caller) {
5499 vpush(&type);
5500 return;
5502 unary();
5503 gen_cast(&type);
5505 } else if (tok == '{') {
5506 int saved_nocode_wanted = nocode_wanted;
5507 if (const_wanted && !(nocode_wanted & unevalmask))
5508 tcc_error("expected constant");
5509 /* save all registers */
5510 save_regs(0);
5511 /* statement expression : we do not accept break/continue
5512 inside as GCC does. We do retain the nocode_wanted state,
5513 as statement expressions can't ever be entered from the
5514 outside, so any reactivation of code emission (from labels
5515 or loop heads) can be disabled again after the end of it. */
5516 block(1);
5517 nocode_wanted = saved_nocode_wanted;
5518 skip(')');
5519 } else {
5520 gexpr();
5521 skip(')');
5523 break;
5524 case '*':
5525 next();
5526 unary();
5527 indir();
5528 break;
5529 case '&':
5530 next();
5531 unary();
5532 /* functions names must be treated as function pointers,
5533 except for unary '&' and sizeof. Since we consider that
5534 functions are not lvalues, we only have to handle it
5535 there and in function calls. */
5536 /* arrays can also be used although they are not lvalues */
5537 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
5538 !(vtop->type.t & VT_ARRAY))
5539 test_lvalue();
5540 if (vtop->sym)
5541 vtop->sym->a.addrtaken = 1;
5542 mk_pointer(&vtop->type);
5543 gaddrof();
5544 break;
5545 case '!':
5546 next();
5547 unary();
5548 gen_test_zero(TOK_EQ);
5549 break;
5550 case '~':
5551 next();
5552 unary();
5553 vpushi(-1);
5554 gen_op('^');
5555 break;
5556 case '+':
5557 next();
5558 unary();
5559 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
5560 tcc_error("pointer not accepted for unary plus");
5561 /* In order to force cast, we add zero, except for floating point
5562 where we really need an noop (otherwise -0.0 will be transformed
5563 into +0.0). */
5564 if (!is_float(vtop->type.t)) {
5565 vpushi(0);
5566 gen_op('+');
5568 break;
5569 case TOK_SIZEOF:
5570 case TOK_ALIGNOF1:
5571 case TOK_ALIGNOF2:
5572 case TOK_ALIGNOF3:
5573 t = tok;
5574 next();
5575 in_sizeof++;
5576 expr_type(&type, unary); /* Perform a in_sizeof = 0; */
5577 s = NULL;
5578 if (vtop[1].r & VT_SYM)
5579 s = vtop[1].sym; /* hack: accessing previous vtop */
5580 size = type_size(&type, &align);
5581 if (s && s->a.aligned)
5582 align = 1 << (s->a.aligned - 1);
5583 if (t == TOK_SIZEOF) {
5584 if (!(type.t & VT_VLA)) {
5585 if (size < 0)
5586 tcc_error("sizeof applied to an incomplete type");
5587 vpushs(size);
5588 } else {
5589 vla_runtime_type_size(&type, &align);
5591 } else {
5592 vpushs(align);
5594 vtop->type.t |= VT_UNSIGNED;
5595 break;
5597 case TOK_builtin_expect:
5598 /* __builtin_expect is a no-op for now */
5599 parse_builtin_params(0, "ee");
5600 vpop();
5601 break;
5602 case TOK_builtin_types_compatible_p:
5603 parse_builtin_params(0, "tt");
5604 vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
5605 vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
5606 n = is_compatible_types(&vtop[-1].type, &vtop[0].type);
5607 vtop -= 2;
5608 vpushi(n);
5609 break;
5610 case TOK_builtin_choose_expr:
5612 int64_t c;
5613 next();
5614 skip('(');
5615 c = expr_const64();
5616 skip(',');
5617 if (!c) {
5618 nocode_wanted++;
5620 expr_eq();
5621 if (!c) {
5622 vpop();
5623 nocode_wanted--;
5625 skip(',');
5626 if (c) {
5627 nocode_wanted++;
5629 expr_eq();
5630 if (c) {
5631 vpop();
5632 nocode_wanted--;
5634 skip(')');
5636 break;
5637 case TOK_builtin_constant_p:
5638 parse_builtin_params(1, "e");
5639 n = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5640 vtop--;
5641 vpushi(n);
5642 break;
5643 case TOK_builtin_frame_address:
5644 case TOK_builtin_return_address:
5646 int tok1 = tok;
5647 int level;
5648 next();
5649 skip('(');
5650 if (tok != TOK_CINT) {
5651 tcc_error("%s only takes positive integers",
5652 tok1 == TOK_builtin_return_address ?
5653 "__builtin_return_address" :
5654 "__builtin_frame_address");
5656 level = (uint32_t)tokc.i;
5657 next();
5658 skip(')');
5659 type.t = VT_VOID;
5660 mk_pointer(&type);
5661 vset(&type, VT_LOCAL, 0); /* local frame */
5662 while (level--) {
5663 #ifdef TCC_TARGET_RISCV64
5664 vpushi(2*PTR_SIZE);
5665 gen_op('-');
5666 #endif
5667 mk_pointer(&vtop->type);
5668 indir(); /* -> parent frame */
5670 if (tok1 == TOK_builtin_return_address) {
5671 // assume return address is just above frame pointer on stack
5672 #ifdef TCC_TARGET_ARM
5673 vpushi(2*PTR_SIZE);
5674 gen_op('+');
5675 #elif defined TCC_TARGET_RISCV64
5676 vpushi(PTR_SIZE);
5677 gen_op('-');
5678 #else
5679 vpushi(PTR_SIZE);
5680 gen_op('+');
5681 #endif
5682 mk_pointer(&vtop->type);
5683 indir();
5686 break;
5687 #ifdef TCC_TARGET_RISCV64
5688 case TOK_builtin_va_start:
5689 parse_builtin_params(0, "ee");
5690 r = vtop->r & VT_VALMASK;
5691 if (r == VT_LLOCAL)
5692 r = VT_LOCAL;
5693 if (r != VT_LOCAL)
5694 tcc_error("__builtin_va_start expects a local variable");
5695 gen_va_start();
5696 vstore();
5697 break;
5698 #endif
5699 #ifdef TCC_TARGET_X86_64
5700 #ifdef TCC_TARGET_PE
5701 case TOK_builtin_va_start:
5702 parse_builtin_params(0, "ee");
5703 r = vtop->r & VT_VALMASK;
5704 if (r == VT_LLOCAL)
5705 r = VT_LOCAL;
5706 if (r != VT_LOCAL)
5707 tcc_error("__builtin_va_start expects a local variable");
5708 vtop->r = r;
5709 vtop->type = char_pointer_type;
5710 vtop->c.i += 8;
5711 vstore();
5712 break;
5713 #else
5714 case TOK_builtin_va_arg_types:
5715 parse_builtin_params(0, "t");
5716 vpushi(classify_x86_64_va_arg(&vtop->type));
5717 vswap();
5718 vpop();
5719 break;
5720 #endif
5721 #endif
5723 #ifdef TCC_TARGET_ARM64
5724 case TOK_builtin_va_start: {
5725 parse_builtin_params(0, "ee");
5726 //xx check types
5727 gen_va_start();
5728 vpushi(0);
5729 vtop->type.t = VT_VOID;
5730 break;
5732 case TOK_builtin_va_arg: {
5733 parse_builtin_params(0, "et");
5734 type = vtop->type;
5735 vpop();
5736 //xx check types
5737 gen_va_arg(&type);
5738 vtop->type = type;
5739 break;
5741 case TOK___arm64_clear_cache: {
5742 parse_builtin_params(0, "ee");
5743 gen_clear_cache();
5744 vpushi(0);
5745 vtop->type.t = VT_VOID;
5746 break;
5748 #endif
5749 /* pre operations */
5750 case TOK_INC:
5751 case TOK_DEC:
5752 t = tok;
5753 next();
5754 unary();
5755 inc(0, t);
5756 break;
5757 case '-':
5758 next();
5759 unary();
5760 t = vtop->type.t & VT_BTYPE;
5761 if (is_float(t)) {
5762 /* In IEEE negate(x) isn't subtract(0,x), but rather
5763 subtract(-0, x). */
5764 vpush(&vtop->type);
5765 if (t == VT_FLOAT)
5766 vtop->c.f = -1.0 * 0.0;
5767 else if (t == VT_DOUBLE)
5768 vtop->c.d = -1.0 * 0.0;
5769 else
5770 vtop->c.ld = -1.0 * 0.0;
5771 } else
5772 vpushi(0);
5773 vswap();
5774 gen_op('-');
5775 break;
5776 case TOK_LAND:
5777 if (!gnu_ext)
5778 goto tok_identifier;
5779 next();
5780 /* allow to take the address of a label */
5781 if (tok < TOK_UIDENT)
5782 expect("label identifier");
5783 s = label_find(tok);
5784 if (!s) {
5785 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
5786 } else {
5787 if (s->r == LABEL_DECLARED)
5788 s->r = LABEL_FORWARD;
5790 if (!s->type.t) {
5791 s->type.t = VT_VOID;
5792 mk_pointer(&s->type);
5793 s->type.t |= VT_STATIC;
5795 vpushsym(&s->type, s);
5796 next();
5797 break;
5799 case TOK_GENERIC:
5801 CType controlling_type;
5802 int has_default = 0;
5803 int has_match = 0;
5804 int learn = 0;
5805 TokenString *str = NULL;
5806 int saved_const_wanted = const_wanted;
5808 next();
5809 skip('(');
5810 const_wanted = 0;
5811 expr_type(&controlling_type, expr_eq);
5812 controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY);
5813 if ((controlling_type.t & VT_BTYPE) == VT_FUNC)
5814 mk_pointer(&controlling_type);
5815 const_wanted = saved_const_wanted;
5816 for (;;) {
5817 learn = 0;
5818 skip(',');
5819 if (tok == TOK_DEFAULT) {
5820 if (has_default)
5821 tcc_error("too many 'default'");
5822 has_default = 1;
5823 if (!has_match)
5824 learn = 1;
5825 next();
5826 } else {
5827 AttributeDef ad_tmp;
5828 int itmp;
5829 CType cur_type;
5831 in_generic++;
5832 parse_btype(&cur_type, &ad_tmp);
5833 in_generic--;
5835 type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
5836 if (compare_types(&controlling_type, &cur_type, 0)) {
5837 if (has_match) {
5838 tcc_error("type match twice");
5840 has_match = 1;
5841 learn = 1;
5844 skip(':');
5845 if (learn) {
5846 if (str)
5847 tok_str_free(str);
5848 skip_or_save_block(&str);
5849 } else {
5850 skip_or_save_block(NULL);
5852 if (tok == ')')
5853 break;
5855 if (!str) {
5856 char buf[60];
5857 type_to_str(buf, sizeof buf, &controlling_type, NULL);
5858 tcc_error("type '%s' does not match any association", buf);
5860 begin_macro(str, 1);
5861 next();
5862 expr_eq();
5863 if (tok != TOK_EOF)
5864 expect(",");
5865 end_macro();
5866 next();
5867 break;
5869 // special qnan , snan and infinity values
5870 case TOK___NAN__:
5871 n = 0x7fc00000;
5872 special_math_val:
5873 vpushi(n);
5874 vtop->type.t = VT_FLOAT;
5875 next();
5876 break;
5877 case TOK___SNAN__:
5878 n = 0x7f800001;
5879 goto special_math_val;
5880 case TOK___INF__:
5881 n = 0x7f800000;
5882 goto special_math_val;
5884 default:
5885 tok_identifier:
5886 t = tok;
5887 next();
5888 if (t < TOK_UIDENT)
5889 expect("identifier");
5890 s = sym_find(t);
5891 if (!s || IS_ASM_SYM(s)) {
5892 const char *name = get_tok_str(t, NULL);
5893 if (tok != '(')
5894 tcc_error("'%s' undeclared", name);
5895 /* for simple function calls, we tolerate undeclared
5896 external reference to int() function */
5897 if (tcc_state->warn_implicit_function_declaration
5898 #ifdef TCC_TARGET_PE
5899 /* people must be warned about using undeclared WINAPI functions
5900 (which usually start with uppercase letter) */
5901 || (name[0] >= 'A' && name[0] <= 'Z')
5902 #endif
5904 tcc_warning("implicit declaration of function '%s'", name);
5905 s = external_global_sym(t, &func_old_type);
5908 r = s->r;
5909 /* A symbol that has a register is a local register variable,
5910 which starts out as VT_LOCAL value. */
5911 if ((r & VT_VALMASK) < VT_CONST)
5912 r = (r & ~VT_VALMASK) | VT_LOCAL;
5914 vset(&s->type, r, s->c);
5915 /* Point to s as backpointer (even without r&VT_SYM).
5916 Will be used by at least the x86 inline asm parser for
5917 regvars. */
5918 vtop->sym = s;
5920 if (r & VT_SYM) {
5921 vtop->c.i = 0;
5922 } else if (r == VT_CONST && IS_ENUM_VAL(s->type.t)) {
5923 vtop->c.i = s->enum_val;
5925 break;
5928 /* post operations */
5929 while (1) {
5930 if (tok == TOK_INC || tok == TOK_DEC) {
5931 inc(1, tok);
5932 next();
5933 } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
5934 int qualifiers, cumofs = 0;
5935 /* field */
5936 if (tok == TOK_ARROW)
5937 indir();
5938 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
5939 test_lvalue();
5940 gaddrof();
5941 /* expect pointer on structure */
5942 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
5943 expect("struct or union");
5944 if (tok == TOK_CDOUBLE)
5945 expect("field name");
5946 next();
5947 if (tok == TOK_CINT || tok == TOK_CUINT)
5948 expect("field name");
5949 s = find_field(&vtop->type, tok, &cumofs);
5950 if (!s)
5951 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc));
5952 /* add field offset to pointer */
5953 vtop->type = char_pointer_type; /* change type to 'char *' */
5954 vpushi(cumofs + s->c);
5955 gen_op('+');
5956 /* change type to field type, and set to lvalue */
5957 vtop->type = s->type;
5958 vtop->type.t |= qualifiers;
5959 /* an array is never an lvalue */
5960 if (!(vtop->type.t & VT_ARRAY)) {
5961 vtop->r |= VT_LVAL;
5962 #ifdef CONFIG_TCC_BCHECK
5963 /* if bound checking, the referenced pointer must be checked */
5964 if (tcc_state->do_bounds_check)
5965 vtop->r |= VT_MUSTBOUND;
5966 #endif
5968 next();
5969 } else if (tok == '[') {
5970 next();
5971 gexpr();
5972 gen_op('+');
5973 indir();
5974 skip(']');
5975 } else if (tok == '(') {
5976 SValue ret;
5977 Sym *sa;
5978 int nb_args, ret_nregs, ret_align, regsize, variadic;
5980 /* function call */
5981 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
5982 /* pointer test (no array accepted) */
5983 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
5984 vtop->type = *pointed_type(&vtop->type);
5985 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
5986 goto error_func;
5987 } else {
5988 error_func:
5989 expect("function pointer");
5991 } else {
5992 vtop->r &= ~VT_LVAL; /* no lvalue */
5994 /* get return type */
5995 s = vtop->type.ref;
5996 next();
5997 sa = s->next; /* first parameter */
5998 nb_args = regsize = 0;
5999 ret.r2 = VT_CONST;
6000 /* compute first implicit argument if a structure is returned */
6001 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
6002 variadic = (s->f.func_type == FUNC_ELLIPSIS);
6003 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
6004 &ret_align, &regsize);
6005 if (ret_nregs <= 0) {
6006 /* get some space for the returned structure */
6007 size = type_size(&s->type, &align);
6008 #ifdef TCC_TARGET_ARM64
6009 /* On arm64, a small struct is return in registers.
6010 It is much easier to write it to memory if we know
6011 that we are allowed to write some extra bytes, so
6012 round the allocated space up to a power of 2: */
6013 if (size < 16)
6014 while (size & (size - 1))
6015 size = (size | (size - 1)) + 1;
6016 #endif
6017 loc = (loc - size) & -align;
6018 ret.type = s->type;
6019 ret.r = VT_LOCAL | VT_LVAL;
6020 /* pass it as 'int' to avoid structure arg passing
6021 problems */
6022 vseti(VT_LOCAL, loc);
6023 ret.c = vtop->c;
6024 if (ret_nregs < 0)
6025 vtop--;
6026 else
6027 nb_args++;
6029 } else {
6030 ret_nregs = 1;
6031 ret.type = s->type;
6034 if (ret_nregs > 0) {
6035 /* return in register */
6036 ret.c.i = 0;
6037 PUT_R_RET(&ret, ret.type.t);
6039 if (tok != ')') {
6040 for(;;) {
6041 expr_eq();
6042 gfunc_param_typed(s, sa);
6043 nb_args++;
6044 if (sa)
6045 sa = sa->next;
6046 if (tok == ')')
6047 break;
6048 skip(',');
6051 if (sa)
6052 tcc_error("too few arguments to function");
6053 skip(')');
6054 #ifdef CONFIG_TCC_BCHECK
6055 if (tcc_state->do_bounds_check &&
6056 (nb_args == 1 || nb_args == 2) &&
6057 (vtop[-nb_args].r & VT_SYM) &&
6058 (vtop[-nb_args].sym->v == TOK_setjmp ||
6059 vtop[-nb_args].sym->v == TOK__setjmp
6060 #ifndef TCC_TARGET_PE
6061 || vtop[-nb_args].sym->v == TOK_sigsetjmp
6062 || vtop[-nb_args].sym->v == TOK___sigsetjmp
6063 #endif
6064 )) {
6065 vpush_global_sym(&func_old_type, TOK___bound_setjmp);
6066 vpushv(vtop - nb_args);
6067 if (nb_args == 2)
6068 vpushv(vtop - nb_args);
6069 gfunc_call(nb_args);
6071 #endif
6072 gfunc_call(nb_args);
6074 if (ret_nregs < 0) {
6075 vsetc(&ret.type, ret.r, &ret.c);
6076 #ifdef TCC_TARGET_RISCV64
6077 arch_transfer_ret_regs(1);
6078 #endif
6079 } else {
6080 /* return value */
6081 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
6082 vsetc(&ret.type, r, &ret.c);
6083 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
6086 /* handle packed struct return */
6087 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
6088 int addr, offset;
6090 size = type_size(&s->type, &align);
6091 /* We're writing whole regs often, make sure there's enough
6092 space. Assume register size is power of 2. */
6093 if (regsize > align)
6094 align = regsize;
6095 loc = (loc - size) & -align;
6096 addr = loc;
6097 offset = 0;
6098 for (;;) {
6099 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
6100 vswap();
6101 vstore();
6102 vtop--;
6103 if (--ret_nregs == 0)
6104 break;
6105 offset += regsize;
6107 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
6110 /* Promote char/short return values. This is matters only
6111 for calling function that were not compiled by TCC and
6112 only on some architectures. For those where it doesn't
6113 matter we expect things to be already promoted to int,
6114 but not larger. */
6115 t = s->type.t & VT_BTYPE;
6116 if (t == VT_BYTE || t == VT_SHORT || t == VT_BOOL) {
6117 #ifdef PROMOTE_RET
6118 vtop->r |= BFVAL(VT_MUSTCAST, 1);
6119 #else
6120 vtop->type.t = VT_INT;
6121 #endif
6124 if (s->f.func_noreturn)
6125 CODE_OFF();
6126 } else {
6127 break;
6132 #ifndef precedence_parser /* original top-down parser */
6134 static void expr_prod(void)
6136 int t;
6138 unary();
6139 while ((t = tok) == '*' || t == '/' || t == '%') {
6140 next();
6141 unary();
6142 gen_op(t);
6146 static void expr_sum(void)
6148 int t;
6150 expr_prod();
6151 while ((t = tok) == '+' || t == '-') {
6152 next();
6153 expr_prod();
6154 gen_op(t);
6158 static void expr_shift(void)
6160 int t;
6162 expr_sum();
6163 while ((t = tok) == TOK_SHL || t == TOK_SAR) {
6164 next();
6165 expr_sum();
6166 gen_op(t);
6170 static void expr_cmp(void)
6172 int t;
6174 expr_shift();
6175 while (((t = tok) >= TOK_ULE && t <= TOK_GT) ||
6176 t == TOK_ULT || t == TOK_UGE) {
6177 next();
6178 expr_shift();
6179 gen_op(t);
6183 static void expr_cmpeq(void)
6185 int t;
6187 expr_cmp();
6188 while ((t = tok) == TOK_EQ || t == TOK_NE) {
6189 next();
6190 expr_cmp();
6191 gen_op(t);
6195 static void expr_and(void)
6197 expr_cmpeq();
6198 while (tok == '&') {
6199 next();
6200 expr_cmpeq();
6201 gen_op('&');
6205 static void expr_xor(void)
6207 expr_and();
6208 while (tok == '^') {
6209 next();
6210 expr_and();
6211 gen_op('^');
6215 static void expr_or(void)
6217 expr_xor();
6218 while (tok == '|') {
6219 next();
6220 expr_xor();
6221 gen_op('|');
6225 static void expr_landor(int op);
6227 static void expr_land(void)
6229 expr_or();
6230 if (tok == TOK_LAND)
6231 expr_landor(tok);
6234 static void expr_lor(void)
6236 expr_land();
6237 if (tok == TOK_LOR)
6238 expr_landor(tok);
6241 # define expr_landor_next(op) op == TOK_LAND ? expr_or() : expr_land()
6242 #else /* defined precedence_parser */
6243 # define expr_landor_next(op) unary(), expr_infix(precedence(op) + 1)
6244 # define expr_lor() unary(), expr_infix(1)
6246 static int precedence(int tok)
6248 switch (tok) {
6249 case TOK_LOR: return 1;
6250 case TOK_LAND: return 2;
6251 case '|': return 3;
6252 case '^': return 4;
6253 case '&': return 5;
6254 case TOK_EQ: case TOK_NE: return 6;
6255 relat: case TOK_ULT: case TOK_UGE: return 7;
6256 case TOK_SHL: case TOK_SAR: return 8;
6257 case '+': case '-': return 9;
6258 case '*': case '/': case '%': return 10;
6259 default:
6260 if (tok >= TOK_ULE && tok <= TOK_GT)
6261 goto relat;
6262 return 0;
6265 static unsigned char prec[256];
6266 static void init_prec(void)
6268 int i;
6269 for (i = 0; i < 256; i++)
6270 prec[i] = precedence(i);
6272 #define precedence(i) ((unsigned)i < 256 ? prec[i] : 0)
6274 static void expr_landor(int op);
6276 static void expr_infix(int p)
6278 int t = tok, p2;
6279 while ((p2 = precedence(t)) >= p) {
6280 if (t == TOK_LOR || t == TOK_LAND) {
6281 expr_landor(t);
6282 } else {
6283 next();
6284 unary();
6285 if (precedence(tok) > p2)
6286 expr_infix(p2 + 1);
6287 gen_op(t);
6289 t = tok;
6292 #endif
6294 /* Assuming vtop is a value used in a conditional context
6295 (i.e. compared with zero) return 0 if it's false, 1 if
6296 true and -1 if it can't be statically determined. */
6297 static int condition_3way(void)
6299 int c = -1;
6300 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
6301 (!(vtop->r & VT_SYM) || !vtop->sym->a.weak)) {
6302 vdup();
6303 gen_cast_s(VT_BOOL);
6304 c = vtop->c.i;
6305 vpop();
6307 return c;
6310 static void expr_landor(int op)
6312 int t = 0, cc = 1, f = 0, i = op == TOK_LAND, c;
6313 for(;;) {
6314 c = f ? i : condition_3way();
6315 if (c < 0)
6316 save_regs(1), cc = 0;
6317 else if (c != i)
6318 nocode_wanted++, f = 1;
6319 if (tok != op)
6320 break;
6321 if (c < 0)
6322 t = gvtst(i, t);
6323 else
6324 vpop();
6325 next();
6326 expr_landor_next(op);
6328 if (cc || f) {
6329 vpop();
6330 vpushi(i ^ f);
6331 gsym(t);
6332 nocode_wanted -= f;
6333 } else {
6334 gvtst_set(i, t);
6338 static int is_cond_bool(SValue *sv)
6340 if ((sv->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST
6341 && (sv->type.t & VT_BTYPE) == VT_INT)
6342 return (unsigned)sv->c.i < 2;
6343 if (sv->r == VT_CMP)
6344 return 1;
6345 return 0;
6348 static void expr_cond(void)
6350 int tt, u, r1, r2, rc, t1, t2, islv, c, g;
6351 SValue sv;
6352 CType type;
6353 int ncw_prev;
6355 expr_lor();
6356 if (tok == '?') {
6357 next();
6358 c = condition_3way();
6359 g = (tok == ':' && gnu_ext);
6360 tt = 0;
6361 if (!g) {
6362 if (c < 0) {
6363 save_regs(1);
6364 tt = gvtst(1, 0);
6365 } else {
6366 vpop();
6368 } else if (c < 0) {
6369 /* needed to avoid having different registers saved in
6370 each branch */
6371 save_regs(1);
6372 gv_dup();
6373 tt = gvtst(0, 0);
6376 ncw_prev = nocode_wanted;
6377 if (c == 0)
6378 nocode_wanted++;
6379 if (!g)
6380 gexpr();
6382 if (c < 0 && vtop->r == VT_CMP) {
6383 t1 = gvtst(0, 0);
6384 vpushi(0);
6385 gvtst_set(0, t1);
6386 gv(RC_INT);
6389 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
6390 mk_pointer(&vtop->type);
6391 sv = *vtop; /* save value to handle it later */
6392 vtop--; /* no vpop so that FP stack is not flushed */
6394 if (g) {
6395 u = tt;
6396 } else if (c < 0) {
6397 u = gjmp(0);
6398 gsym(tt);
6399 } else
6400 u = 0;
6402 nocode_wanted = ncw_prev;
6403 if (c == 1)
6404 nocode_wanted++;
6405 skip(':');
6406 expr_cond();
6408 if (c < 0 && is_cond_bool(vtop) && is_cond_bool(&sv)) {
6409 if (sv.r == VT_CMP) {
6410 t1 = sv.jtrue;
6411 t2 = u;
6412 } else {
6413 t1 = gvtst(0, 0);
6414 t2 = gjmp(0);
6415 gsym(u);
6416 vpushv(&sv);
6418 gvtst_set(0, t1);
6419 gvtst_set(1, t2);
6420 nocode_wanted = ncw_prev;
6421 // tcc_warning("two conditions expr_cond");
6422 return;
6425 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
6426 mk_pointer(&vtop->type);
6428 /* cast operands to correct type according to ISOC rules */
6429 if (!combine_types(&type, &sv, vtop, '?'))
6430 type_incompatibility_error(&sv.type, &vtop->type,
6431 "type mismatch in conditional expression (have '%s' and '%s')");
6432 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
6433 that `(expr ? a : b).mem` does not error with "lvalue expected" */
6434 islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
6436 /* now we convert second operand */
6437 if (c != 1) {
6438 gen_cast(&type);
6439 if (islv) {
6440 mk_pointer(&vtop->type);
6441 gaddrof();
6442 } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
6443 gaddrof();
6446 rc = RC_TYPE(type.t);
6447 /* for long longs, we use fixed registers to avoid having
6448 to handle a complicated move */
6449 if (USING_TWO_WORDS(type.t))
6450 rc = RC_RET(type.t);
6452 tt = r2 = 0;
6453 if (c < 0) {
6454 r2 = gv(rc);
6455 tt = gjmp(0);
6457 gsym(u);
6458 nocode_wanted = ncw_prev;
6460 /* this is horrible, but we must also convert first
6461 operand */
6462 if (c != 0) {
6463 *vtop = sv;
6464 gen_cast(&type);
6465 if (islv) {
6466 mk_pointer(&vtop->type);
6467 gaddrof();
6468 } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
6469 gaddrof();
6472 if (c < 0) {
6473 r1 = gv(rc);
6474 move_reg(r2, r1, islv ? VT_PTR : type.t);
6475 vtop->r = r2;
6476 gsym(tt);
6479 if (islv)
6480 indir();
6484 static void expr_eq(void)
6486 int t;
6488 expr_cond();
6489 if ((t = tok) == '=' || TOK_ASSIGN(t)) {
6490 test_lvalue();
6491 next();
6492 if (t == '=') {
6493 expr_eq();
6494 } else {
6495 vdup();
6496 expr_eq();
6497 gen_op(TOK_ASSIGN_OP(t));
6499 vstore();
6503 ST_FUNC void gexpr(void)
6505 while (1) {
6506 expr_eq();
6507 if (tok != ',')
6508 break;
6509 vpop();
6510 next();
6514 /* parse a constant expression and return value in vtop. */
6515 static void expr_const1(void)
6517 const_wanted++;
6518 nocode_wanted += unevalmask + 1;
6519 expr_cond();
6520 nocode_wanted -= unevalmask + 1;
6521 const_wanted--;
6524 /* parse an integer constant and return its value. */
6525 static inline int64_t expr_const64(void)
6527 int64_t c;
6528 expr_const1();
6529 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
6530 expect("constant expression");
6531 c = vtop->c.i;
6532 vpop();
6533 return c;
6536 /* parse an integer constant and return its value.
6537 Complain if it doesn't fit 32bit (signed or unsigned). */
6538 ST_FUNC int expr_const(void)
6540 int c;
6541 int64_t wc = expr_const64();
6542 c = wc;
6543 if (c != wc && (unsigned)c != wc)
6544 tcc_error("constant exceeds 32 bit");
6545 return c;
6548 /* ------------------------------------------------------------------------- */
6549 /* return from function */
6551 #ifndef TCC_TARGET_ARM64
6552 static void gfunc_return(CType *func_type)
6554 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
6555 CType type, ret_type;
6556 int ret_align, ret_nregs, regsize;
6557 ret_nregs = gfunc_sret(func_type, func_var, &ret_type,
6558 &ret_align, &regsize);
6559 if (ret_nregs < 0) {
6560 #ifdef TCC_TARGET_RISCV64
6561 arch_transfer_ret_regs(0);
6562 #endif
6563 } else if (0 == ret_nregs) {
6564 /* if returning structure, must copy it to implicit
6565 first pointer arg location */
6566 type = *func_type;
6567 mk_pointer(&type);
6568 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
6569 indir();
6570 vswap();
6571 /* copy structure value to pointer */
6572 vstore();
6573 } else {
6574 /* returning structure packed into registers */
6575 int size, addr, align, rc;
6576 size = type_size(func_type,&align);
6577 if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
6578 (vtop->c.i & (ret_align-1)))
6579 && (align & (ret_align-1))) {
6580 loc = (loc - size) & -ret_align;
6581 addr = loc;
6582 type = *func_type;
6583 vset(&type, VT_LOCAL | VT_LVAL, addr);
6584 vswap();
6585 vstore();
6586 vpop();
6587 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
6589 vtop->type = ret_type;
6590 rc = RC_RET(ret_type.t);
6591 if (ret_nregs == 1)
6592 gv(rc);
6593 else {
6594 for (;;) {
6595 vdup();
6596 gv(rc);
6597 vpop();
6598 if (--ret_nregs == 0)
6599 break;
6600 /* We assume that when a structure is returned in multiple
6601 registers, their classes are consecutive values of the
6602 suite s(n) = 2^n */
6603 rc <<= 1;
6604 vtop->c.i += regsize;
6608 } else {
6609 gv(RC_RET(func_type->t));
6611 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
6613 #endif
6615 static void check_func_return(void)
6617 if ((func_vt.t & VT_BTYPE) == VT_VOID)
6618 return;
6619 if (!strcmp (funcname, "main")
6620 && (func_vt.t & VT_BTYPE) == VT_INT) {
6621 /* main returns 0 by default */
6622 vpushi(0);
6623 gen_assign_cast(&func_vt);
6624 gfunc_return(&func_vt);
6625 } else {
6626 tcc_warning("function might return no value: '%s'", funcname);
6630 /* ------------------------------------------------------------------------- */
6631 /* switch/case */
6633 static int case_cmp(const void *pa, const void *pb)
6635 int64_t a = (*(struct case_t**) pa)->v1;
6636 int64_t b = (*(struct case_t**) pb)->v1;
6637 return a < b ? -1 : a > b;
6640 static void gtst_addr(int t, int a)
6642 gsym_addr(gvtst(0, t), a);
6645 static void gcase(struct case_t **base, int len, int *bsym)
6647 struct case_t *p;
6648 int e;
6649 int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG;
6650 while (len > 8) {
6651 /* binary search */
6652 p = base[len/2];
6653 vdup();
6654 if (ll)
6655 vpushll(p->v2);
6656 else
6657 vpushi(p->v2);
6658 gen_op(TOK_LE);
6659 e = gvtst(1, 0);
6660 vdup();
6661 if (ll)
6662 vpushll(p->v1);
6663 else
6664 vpushi(p->v1);
6665 gen_op(TOK_GE);
6666 gtst_addr(0, p->sym); /* v1 <= x <= v2 */
6667 /* x < v1 */
6668 gcase(base, len/2, bsym);
6669 /* x > v2 */
6670 gsym(e);
6671 e = len/2 + 1;
6672 base += e; len -= e;
6674 /* linear scan */
6675 while (len--) {
6676 p = *base++;
6677 vdup();
6678 if (ll)
6679 vpushll(p->v2);
6680 else
6681 vpushi(p->v2);
6682 if (p->v1 == p->v2) {
6683 gen_op(TOK_EQ);
6684 gtst_addr(0, p->sym);
6685 } else {
6686 gen_op(TOK_LE);
6687 e = gvtst(1, 0);
6688 vdup();
6689 if (ll)
6690 vpushll(p->v1);
6691 else
6692 vpushi(p->v1);
6693 gen_op(TOK_GE);
6694 gtst_addr(0, p->sym);
6695 gsym(e);
6698 *bsym = gjmp(*bsym);
6701 /* ------------------------------------------------------------------------- */
6702 /* __attribute__((cleanup(fn))) */
6704 static void try_call_scope_cleanup(Sym *stop)
6706 Sym *cls = cur_scope->cl.s;
6708 for (; cls != stop; cls = cls->ncl) {
6709 Sym *fs = cls->next;
6710 Sym *vs = cls->prev_tok;
6712 vpushsym(&fs->type, fs);
6713 vset(&vs->type, vs->r, vs->c);
6714 vtop->sym = vs;
6715 mk_pointer(&vtop->type);
6716 gaddrof();
6717 gfunc_call(1);
6721 static void try_call_cleanup_goto(Sym *cleanupstate)
6723 Sym *oc, *cc;
6724 int ocd, ccd;
6726 if (!cur_scope->cl.s)
6727 return;
6729 /* search NCA of both cleanup chains given parents and initial depth */
6730 ocd = cleanupstate ? cleanupstate->v & ~SYM_FIELD : 0;
6731 for (ccd = cur_scope->cl.n, oc = cleanupstate; ocd > ccd; --ocd, oc = oc->ncl)
6733 for (cc = cur_scope->cl.s; ccd > ocd; --ccd, cc = cc->ncl)
6735 for (; cc != oc; cc = cc->ncl, oc = oc->ncl, --ccd)
6738 try_call_scope_cleanup(cc);
6741 /* call 'func' for each __attribute__((cleanup(func))) */
6742 static void block_cleanup(struct scope *o)
6744 int jmp = 0;
6745 Sym *g, **pg;
6746 for (pg = &pending_gotos; (g = *pg) && g->c > o->cl.n;) {
6747 if (g->prev_tok->r & LABEL_FORWARD) {
6748 Sym *pcl = g->next;
6749 if (!jmp)
6750 jmp = gjmp(0);
6751 gsym(pcl->jnext);
6752 try_call_scope_cleanup(o->cl.s);
6753 pcl->jnext = gjmp(0);
6754 if (!o->cl.n)
6755 goto remove_pending;
6756 g->c = o->cl.n;
6757 pg = &g->prev;
6758 } else {
6759 remove_pending:
6760 *pg = g->prev;
6761 sym_free(g);
6764 gsym(jmp);
6765 try_call_scope_cleanup(o->cl.s);
6768 /* ------------------------------------------------------------------------- */
6769 /* VLA */
6771 static void vla_restore(int loc)
6773 if (loc)
6774 gen_vla_sp_restore(loc);
6777 static void vla_leave(struct scope *o)
6779 if (o->vla.num < cur_scope->vla.num)
6780 vla_restore(o->vla.loc);
6783 /* ------------------------------------------------------------------------- */
6784 /* local scopes */
6786 void new_scope(struct scope *o)
6788 /* copy and link previous scope */
6789 *o = *cur_scope;
6790 o->prev = cur_scope;
6791 cur_scope = o;
6793 /* record local declaration stack position */
6794 o->lstk = local_stack;
6795 o->llstk = local_label_stack;
6797 ++local_scope;
6799 if (tcc_state->do_debug)
6800 tcc_debug_stabn(N_LBRAC, ind - func_ind);
6803 void prev_scope(struct scope *o, int is_expr)
6805 vla_leave(o->prev);
6807 if (o->cl.s != o->prev->cl.s)
6808 block_cleanup(o->prev);
6810 /* pop locally defined labels */
6811 label_pop(&local_label_stack, o->llstk, is_expr);
6813 /* In the is_expr case (a statement expression is finished here),
6814 vtop might refer to symbols on the local_stack. Either via the
6815 type or via vtop->sym. We can't pop those nor any that in turn
6816 might be referred to. To make it easier we don't roll back
6817 any symbols in that case; some upper level call to block() will
6818 do that. We do have to remove such symbols from the lookup
6819 tables, though. sym_pop will do that. */
6821 /* pop locally defined symbols */
6822 pop_local_syms(&local_stack, o->lstk, is_expr, 0);
6823 cur_scope = o->prev;
6824 --local_scope;
6826 if (tcc_state->do_debug)
6827 tcc_debug_stabn(N_RBRAC, ind - func_ind);
6830 /* leave a scope via break/continue(/goto) */
6831 void leave_scope(struct scope *o)
6833 if (!o)
6834 return;
6835 try_call_scope_cleanup(o->cl.s);
6836 vla_leave(o);
6839 /* ------------------------------------------------------------------------- */
6840 /* call block from 'for do while' loops */
6842 static void lblock(int *bsym, int *csym)
6844 struct scope *lo = loop_scope, *co = cur_scope;
6845 int *b = co->bsym, *c = co->csym;
6846 if (csym) {
6847 co->csym = csym;
6848 loop_scope = co;
6850 co->bsym = bsym;
6851 block(0);
6852 co->bsym = b;
6853 if (csym) {
6854 co->csym = c;
6855 loop_scope = lo;
6859 static void block(int is_expr)
6861 int a, b, c, d, e, t;
6862 struct scope o;
6863 Sym *s;
6865 if (is_expr) {
6866 /* default return value is (void) */
6867 vpushi(0);
6868 vtop->type.t = VT_VOID;
6871 again:
6872 t = tok, next();
6874 if (t == TOK_IF) {
6875 skip('(');
6876 gexpr();
6877 skip(')');
6878 a = gvtst(1, 0);
6879 block(0);
6880 if (tok == TOK_ELSE) {
6881 d = gjmp(0);
6882 gsym(a);
6883 next();
6884 block(0);
6885 gsym(d); /* patch else jmp */
6886 } else {
6887 gsym(a);
6890 } else if (t == TOK_WHILE) {
6891 d = gind();
6892 skip('(');
6893 gexpr();
6894 skip(')');
6895 a = gvtst(1, 0);
6896 b = 0;
6897 lblock(&a, &b);
6898 gjmp_addr(d);
6899 gsym_addr(b, d);
6900 gsym(a);
6902 } else if (t == '{') {
6903 new_scope(&o);
6905 /* handle local labels declarations */
6906 while (tok == TOK_LABEL) {
6907 do {
6908 next();
6909 if (tok < TOK_UIDENT)
6910 expect("label identifier");
6911 label_push(&local_label_stack, tok, LABEL_DECLARED);
6912 next();
6913 } while (tok == ',');
6914 skip(';');
6917 while (tok != '}') {
6918 decl(VT_LOCAL);
6919 if (tok != '}') {
6920 if (is_expr)
6921 vpop();
6922 block(is_expr);
6926 prev_scope(&o, is_expr);
6927 if (local_scope)
6928 next();
6929 else if (!nocode_wanted)
6930 check_func_return();
6932 } else if (t == TOK_RETURN) {
6933 b = (func_vt.t & VT_BTYPE) != VT_VOID;
6934 if (tok != ';') {
6935 gexpr();
6936 if (b) {
6937 gen_assign_cast(&func_vt);
6938 } else {
6939 if (vtop->type.t != VT_VOID)
6940 tcc_warning("void function returns a value");
6941 vtop--;
6943 } else if (b) {
6944 tcc_warning("'return' with no value");
6945 b = 0;
6947 leave_scope(root_scope);
6948 if (b)
6949 gfunc_return(&func_vt);
6950 skip(';');
6951 /* jump unless last stmt in top-level block */
6952 if (tok != '}' || local_scope != 1)
6953 rsym = gjmp(rsym);
6954 CODE_OFF();
6956 } else if (t == TOK_BREAK) {
6957 /* compute jump */
6958 if (!cur_scope->bsym)
6959 tcc_error("cannot break");
6960 if (cur_switch && cur_scope->bsym == cur_switch->bsym)
6961 leave_scope(cur_switch->scope);
6962 else
6963 leave_scope(loop_scope);
6964 *cur_scope->bsym = gjmp(*cur_scope->bsym);
6965 skip(';');
6967 } else if (t == TOK_CONTINUE) {
6968 /* compute jump */
6969 if (!cur_scope->csym)
6970 tcc_error("cannot continue");
6971 leave_scope(loop_scope);
6972 *cur_scope->csym = gjmp(*cur_scope->csym);
6973 skip(';');
6975 } else if (t == TOK_FOR) {
6976 new_scope(&o);
6978 skip('(');
6979 if (tok != ';') {
6980 /* c99 for-loop init decl? */
6981 if (!decl0(VT_LOCAL, 1, NULL)) {
6982 /* no, regular for-loop init expr */
6983 gexpr();
6984 vpop();
6987 skip(';');
6988 a = b = 0;
6989 c = d = gind();
6990 if (tok != ';') {
6991 gexpr();
6992 a = gvtst(1, 0);
6994 skip(';');
6995 if (tok != ')') {
6996 e = gjmp(0);
6997 d = gind();
6998 gexpr();
6999 vpop();
7000 gjmp_addr(c);
7001 gsym(e);
7003 skip(')');
7004 lblock(&a, &b);
7005 gjmp_addr(d);
7006 gsym_addr(b, d);
7007 gsym(a);
7008 prev_scope(&o, 0);
7010 } else if (t == TOK_DO) {
7011 a = b = 0;
7012 d = gind();
7013 lblock(&a, &b);
7014 gsym(b);
7015 skip(TOK_WHILE);
7016 skip('(');
7017 gexpr();
7018 skip(')');
7019 skip(';');
7020 c = gvtst(0, 0);
7021 gsym_addr(c, d);
7022 gsym(a);
7024 } else if (t == TOK_SWITCH) {
7025 struct switch_t *sw;
7027 sw = tcc_mallocz(sizeof *sw);
7028 sw->bsym = &a;
7029 sw->scope = cur_scope;
7030 sw->prev = cur_switch;
7031 cur_switch = sw;
7033 skip('(');
7034 gexpr();
7035 skip(')');
7036 sw->sv = *vtop--; /* save switch value */
7038 a = 0;
7039 b = gjmp(0); /* jump to first case */
7040 lblock(&a, NULL);
7041 a = gjmp(a); /* add implicit break */
7042 /* case lookup */
7043 gsym(b);
7045 qsort(sw->p, sw->n, sizeof(void*), case_cmp);
7046 for (b = 1; b < sw->n; b++)
7047 if (sw->p[b - 1]->v2 >= sw->p[b]->v1)
7048 tcc_error("duplicate case value");
7050 /* Our switch table sorting is signed, so the compared
7051 value needs to be as well when it's 64bit. */
7052 vpushv(&sw->sv);
7053 if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
7054 vtop->type.t &= ~VT_UNSIGNED;
7055 gv(RC_INT);
7056 d = 0, gcase(sw->p, sw->n, &d);
7057 vpop();
7058 if (sw->def_sym)
7059 gsym_addr(d, sw->def_sym);
7060 else
7061 gsym(d);
7062 /* break label */
7063 gsym(a);
7065 dynarray_reset(&sw->p, &sw->n);
7066 cur_switch = sw->prev;
7067 tcc_free(sw);
7069 } else if (t == TOK_CASE) {
7070 struct case_t *cr = tcc_malloc(sizeof(struct case_t));
7071 if (!cur_switch)
7072 expect("switch");
7073 cr->v1 = cr->v2 = expr_const64();
7074 if (gnu_ext && tok == TOK_DOTS) {
7075 next();
7076 cr->v2 = expr_const64();
7077 if (cr->v2 < cr->v1)
7078 tcc_warning("empty case range");
7080 cr->sym = gind();
7081 dynarray_add(&cur_switch->p, &cur_switch->n, cr);
7082 skip(':');
7083 is_expr = 0;
7084 goto block_after_label;
7086 } else if (t == TOK_DEFAULT) {
7087 if (!cur_switch)
7088 expect("switch");
7089 if (cur_switch->def_sym)
7090 tcc_error("too many 'default'");
7091 cur_switch->def_sym = gind();
7092 skip(':');
7093 is_expr = 0;
7094 goto block_after_label;
7096 } else if (t == TOK_GOTO) {
7097 vla_restore(root_scope->vla.loc);
7098 if (tok == '*' && gnu_ext) {
7099 /* computed goto */
7100 next();
7101 gexpr();
7102 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
7103 expect("pointer");
7104 ggoto();
7106 } else if (tok >= TOK_UIDENT) {
7107 s = label_find(tok);
7108 /* put forward definition if needed */
7109 if (!s)
7110 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
7111 else if (s->r == LABEL_DECLARED)
7112 s->r = LABEL_FORWARD;
7114 if (s->r & LABEL_FORWARD) {
7115 /* start new goto chain for cleanups, linked via label->next */
7116 if (cur_scope->cl.s && !nocode_wanted) {
7117 sym_push2(&pending_gotos, SYM_FIELD, 0, cur_scope->cl.n);
7118 pending_gotos->prev_tok = s;
7119 s = sym_push2(&s->next, SYM_FIELD, 0, 0);
7120 pending_gotos->next = s;
7122 s->jnext = gjmp(s->jnext);
7123 } else {
7124 try_call_cleanup_goto(s->cleanupstate);
7125 gjmp_addr(s->jnext);
7127 next();
7129 } else {
7130 expect("label identifier");
7132 skip(';');
7134 } else if (t == TOK_ASM1 || t == TOK_ASM2 || t == TOK_ASM3) {
7135 asm_instr();
7137 } else {
7138 if (tok == ':' && t >= TOK_UIDENT) {
7139 /* label case */
7140 next();
7141 s = label_find(t);
7142 if (s) {
7143 if (s->r == LABEL_DEFINED)
7144 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
7145 s->r = LABEL_DEFINED;
7146 if (s->next) {
7147 Sym *pcl; /* pending cleanup goto */
7148 for (pcl = s->next; pcl; pcl = pcl->prev)
7149 gsym(pcl->jnext);
7150 sym_pop(&s->next, NULL, 0);
7151 } else
7152 gsym(s->jnext);
7153 } else {
7154 s = label_push(&global_label_stack, t, LABEL_DEFINED);
7156 s->jnext = gind();
7157 s->cleanupstate = cur_scope->cl.s;
7159 block_after_label:
7160 vla_restore(cur_scope->vla.loc);
7161 /* we accept this, but it is a mistake */
7162 if (tok == '}') {
7163 tcc_warning("deprecated use of label at end of compound statement");
7164 } else {
7165 goto again;
7168 } else {
7169 /* expression case */
7170 if (t != ';') {
7171 unget_tok(t);
7172 if (is_expr) {
7173 vpop();
7174 gexpr();
7175 } else {
7176 gexpr();
7177 vpop();
7179 skip(';');
7185 /* This skips over a stream of tokens containing balanced {} and ()
7186 pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started
7187 with a '{'). If STR then allocates and stores the skipped tokens
7188 in *STR. This doesn't check if () and {} are nested correctly,
7189 i.e. "({)}" is accepted. */
7190 static void skip_or_save_block(TokenString **str)
7192 int braces = tok == '{';
7193 int level = 0;
7194 if (str)
7195 *str = tok_str_alloc();
7197 while ((level > 0 || (tok != '}' && tok != ',' && tok != ';' && tok != ')'))) {
7198 int t;
7199 if (tok == TOK_EOF) {
7200 if (str || level > 0)
7201 tcc_error("unexpected end of file");
7202 else
7203 break;
7205 if (str)
7206 tok_str_add_tok(*str);
7207 t = tok;
7208 next();
7209 if (t == '{' || t == '(') {
7210 level++;
7211 } else if (t == '}' || t == ')') {
7212 level--;
7213 if (level == 0 && braces && t == '}')
7214 break;
7217 if (str) {
7218 tok_str_add(*str, -1);
7219 tok_str_add(*str, 0);
7223 #define EXPR_CONST 1
7224 #define EXPR_ANY 2
7226 static void parse_init_elem(int expr_type)
7228 int saved_global_expr;
7229 switch(expr_type) {
7230 case EXPR_CONST:
7231 /* compound literals must be allocated globally in this case */
7232 saved_global_expr = global_expr;
7233 global_expr = 1;
7234 expr_const1();
7235 global_expr = saved_global_expr;
7236 /* NOTE: symbols are accepted, as well as lvalue for anon symbols
7237 (compound literals). */
7238 if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST
7239 && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL)
7240 || vtop->sym->v < SYM_FIRST_ANOM))
7241 #ifdef TCC_TARGET_PE
7242 || ((vtop->r & VT_SYM) && vtop->sym->a.dllimport)
7243 #endif
7245 tcc_error("initializer element is not constant");
7246 break;
7247 case EXPR_ANY:
7248 expr_eq();
7249 break;
7253 /* put zeros for variable based init */
7254 static void init_putz(Section *sec, unsigned long c, int size)
7256 if (sec) {
7257 /* nothing to do because globals are already set to zero */
7258 } else {
7259 vpush_global_sym(&func_old_type, TOK_memset);
7260 vseti(VT_LOCAL, c);
7261 #ifdef TCC_TARGET_ARM
7262 vpushs(size);
7263 vpushi(0);
7264 #else
7265 vpushi(0);
7266 vpushs(size);
7267 #endif
7268 gfunc_call(3);
7272 #define DIF_FIRST 1
7273 #define DIF_SIZE_ONLY 2
7274 #define DIF_HAVE_ELEM 4
7276 /* t is the array or struct type. c is the array or struct
7277 address. cur_field is the pointer to the current
7278 field, for arrays the 'c' member contains the current start
7279 index. 'flags' is as in decl_initializer.
7280 'al' contains the already initialized length of the
7281 current container (starting at c). This returns the new length of that. */
7282 static int decl_designator(CType *type, Section *sec, unsigned long c,
7283 Sym **cur_field, int flags, int al)
7285 Sym *s, *f;
7286 int index, index_last, align, l, nb_elems, elem_size;
7287 unsigned long corig = c;
7289 elem_size = 0;
7290 nb_elems = 1;
7292 if (flags & DIF_HAVE_ELEM)
7293 goto no_designator;
7295 if (gnu_ext && tok >= TOK_UIDENT) {
7296 l = tok, next();
7297 if (tok == ':')
7298 goto struct_field;
7299 unget_tok(l);
7302 /* NOTE: we only support ranges for last designator */
7303 while (nb_elems == 1 && (tok == '[' || tok == '.')) {
7304 if (tok == '[') {
7305 if (!(type->t & VT_ARRAY))
7306 expect("array type");
7307 next();
7308 index = index_last = expr_const();
7309 if (tok == TOK_DOTS && gnu_ext) {
7310 next();
7311 index_last = expr_const();
7313 skip(']');
7314 s = type->ref;
7315 if (index < 0 || (s->c >= 0 && index_last >= s->c) ||
7316 index_last < index)
7317 tcc_error("invalid index");
7318 if (cur_field)
7319 (*cur_field)->c = index_last;
7320 type = pointed_type(type);
7321 elem_size = type_size(type, &align);
7322 c += index * elem_size;
7323 nb_elems = index_last - index + 1;
7324 } else {
7325 int cumofs;
7326 next();
7327 l = tok;
7328 struct_field:
7329 next();
7330 if ((type->t & VT_BTYPE) != VT_STRUCT)
7331 expect("struct/union type");
7332 cumofs = 0;
7333 f = find_field(type, l, &cumofs);
7334 if (!f)
7335 expect("field");
7336 if (cur_field)
7337 *cur_field = f;
7338 type = &f->type;
7339 c += cumofs + f->c;
7341 cur_field = NULL;
7343 if (!cur_field) {
7344 if (tok == '=') {
7345 next();
7346 } else if (!gnu_ext) {
7347 expect("=");
7349 } else {
7350 no_designator:
7351 if (type->t & VT_ARRAY) {
7352 index = (*cur_field)->c;
7353 if (type->ref->c >= 0 && index >= type->ref->c)
7354 tcc_error("index too large");
7355 type = pointed_type(type);
7356 c += index * type_size(type, &align);
7357 } else {
7358 f = *cur_field;
7359 while (f && (f->v & SYM_FIRST_ANOM) && (f->type.t & VT_BITFIELD))
7360 *cur_field = f = f->next;
7361 if (!f)
7362 tcc_error("too many field init");
7363 type = &f->type;
7364 c += f->c;
7367 /* must put zero in holes (note that doing it that way
7368 ensures that it even works with designators) */
7369 if (!(flags & DIF_SIZE_ONLY) && c - corig > al)
7370 init_putz(sec, corig + al, c - corig - al);
7371 decl_initializer(type, sec, c, flags & ~DIF_FIRST);
7373 /* XXX: make it more general */
7374 if (!(flags & DIF_SIZE_ONLY) && nb_elems > 1) {
7375 unsigned long c_end;
7376 uint8_t *src, *dst;
7377 int i;
7379 if (!sec) {
7380 vset(type, VT_LOCAL|VT_LVAL, c);
7381 for (i = 1; i < nb_elems; i++) {
7382 vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i);
7383 vswap();
7384 vstore();
7386 vpop();
7387 } else if (!NODATA_WANTED) {
7388 c_end = c + nb_elems * elem_size;
7389 if (c_end > sec->data_allocated)
7390 section_realloc(sec, c_end);
7391 src = sec->data + c;
7392 dst = src;
7393 for(i = 1; i < nb_elems; i++) {
7394 dst += elem_size;
7395 memcpy(dst, src, elem_size);
7399 c += nb_elems * type_size(type, &align);
7400 if (c - corig > al)
7401 al = c - corig;
7402 return al;
7405 /* store a value or an expression directly in global data or in local array */
7406 static void init_putv(CType *type, Section *sec, unsigned long c)
7408 int bt;
7409 void *ptr;
7410 CType dtype;
7412 dtype = *type;
7413 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
7415 if (sec) {
7416 int size, align;
7417 /* XXX: not portable */
7418 /* XXX: generate error if incorrect relocation */
7419 gen_assign_cast(&dtype);
7420 bt = type->t & VT_BTYPE;
7422 if ((vtop->r & VT_SYM)
7423 && bt != VT_PTR
7424 && bt != VT_FUNC
7425 && (bt != (PTR_SIZE == 8 ? VT_LLONG : VT_INT)
7426 || (type->t & VT_BITFIELD))
7427 && !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM)
7429 tcc_error("initializer element is not computable at load time");
7431 if (NODATA_WANTED) {
7432 vtop--;
7433 return;
7436 size = type_size(type, &align);
7437 section_reserve(sec, c + size);
7438 ptr = sec->data + c;
7440 /* XXX: make code faster ? */
7441 if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) &&
7442 vtop->sym->v >= SYM_FIRST_ANOM &&
7443 /* XXX This rejects compound literals like
7444 '(void *){ptr}'. The problem is that '&sym' is
7445 represented the same way, which would be ruled out
7446 by the SYM_FIRST_ANOM check above, but also '"string"'
7447 in 'char *p = "string"' is represented the same
7448 with the type being VT_PTR and the symbol being an
7449 anonymous one. That is, there's no difference in vtop
7450 between '(void *){x}' and '&(void *){x}'. Ignore
7451 pointer typed entities here. Hopefully no real code
7452 will ever use compound literals with scalar type. */
7453 (vtop->type.t & VT_BTYPE) != VT_PTR) {
7454 /* These come from compound literals, memcpy stuff over. */
7455 Section *ssec;
7456 ElfSym *esym;
7457 ElfW_Rel *rel;
7458 esym = elfsym(vtop->sym);
7459 ssec = tcc_state->sections[esym->st_shndx];
7460 memmove (ptr, ssec->data + esym->st_value + (int)vtop->c.i, size);
7461 if (ssec->reloc) {
7462 /* We need to copy over all memory contents, and that
7463 includes relocations. Use the fact that relocs are
7464 created it order, so look from the end of relocs
7465 until we hit one before the copied region. */
7466 int num_relocs = ssec->reloc->data_offset / sizeof(*rel);
7467 rel = (ElfW_Rel*)(ssec->reloc->data + ssec->reloc->data_offset);
7468 while (num_relocs--) {
7469 rel--;
7470 if (rel->r_offset >= esym->st_value + size)
7471 continue;
7472 if (rel->r_offset < esym->st_value)
7473 break;
7474 /* Note: if the same fields are initialized multiple
7475 times (possible with designators) then we possibly
7476 add multiple relocations for the same offset here.
7477 That would lead to wrong code, the last reloc needs
7478 to win. We clean this up later after the whole
7479 initializer is parsed. */
7480 put_elf_reloca(symtab_section, sec,
7481 c + rel->r_offset - esym->st_value,
7482 ELFW(R_TYPE)(rel->r_info),
7483 ELFW(R_SYM)(rel->r_info),
7484 #if PTR_SIZE == 8
7485 rel->r_addend
7486 #else
7488 #endif
7492 } else {
7493 if (type->t & VT_BITFIELD) {
7494 int bit_pos, bit_size, bits, n;
7495 unsigned char *p, v, m;
7496 bit_pos = BIT_POS(vtop->type.t);
7497 bit_size = BIT_SIZE(vtop->type.t);
7498 p = (unsigned char*)ptr + (bit_pos >> 3);
7499 bit_pos &= 7, bits = 0;
7500 while (bit_size) {
7501 n = 8 - bit_pos;
7502 if (n > bit_size)
7503 n = bit_size;
7504 v = vtop->c.i >> bits << bit_pos;
7505 m = ((1 << n) - 1) << bit_pos;
7506 *p = (*p & ~m) | (v & m);
7507 bits += n, bit_size -= n, bit_pos = 0, ++p;
7509 } else
7510 switch(bt) {
7511 /* XXX: when cross-compiling we assume that each type has the
7512 same representation on host and target, which is likely to
7513 be wrong in the case of long double */
7514 case VT_BOOL:
7515 vtop->c.i = vtop->c.i != 0;
7516 case VT_BYTE:
7517 *(char *)ptr |= vtop->c.i;
7518 break;
7519 case VT_SHORT:
7520 *(short *)ptr |= vtop->c.i;
7521 break;
7522 case VT_FLOAT:
7523 *(float*)ptr = vtop->c.f;
7524 break;
7525 case VT_DOUBLE:
7526 *(double *)ptr = vtop->c.d;
7527 break;
7528 case VT_LDOUBLE:
7529 #if defined TCC_IS_NATIVE_387
7530 if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
7531 memcpy(ptr, &vtop->c.ld, 10);
7532 #ifdef __TINYC__
7533 else if (sizeof (long double) == sizeof (double))
7534 __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld));
7535 #endif
7536 else if (vtop->c.ld == 0.0)
7538 else
7539 #endif
7540 if (sizeof(long double) == LDOUBLE_SIZE)
7541 *(long double*)ptr = vtop->c.ld;
7542 else if (sizeof(double) == LDOUBLE_SIZE)
7543 *(double *)ptr = (double)vtop->c.ld;
7544 else
7545 tcc_error("can't cross compile long double constants");
7546 break;
7547 #if PTR_SIZE != 8
7548 case VT_LLONG:
7549 *(long long *)ptr |= vtop->c.i;
7550 break;
7551 #else
7552 case VT_LLONG:
7553 #endif
7554 case VT_PTR:
7556 addr_t val = vtop->c.i;
7557 #if PTR_SIZE == 8
7558 if (vtop->r & VT_SYM)
7559 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
7560 else
7561 *(addr_t *)ptr |= val;
7562 #else
7563 if (vtop->r & VT_SYM)
7564 greloc(sec, vtop->sym, c, R_DATA_PTR);
7565 *(addr_t *)ptr |= val;
7566 #endif
7567 break;
7569 default:
7571 int val = vtop->c.i;
7572 #if PTR_SIZE == 8
7573 if (vtop->r & VT_SYM)
7574 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
7575 else
7576 *(int *)ptr |= val;
7577 #else
7578 if (vtop->r & VT_SYM)
7579 greloc(sec, vtop->sym, c, R_DATA_PTR);
7580 *(int *)ptr |= val;
7581 #endif
7582 break;
7586 vtop--;
7587 } else {
7588 vset(&dtype, VT_LOCAL|VT_LVAL, c);
7589 vswap();
7590 vstore();
7591 vpop();
7595 /* 't' contains the type and storage info. 'c' is the offset of the
7596 object in section 'sec'. If 'sec' is NULL, it means stack based
7597 allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi
7598 dimension implicit array init handling). 'flags & DIF_SIZE_ONLY' is true if
7599 size only evaluation is wanted (only for arrays). */
7600 static void decl_initializer(CType *type, Section *sec, unsigned long c,
7601 int flags)
7603 int len, n, no_oblock, i;
7604 int size1, align1;
7605 Sym *s, *f;
7606 Sym indexsym;
7607 CType *t1;
7609 if (!(flags & DIF_HAVE_ELEM) && tok != '{' &&
7610 /* In case of strings we have special handling for arrays, so
7611 don't consume them as initializer value (which would commit them
7612 to some anonymous symbol). */
7613 tok != TOK_LSTR && tok != TOK_STR &&
7614 !(flags & DIF_SIZE_ONLY)) {
7615 parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
7616 flags |= DIF_HAVE_ELEM;
7619 if ((flags & DIF_HAVE_ELEM) &&
7620 !(type->t & VT_ARRAY) &&
7621 /* Use i_c_parameter_t, to strip toplevel qualifiers.
7622 The source type might have VT_CONSTANT set, which is
7623 of course assignable to non-const elements. */
7624 is_compatible_unqualified_types(type, &vtop->type)) {
7625 init_putv(type, sec, c);
7626 } else if (type->t & VT_ARRAY) {
7627 s = type->ref;
7628 n = s->c;
7629 t1 = pointed_type(type);
7630 size1 = type_size(t1, &align1);
7632 no_oblock = 1;
7633 if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) ||
7634 tok == '{') {
7635 if (tok != '{')
7636 tcc_error("character array initializer must be a literal,"
7637 " optionally enclosed in braces");
7638 skip('{');
7639 no_oblock = 0;
7642 /* only parse strings here if correct type (otherwise: handle
7643 them as ((w)char *) expressions */
7644 if ((tok == TOK_LSTR &&
7645 #ifdef TCC_TARGET_PE
7646 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
7647 #else
7648 (t1->t & VT_BTYPE) == VT_INT
7649 #endif
7650 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
7651 int nb;
7652 len = 0;
7653 cstr_reset(&initstr);
7654 if (size1 != (tok == TOK_STR ? 1 : sizeof(nwchar_t)))
7655 tcc_error("unhandled string literal merging");
7656 while (tok == TOK_STR || tok == TOK_LSTR) {
7657 if (initstr.size)
7658 initstr.size -= size1;
7659 if (tok == TOK_STR)
7660 len += tokc.str.size;
7661 else
7662 len += tokc.str.size / sizeof(nwchar_t);
7663 len--;
7664 cstr_cat(&initstr, tokc.str.data, tokc.str.size);
7665 next();
7667 if (tok != ')' && tok != '}' && tok != ',' && tok != ';'
7668 && tok != TOK_EOF) {
7669 /* Not a lone literal but part of a bigger expression. */
7670 unget_tok(size1 == 1 ? TOK_STR : TOK_LSTR);
7671 tokc.str.size = initstr.size;
7672 tokc.str.data = initstr.data;
7673 indexsym.c = 0;
7674 f = &indexsym;
7675 goto do_init_list;
7677 nb = len;
7678 if (n >= 0 && len > n)
7679 nb = n;
7680 if (!(flags & DIF_SIZE_ONLY)) {
7681 if (len > nb)
7682 tcc_warning("initializer-string for array is too long");
7683 /* in order to go faster for common case (char
7684 string in global variable, we handle it
7685 specifically */
7686 if (sec && size1 == 1) {
7687 if (!NODATA_WANTED)
7688 memcpy(sec->data + c, initstr.data, nb);
7689 } else {
7690 for(i=0;i<nb;i++) {
7691 if (size1 == 1)
7692 ch = ((unsigned char *)initstr.data)[i];
7693 else
7694 ch = ((nwchar_t *)initstr.data)[i];
7695 vpushi(ch);
7696 init_putv(t1, sec, c + i * size1);
7700 /* only add trailing zero if enough storage (no
7701 warning in this case since it is standard) */
7702 if (n < 0 || len < n) {
7703 if (!(flags & DIF_SIZE_ONLY)) {
7704 vpushi(0);
7705 init_putv(t1, sec, c + (len * size1));
7707 len++;
7709 len *= size1;
7710 } else {
7711 indexsym.c = 0;
7712 f = &indexsym;
7714 do_init_list:
7715 len = 0;
7716 while (tok != '}' || (flags & DIF_HAVE_ELEM)) {
7717 len = decl_designator(type, sec, c, &f, flags, len);
7718 flags &= ~DIF_HAVE_ELEM;
7719 if (type->t & VT_ARRAY) {
7720 ++indexsym.c;
7721 /* special test for multi dimensional arrays (may not
7722 be strictly correct if designators are used at the
7723 same time) */
7724 if (no_oblock && len >= n*size1)
7725 break;
7726 } else {
7727 if (s->type.t == VT_UNION)
7728 f = NULL;
7729 else
7730 f = f->next;
7731 if (no_oblock && f == NULL)
7732 break;
7735 if (tok == '}')
7736 break;
7737 skip(',');
7740 /* put zeros at the end */
7741 if (!(flags & DIF_SIZE_ONLY) && len < n*size1)
7742 init_putz(sec, c + len, n*size1 - len);
7743 if (!no_oblock)
7744 skip('}');
7745 /* patch type size if needed, which happens only for array types */
7746 if (n < 0)
7747 s->c = size1 == 1 ? len : ((len + size1 - 1)/size1);
7748 } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
7749 size1 = 1;
7750 no_oblock = 1;
7751 if ((flags & DIF_FIRST) || tok == '{') {
7752 skip('{');
7753 no_oblock = 0;
7755 s = type->ref;
7756 f = s->next;
7757 n = s->c;
7758 goto do_init_list;
7759 } else if (tok == '{') {
7760 if (flags & DIF_HAVE_ELEM)
7761 skip(';');
7762 next();
7763 decl_initializer(type, sec, c, flags & ~DIF_HAVE_ELEM);
7764 skip('}');
7765 } else if ((flags & DIF_SIZE_ONLY)) {
7766 /* If we supported only ISO C we wouldn't have to accept calling
7767 this on anything than an array if DIF_SIZE_ONLY (and even then
7768 only on the outermost level, so no recursion would be needed),
7769 because initializing a flex array member isn't supported.
7770 But GNU C supports it, so we need to recurse even into
7771 subfields of structs and arrays when DIF_SIZE_ONLY is set. */
7772 /* just skip expression */
7773 skip_or_save_block(NULL);
7774 } else {
7775 if (!(flags & DIF_HAVE_ELEM)) {
7776 /* This should happen only when we haven't parsed
7777 the init element above for fear of committing a
7778 string constant to memory too early. */
7779 if (tok != TOK_STR && tok != TOK_LSTR)
7780 expect("string constant");
7781 parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
7783 init_putv(type, sec, c);
7787 /* parse an initializer for type 't' if 'has_init' is non zero, and
7788 allocate space in local or global data space ('r' is either
7789 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7790 variable 'v' of scope 'scope' is declared before initializers
7791 are parsed. If 'v' is zero, then a reference to the new object
7792 is put in the value stack. If 'has_init' is 2, a special parsing
7793 is done to handle string constants. */
7794 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
7795 int has_init, int v, int scope)
7797 int size, align, addr;
7798 TokenString *init_str = NULL;
7800 Section *sec;
7801 Sym *flexible_array;
7802 Sym *sym = NULL;
7803 int saved_nocode_wanted = nocode_wanted;
7804 #ifdef CONFIG_TCC_BCHECK
7805 int bcheck = tcc_state->do_bounds_check && !NODATA_WANTED;
7806 #endif
7808 /* Always allocate static or global variables */
7809 if (v && (r & VT_VALMASK) == VT_CONST)
7810 nocode_wanted |= 0x80000000;
7812 flexible_array = NULL;
7813 if ((type->t & VT_BTYPE) == VT_STRUCT) {
7814 Sym *field = type->ref->next;
7815 if (field) {
7816 while (field->next)
7817 field = field->next;
7818 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
7819 flexible_array = field;
7823 size = type_size(type, &align);
7824 /* If unknown size, we must evaluate it before
7825 evaluating initializers because
7826 initializers can generate global data too
7827 (e.g. string pointers or ISOC99 compound
7828 literals). It also simplifies local
7829 initializers handling */
7830 if (size < 0 || (flexible_array && has_init)) {
7831 if (!has_init)
7832 tcc_error("unknown type size");
7833 /* get all init string */
7834 if (has_init == 2) {
7835 init_str = tok_str_alloc();
7836 /* only get strings */
7837 while (tok == TOK_STR || tok == TOK_LSTR) {
7838 tok_str_add_tok(init_str);
7839 next();
7841 tok_str_add(init_str, -1);
7842 tok_str_add(init_str, 0);
7843 } else {
7844 skip_or_save_block(&init_str);
7846 unget_tok(0);
7848 /* compute size */
7849 begin_macro(init_str, 1);
7850 next();
7851 decl_initializer(type, NULL, 0, DIF_FIRST | DIF_SIZE_ONLY);
7852 /* prepare second initializer parsing */
7853 macro_ptr = init_str->str;
7854 next();
7856 /* if still unknown size, error */
7857 size = type_size(type, &align);
7858 if (size < 0)
7859 tcc_error("unknown type size");
7861 /* If there's a flex member and it was used in the initializer
7862 adjust size. */
7863 if (flexible_array &&
7864 flexible_array->type.ref->c > 0)
7865 size += flexible_array->type.ref->c
7866 * pointed_size(&flexible_array->type);
7867 /* take into account specified alignment if bigger */
7868 if (ad->a.aligned) {
7869 int speca = 1 << (ad->a.aligned - 1);
7870 if (speca > align)
7871 align = speca;
7872 } else if (ad->a.packed) {
7873 align = 1;
7876 if (!v && NODATA_WANTED)
7877 size = 0, align = 1;
7879 if ((r & VT_VALMASK) == VT_LOCAL) {
7880 sec = NULL;
7881 #ifdef CONFIG_TCC_BCHECK
7882 if (bcheck && v) {
7883 /* add padding between stack variables for bound checking */
7884 loc--;
7886 #endif
7887 loc = (loc - size) & -align;
7888 addr = loc;
7889 #ifdef CONFIG_TCC_BCHECK
7890 if (bcheck && v) {
7891 /* add padding between stack variables for bound checking */
7892 loc--;
7894 #endif
7895 if (v) {
7896 /* local variable */
7897 #ifdef CONFIG_TCC_ASM
7898 if (ad->asm_label) {
7899 int reg = asm_parse_regvar(ad->asm_label);
7900 if (reg >= 0)
7901 r = (r & ~VT_VALMASK) | reg;
7903 #endif
7904 sym = sym_push(v, type, r, addr);
7905 if (ad->cleanup_func) {
7906 Sym *cls = sym_push2(&all_cleanups,
7907 SYM_FIELD | ++cur_scope->cl.n, 0, 0);
7908 cls->prev_tok = sym;
7909 cls->next = ad->cleanup_func;
7910 cls->ncl = cur_scope->cl.s;
7911 cur_scope->cl.s = cls;
7914 sym->a = ad->a;
7915 } else {
7916 /* push local reference */
7917 vset(type, r, addr);
7919 } else {
7920 if (v && scope == VT_CONST) {
7921 /* see if the symbol was already defined */
7922 sym = sym_find(v);
7923 if (sym) {
7924 patch_storage(sym, ad, type);
7925 /* we accept several definitions of the same global variable. */
7926 if (!has_init && sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)
7927 goto no_alloc;
7931 /* allocate symbol in corresponding section */
7932 sec = ad->section;
7933 if (!sec) {
7934 if (has_init)
7935 sec = data_section;
7936 else if (tcc_state->nocommon)
7937 sec = bss_section;
7940 if (sec) {
7941 addr = section_add(sec, size, align);
7942 #ifdef CONFIG_TCC_BCHECK
7943 /* add padding if bound check */
7944 if (bcheck)
7945 section_add(sec, 1, 1);
7946 #endif
7947 } else {
7948 addr = align; /* SHN_COMMON is special, symbol value is align */
7949 sec = common_section;
7952 if (v) {
7953 if (!sym) {
7954 sym = sym_push(v, type, r | VT_SYM, 0);
7955 patch_storage(sym, ad, NULL);
7957 /* update symbol definition */
7958 put_extern_sym(sym, sec, addr, size);
7959 } else {
7960 /* push global reference */
7961 vpush_ref(type, sec, addr, size);
7962 sym = vtop->sym;
7963 vtop->r |= r;
7966 #ifdef CONFIG_TCC_BCHECK
7967 /* handles bounds now because the symbol must be defined
7968 before for the relocation */
7969 if (bcheck) {
7970 addr_t *bounds_ptr;
7972 greloca(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR, 0);
7973 /* then add global bound info */
7974 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
7975 bounds_ptr[0] = 0; /* relocated */
7976 bounds_ptr[1] = size;
7978 #endif
7981 if (type->t & VT_VLA) {
7982 int a;
7984 if (NODATA_WANTED)
7985 goto no_alloc;
7987 /* save current stack pointer */
7988 if (root_scope->vla.loc == 0) {
7989 struct scope *v = cur_scope;
7990 gen_vla_sp_save(loc -= PTR_SIZE);
7991 do v->vla.loc = loc; while ((v = v->prev));
7994 vla_runtime_type_size(type, &a);
7995 gen_vla_alloc(type, a);
7996 #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
7997 /* on _WIN64, because of the function args scratch area, the
7998 result of alloca differs from RSP and is returned in RAX. */
7999 gen_vla_result(addr), addr = (loc -= PTR_SIZE);
8000 #endif
8001 gen_vla_sp_save(addr);
8002 cur_scope->vla.loc = addr;
8003 cur_scope->vla.num++;
8004 } else if (has_init) {
8005 size_t oldreloc_offset = 0;
8006 if (sec && sec->reloc)
8007 oldreloc_offset = sec->reloc->data_offset;
8008 decl_initializer(type, sec, addr, DIF_FIRST);
8009 if (sec && sec->reloc)
8010 squeeze_multi_relocs(sec, oldreloc_offset);
8011 /* patch flexible array member size back to -1, */
8012 /* for possible subsequent similar declarations */
8013 if (flexible_array)
8014 flexible_array->type.ref->c = -1;
8017 no_alloc:
8018 /* restore parse state if needed */
8019 if (init_str) {
8020 end_macro();
8021 next();
8024 nocode_wanted = saved_nocode_wanted;
8027 /* parse a function defined by symbol 'sym' and generate its code in
8028 'cur_text_section' */
8029 static void gen_function(Sym *sym)
8031 /* Initialize VLA state */
8032 struct scope f = { 0 };
8033 cur_scope = root_scope = &f;
8035 nocode_wanted = 0;
8036 ind = cur_text_section->data_offset;
8037 if (sym->a.aligned) {
8038 size_t newoff = section_add(cur_text_section, 0,
8039 1 << (sym->a.aligned - 1));
8040 gen_fill_nops(newoff - ind);
8042 /* NOTE: we patch the symbol size later */
8043 put_extern_sym(sym, cur_text_section, ind, 0);
8044 if (sym->type.ref->f.func_ctor)
8045 add_array (tcc_state, ".init_array", sym->c);
8046 if (sym->type.ref->f.func_dtor)
8047 add_array (tcc_state, ".fini_array", sym->c);
8049 funcname = get_tok_str(sym->v, NULL);
8050 func_ind = ind;
8051 func_vt = sym->type.ref->type;
8052 func_var = sym->type.ref->f.func_type == FUNC_ELLIPSIS;
8054 /* put debug symbol */
8055 tcc_debug_funcstart(tcc_state, sym);
8056 /* push a dummy symbol to enable local sym storage */
8057 sym_push2(&local_stack, SYM_FIELD, 0, 0);
8058 local_scope = 1; /* for function parameters */
8059 gfunc_prolog(sym);
8060 local_scope = 0;
8061 rsym = 0;
8062 clear_temp_local_var_list();
8063 block(0);
8064 gsym(rsym);
8065 nocode_wanted = 0;
8066 /* reset local stack */
8067 pop_local_syms(&local_stack, NULL, 0, func_var);
8068 gfunc_epilog();
8069 cur_text_section->data_offset = ind;
8070 local_scope = 0;
8071 label_pop(&global_label_stack, NULL, 0);
8072 sym_pop(&all_cleanups, NULL, 0);
8073 /* patch symbol size */
8074 elfsym(sym)->st_size = ind - func_ind;
8075 /* end of function */
8076 tcc_debug_funcend(tcc_state, ind - func_ind);
8077 /* It's better to crash than to generate wrong code */
8078 cur_text_section = NULL;
8079 funcname = ""; /* for safety */
8080 func_vt.t = VT_VOID; /* for safety */
8081 func_var = 0; /* for safety */
8082 ind = 0; /* for safety */
8083 nocode_wanted = 0x80000000;
8084 check_vstack();
8085 /* do this after funcend debug info */
8086 next();
8089 static void gen_inline_functions(TCCState *s)
8091 Sym *sym;
8092 int inline_generated, i;
8093 struct InlineFunc *fn;
8095 tcc_open_bf(s, ":inline:", 0);
8096 /* iterate while inline function are referenced */
8097 do {
8098 inline_generated = 0;
8099 for (i = 0; i < s->nb_inline_fns; ++i) {
8100 fn = s->inline_fns[i];
8101 sym = fn->sym;
8102 if (sym && (sym->c || !(sym->type.t & VT_INLINE))) {
8103 /* the function was used or forced (and then not internal):
8104 generate its code and convert it to a normal function */
8105 fn->sym = NULL;
8106 tcc_debug_putfile(s, fn->filename);
8107 begin_macro(fn->func_str, 1);
8108 next();
8109 cur_text_section = text_section;
8110 gen_function(sym);
8111 end_macro();
8113 inline_generated = 1;
8116 } while (inline_generated);
8117 tcc_close();
8120 static void free_inline_functions(TCCState *s)
8122 int i;
8123 /* free tokens of unused inline functions */
8124 for (i = 0; i < s->nb_inline_fns; ++i) {
8125 struct InlineFunc *fn = s->inline_fns[i];
8126 if (fn->sym)
8127 tok_str_free(fn->func_str);
8129 dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
8132 /* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
8133 if parsing old style parameter decl list (and FUNC_SYM is set then) */
8134 static int decl0(int l, int is_for_loop_init, Sym *func_sym)
8136 int v, has_init, r;
8137 CType type, btype;
8138 Sym *sym;
8139 AttributeDef ad, adbase;
8141 while (1) {
8142 if (tok == TOK_STATIC_ASSERT) {
8143 CString error_str;
8144 int c;
8146 next();
8147 skip('(');
8148 c = expr_const();
8150 if (tok == ')') {
8151 if (!c)
8152 tcc_error("_Static_assert fail");
8153 next();
8154 goto static_assert_out;
8157 skip(',');
8158 parse_mult_str(&error_str, "string constant");
8159 if (c == 0)
8160 tcc_error("%s", (char *)error_str.data);
8161 cstr_free(&error_str);
8162 skip(')');
8163 static_assert_out:
8164 skip(';');
8165 continue;
8167 if (!parse_btype(&btype, &adbase)) {
8168 if (is_for_loop_init)
8169 return 0;
8170 /* skip redundant ';' if not in old parameter decl scope */
8171 if (tok == ';' && l != VT_CMP) {
8172 next();
8173 continue;
8175 if (l != VT_CONST)
8176 break;
8177 if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
8178 /* global asm block */
8179 asm_global_instr();
8180 continue;
8182 if (tok >= TOK_UIDENT) {
8183 /* special test for old K&R protos without explicit int
8184 type. Only accepted when defining global data */
8185 btype.t = VT_INT;
8186 } else {
8187 if (tok != TOK_EOF)
8188 expect("declaration");
8189 break;
8192 if (tok == ';') {
8193 if ((btype.t & VT_BTYPE) == VT_STRUCT) {
8194 int v = btype.ref->v;
8195 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
8196 tcc_warning("unnamed struct/union that defines no instances");
8197 next();
8198 continue;
8200 if (IS_ENUM(btype.t)) {
8201 next();
8202 continue;
8205 while (1) { /* iterate thru each declaration */
8206 type = btype;
8207 /* If the base type itself was an array type of unspecified
8208 size (like in 'typedef int arr[]; arr x = {1};') then
8209 we will overwrite the unknown size by the real one for
8210 this decl. We need to unshare the ref symbol holding
8211 that size. */
8212 if ((type.t & VT_ARRAY) && type.ref->c < 0) {
8213 type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c);
8215 ad = adbase;
8216 type_decl(&type, &ad, &v, TYPE_DIRECT);
8217 #if 0
8219 char buf[500];
8220 type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL));
8221 printf("type = '%s'\n", buf);
8223 #endif
8224 if ((type.t & VT_BTYPE) == VT_FUNC) {
8225 if ((type.t & VT_STATIC) && (l == VT_LOCAL))
8226 tcc_error("function without file scope cannot be static");
8227 /* if old style function prototype, we accept a
8228 declaration list */
8229 sym = type.ref;
8230 if (sym->f.func_type == FUNC_OLD && l == VT_CONST)
8231 decl0(VT_CMP, 0, sym);
8232 if (sym->f.func_alwinl
8233 && ((type.t & (VT_EXTERN | VT_INLINE))
8234 == (VT_EXTERN | VT_INLINE))) {
8235 /* always_inline functions must be handled as if they
8236 don't generate multiple global defs, even if extern
8237 inline, i.e. GNU inline semantics for those. Rewrite
8238 them into static inline. */
8239 type.t &= ~VT_EXTERN;
8240 type.t |= VT_STATIC;
8242 /* always compile 'extern inline' */
8243 if (type.t & VT_EXTERN)
8244 type.t &= ~VT_INLINE;
8247 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
8248 ad.asm_label = asm_label_instr();
8249 /* parse one last attribute list, after asm label */
8250 parse_attribute(&ad);
8251 #if 0
8252 /* gcc does not allow __asm__("label") with function definition,
8253 but why not ... */
8254 if (tok == '{')
8255 expect(";");
8256 #endif
8259 #ifdef TCC_TARGET_PE
8260 if (ad.a.dllimport || ad.a.dllexport) {
8261 if (type.t & VT_STATIC)
8262 tcc_error("cannot have dll linkage with static");
8263 if (type.t & VT_TYPEDEF) {
8264 tcc_warning("'%s' attribute ignored for typedef",
8265 ad.a.dllimport ? (ad.a.dllimport = 0, "dllimport") :
8266 (ad.a.dllexport = 0, "dllexport"));
8267 } else if (ad.a.dllimport) {
8268 if ((type.t & VT_BTYPE) == VT_FUNC)
8269 ad.a.dllimport = 0;
8270 else
8271 type.t |= VT_EXTERN;
8274 #endif
8275 if (tok == '{') {
8276 if (l != VT_CONST)
8277 tcc_error("cannot use local functions");
8278 if ((type.t & VT_BTYPE) != VT_FUNC)
8279 expect("function definition");
8281 /* reject abstract declarators in function definition
8282 make old style params without decl have int type */
8283 sym = type.ref;
8284 while ((sym = sym->next) != NULL) {
8285 if (!(sym->v & ~SYM_FIELD))
8286 expect("identifier");
8287 if (sym->type.t == VT_VOID)
8288 sym->type = int_type;
8291 /* apply post-declaraton attributes */
8292 merge_funcattr(&type.ref->f, &ad.f);
8294 /* put function symbol */
8295 type.t &= ~VT_EXTERN;
8296 sym = external_sym(v, &type, 0, &ad);
8298 /* static inline functions are just recorded as a kind
8299 of macro. Their code will be emitted at the end of
8300 the compilation unit only if they are used */
8301 if (sym->type.t & VT_INLINE) {
8302 struct InlineFunc *fn;
8303 fn = tcc_malloc(sizeof *fn + strlen(file->filename));
8304 strcpy(fn->filename, file->filename);
8305 fn->sym = sym;
8306 skip_or_save_block(&fn->func_str);
8307 dynarray_add(&tcc_state->inline_fns,
8308 &tcc_state->nb_inline_fns, fn);
8309 } else {
8310 /* compute text section */
8311 cur_text_section = ad.section;
8312 if (!cur_text_section)
8313 cur_text_section = text_section;
8314 gen_function(sym);
8316 break;
8317 } else {
8318 if (l == VT_CMP) {
8319 /* find parameter in function parameter list */
8320 for (sym = func_sym->next; sym; sym = sym->next)
8321 if ((sym->v & ~SYM_FIELD) == v)
8322 goto found;
8323 tcc_error("declaration for parameter '%s' but no such parameter",
8324 get_tok_str(v, NULL));
8325 found:
8326 if (type.t & VT_STORAGE) /* 'register' is okay */
8327 tcc_error("storage class specified for '%s'",
8328 get_tok_str(v, NULL));
8329 if (sym->type.t != VT_VOID)
8330 tcc_error("redefinition of parameter '%s'",
8331 get_tok_str(v, NULL));
8332 convert_parameter_type(&type);
8333 sym->type = type;
8334 } else if (type.t & VT_TYPEDEF) {
8335 /* save typedefed type */
8336 /* XXX: test storage specifiers ? */
8337 sym = sym_find(v);
8338 if (sym && sym->sym_scope == local_scope) {
8339 if (!is_compatible_types(&sym->type, &type)
8340 || !(sym->type.t & VT_TYPEDEF))
8341 tcc_error("incompatible redefinition of '%s'",
8342 get_tok_str(v, NULL));
8343 sym->type = type;
8344 } else {
8345 sym = sym_push(v, &type, 0, 0);
8347 sym->a = ad.a;
8348 sym->f = ad.f;
8349 } else if ((type.t & VT_BTYPE) == VT_VOID
8350 && !(type.t & VT_EXTERN)) {
8351 tcc_error("declaration of void object");
8352 } else {
8353 r = 0;
8354 if ((type.t & VT_BTYPE) == VT_FUNC) {
8355 /* external function definition */
8356 /* specific case for func_call attribute */
8357 type.ref->f = ad.f;
8358 } else if (!(type.t & VT_ARRAY)) {
8359 /* not lvalue if array */
8360 r |= VT_LVAL;
8362 has_init = (tok == '=');
8363 if (has_init && (type.t & VT_VLA))
8364 tcc_error("variable length array cannot be initialized");
8365 if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST))
8366 || (type.t & VT_BTYPE) == VT_FUNC
8367 /* as with GCC, uninitialized global arrays with no size
8368 are considered extern: */
8369 || ((type.t & VT_ARRAY) && !has_init
8370 && l == VT_CONST && type.ref->c < 0)
8372 /* external variable or function */
8373 type.t |= VT_EXTERN;
8374 sym = external_sym(v, &type, r, &ad);
8375 if (ad.alias_target) {
8376 ElfSym *esym;
8377 Sym *alias_target;
8378 alias_target = sym_find(ad.alias_target);
8379 esym = elfsym(alias_target);
8380 if (!esym)
8381 tcc_error("unsupported forward __alias__ attribute");
8382 put_extern_sym2(sym, esym->st_shndx, esym->st_value, esym->st_size, 0);
8384 } else {
8385 if (type.t & VT_STATIC)
8386 r |= VT_CONST;
8387 else
8388 r |= l;
8389 if (has_init)
8390 next();
8391 else if (l == VT_CONST)
8392 /* uninitialized global variables may be overridden */
8393 type.t |= VT_EXTERN;
8394 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
8397 if (tok != ',') {
8398 if (is_for_loop_init)
8399 return 1;
8400 skip(';');
8401 break;
8403 next();
8407 return 0;
8410 static void decl(int l)
8412 decl0(l, 0, NULL);
8415 /* ------------------------------------------------------------------------- */
8416 #undef gjmp_addr
8417 #undef gjmp
8418 /* ------------------------------------------------------------------------- */