arm-asm, arm64-link: Silence warnings for unused functions
[tinycc.git] / tccgen.c
blobed417768cf62efe3f8a880c34167359b287ed2b5
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;
49 ST_DATA char debug_modes;
51 ST_DATA SValue *vtop;
52 static SValue _vstack[1 + VSTACK_SIZE];
53 #define vstack (_vstack + 1)
55 ST_DATA int const_wanted; /* true if constant wanted */
56 ST_DATA int nocode_wanted; /* no code generation wanted */
57 #define unevalmask 0xffff /* unevaluated subexpression */
58 #define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
59 #define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */
61 /* Automagical code suppression ----> */
62 #define CODE_OFF() (nocode_wanted |= 0x20000000)
63 #define CODE_ON() (nocode_wanted &= ~0x20000000)
65 static void tcc_tcov_block_begin(void);
67 /* Clear 'nocode_wanted' at label if it was used */
68 ST_FUNC void gsym(int t) { if (t) { gsym_addr(t, ind); CODE_ON(); }}
69 static int gind(void) { int t = ind; CODE_ON(); if (debug_modes) tcc_tcov_block_begin(); return t; }
71 /* Set 'nocode_wanted' after unconditional jumps */
72 static void gjmp_addr_acs(int t) { gjmp_addr(t); CODE_OFF(); }
73 static int gjmp_acs(int t) { t = gjmp(t); CODE_OFF(); return t; }
75 /* These are #undef'd at the end of this file */
76 #define gjmp_addr gjmp_addr_acs
77 #define gjmp gjmp_acs
78 /* <---- */
80 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
81 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
82 ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
83 ST_DATA int func_vc;
84 static int last_line_num, new_file, func_ind; /* debug info control */
85 ST_DATA const char *funcname;
86 ST_DATA CType int_type, func_old_type, char_type, char_pointer_type;
87 static CString initstr;
89 #if PTR_SIZE == 4
90 #define VT_SIZE_T (VT_INT | VT_UNSIGNED)
91 #define VT_PTRDIFF_T VT_INT
92 #elif LONG_SIZE == 4
93 #define VT_SIZE_T (VT_LLONG | VT_UNSIGNED)
94 #define VT_PTRDIFF_T VT_LLONG
95 #else
96 #define VT_SIZE_T (VT_LONG | VT_LLONG | VT_UNSIGNED)
97 #define VT_PTRDIFF_T (VT_LONG | VT_LLONG)
98 #endif
100 static struct switch_t {
101 struct case_t {
102 int64_t v1, v2;
103 int sym;
104 } **p; int n; /* list of case ranges */
105 int def_sym; /* default symbol */
106 int *bsym;
107 struct scope *scope;
108 struct switch_t *prev;
109 SValue sv;
110 } *cur_switch; /* current switch */
112 #define MAX_TEMP_LOCAL_VARIABLE_NUMBER 8
113 /*list of temporary local variables on the stack in current function. */
114 static struct temp_local_variable {
115 int location; //offset on stack. Svalue.c.i
116 short size;
117 short align;
118 } arr_temp_local_vars[MAX_TEMP_LOCAL_VARIABLE_NUMBER];
119 static int nb_temp_local_vars;
121 static struct scope {
122 struct scope *prev;
123 struct { int loc, locorig, num; } vla;
124 struct { Sym *s; int n; } cl;
125 int *bsym, *csym;
126 Sym *lstk, *llstk;
127 } *cur_scope, *loop_scope, *root_scope;
129 typedef struct {
130 Section *sec;
131 int local_offset;
132 Sym *flex_array_ref;
133 } init_params;
135 #if 1
136 #define precedence_parser
137 static void init_prec(void);
138 #endif
140 /********************************************************/
141 /* stab debug support */
143 static const struct {
144 int type;
145 const char *name;
146 } default_debug[] = {
147 { VT_INT, "int:t1=r1;-2147483648;2147483647;" },
148 { VT_BYTE, "char:t2=r2;0;127;" },
149 #if LONG_SIZE == 4
150 { VT_LONG | VT_INT, "long int:t3=r3;-2147483648;2147483647;" },
151 #else
152 { VT_LLONG | VT_LONG, "long int:t3=r3;-9223372036854775808;9223372036854775807;" },
153 #endif
154 { VT_INT | VT_UNSIGNED, "unsigned int:t4=r4;0;037777777777;" },
155 #if LONG_SIZE == 4
156 { VT_LONG | VT_INT | VT_UNSIGNED, "long unsigned int:t5=r5;0;037777777777;" },
157 #else
158 /* use octal instead of -1 so size_t works (-gstabs+ in gcc) */
159 { VT_LLONG | VT_LONG | VT_UNSIGNED, "long unsigned int:t5=r5;0;01777777777777777777777;" },
160 #endif
161 { VT_QLONG, "__int128:t6=r6;0;-1;" },
162 { VT_QLONG | VT_UNSIGNED, "__int128 unsigned:t7=r7;0;-1;" },
163 { VT_LLONG, "long long int:t8=r8;-9223372036854775808;9223372036854775807;" },
164 { VT_LLONG | VT_UNSIGNED, "long long unsigned int:t9=r9;0;01777777777777777777777;" },
165 { VT_SHORT, "short int:t10=r10;-32768;32767;" },
166 { VT_SHORT | VT_UNSIGNED, "short unsigned int:t11=r11;0;65535;" },
167 { VT_BYTE | VT_DEFSIGN, "signed char:t12=r12;-128;127;" },
168 { VT_BYTE | VT_DEFSIGN | VT_UNSIGNED, "unsigned char:t13=r13;0;255;" },
169 { VT_FLOAT, "float:t14=r1;4;0;" },
170 { VT_DOUBLE, "double:t15=r1;8;0;" },
171 #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
172 { VT_DOUBLE | VT_LONG, "long double:t16=r1;8;0;" },
173 #else
174 { VT_LDOUBLE, "long double:t16=r1;16;0;" },
175 #endif
176 { -1, "_Float32:t17=r1;4;0;" },
177 { -1, "_Float64:t18=r1;8;0;" },
178 { -1, "_Float128:t19=r1;16;0;" },
179 { -1, "_Float32x:t20=r1;8;0;" },
180 { -1, "_Float64x:t21=r1;16;0;" },
181 { -1, "_Decimal32:t22=r1;4;0;" },
182 { -1, "_Decimal64:t23=r1;8;0;" },
183 { -1, "_Decimal128:t24=r1;16;0;" },
184 /* if default char is unsigned */
185 { VT_BYTE | VT_UNSIGNED, "unsigned char:t25=r25;0;255;" },
186 /* boolean type */
187 { VT_BOOL, "bool:t26=r26;0;255;" },
188 { VT_VOID, "void:t27=27" },
191 static int debug_next_type;
193 static struct debug_hash {
194 int debug_type;
195 Sym *type;
196 } *debug_hash;
198 static int n_debug_hash;
200 static struct debug_info {
201 int start;
202 int end;
203 int n_sym;
204 struct debug_sym {
205 int type;
206 unsigned long value;
207 char *str;
208 Section *sec;
209 int sym_index;
210 } *sym;
211 struct debug_info *child, *next, *last, *parent;
212 } *debug_info, *debug_info_root;
214 static struct {
215 unsigned long offset;
216 unsigned long last_file_name;
217 unsigned long last_func_name;
218 int ind;
219 int line;
220 } tcov_data;
222 /********************************************************/
223 static void gen_cast(CType *type);
224 static void gen_cast_s(int t);
225 static inline CType *pointed_type(CType *type);
226 static int is_compatible_types(CType *type1, CType *type2);
227 static int parse_btype(CType *type, AttributeDef *ad);
228 static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td);
229 static void parse_expr_type(CType *type);
230 static void init_putv(init_params *p, CType *type, unsigned long c);
231 static void decl_initializer(init_params *p, CType *type, unsigned long c, int flags);
232 static void block(int is_expr);
233 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
234 static void decl(int l);
235 static int decl0(int l, int is_for_loop_init, Sym *);
236 static void expr_eq(void);
237 static void vpush_type_size(CType *type, int *a);
238 static int is_compatible_unqualified_types(CType *type1, CType *type2);
239 static inline int64_t expr_const64(void);
240 static void vpush64(int ty, unsigned long long v);
241 static void vpush(CType *type);
242 static int gvtst(int inv, int t);
243 static void gen_inline_functions(TCCState *s);
244 static void free_inline_functions(TCCState *s);
245 static void skip_or_save_block(TokenString **str);
246 static void gv_dup(void);
247 static int get_temp_local_var(int size,int align);
248 static void clear_temp_local_var_list();
249 static void cast_error(CType *st, CType *dt);
251 ST_INLN int is_float(int t)
253 int bt = t & VT_BTYPE;
254 return bt == VT_LDOUBLE
255 || bt == VT_DOUBLE
256 || bt == VT_FLOAT
257 || bt == VT_QFLOAT;
260 static inline int is_integer_btype(int bt)
262 return bt == VT_BYTE
263 || bt == VT_BOOL
264 || bt == VT_SHORT
265 || bt == VT_INT
266 || bt == VT_LLONG;
269 static int btype_size(int bt)
271 return bt == VT_BYTE || bt == VT_BOOL ? 1 :
272 bt == VT_SHORT ? 2 :
273 bt == VT_INT ? 4 :
274 bt == VT_LLONG ? 8 :
275 bt == VT_PTR ? PTR_SIZE : 0;
278 /* returns function return register from type */
279 static int R_RET(int t)
281 if (!is_float(t))
282 return REG_IRET;
283 #ifdef TCC_TARGET_X86_64
284 if ((t & VT_BTYPE) == VT_LDOUBLE)
285 return TREG_ST0;
286 #elif defined TCC_TARGET_RISCV64
287 if ((t & VT_BTYPE) == VT_LDOUBLE)
288 return REG_IRET;
289 #endif
290 return REG_FRET;
293 /* returns 2nd function return register, if any */
294 static int R2_RET(int t)
296 t &= VT_BTYPE;
297 #if PTR_SIZE == 4
298 if (t == VT_LLONG)
299 return REG_IRE2;
300 #elif defined TCC_TARGET_X86_64
301 if (t == VT_QLONG)
302 return REG_IRE2;
303 if (t == VT_QFLOAT)
304 return REG_FRE2;
305 #elif defined TCC_TARGET_RISCV64
306 if (t == VT_LDOUBLE)
307 return REG_IRE2;
308 #endif
309 return VT_CONST;
312 /* returns true for two-word types */
313 #define USING_TWO_WORDS(t) (R2_RET(t) != VT_CONST)
315 /* put function return registers to stack value */
316 static void PUT_R_RET(SValue *sv, int t)
318 sv->r = R_RET(t), sv->r2 = R2_RET(t);
321 /* returns function return register class for type t */
322 static int RC_RET(int t)
324 return reg_classes[R_RET(t)] & ~(RC_FLOAT | RC_INT);
327 /* returns generic register class for type t */
328 static int RC_TYPE(int t)
330 if (!is_float(t))
331 return RC_INT;
332 #ifdef TCC_TARGET_X86_64
333 if ((t & VT_BTYPE) == VT_LDOUBLE)
334 return RC_ST0;
335 if ((t & VT_BTYPE) == VT_QFLOAT)
336 return RC_FRET;
337 #elif defined TCC_TARGET_RISCV64
338 if ((t & VT_BTYPE) == VT_LDOUBLE)
339 return RC_INT;
340 #endif
341 return RC_FLOAT;
344 /* returns 2nd register class corresponding to t and rc */
345 static int RC2_TYPE(int t, int rc)
347 if (!USING_TWO_WORDS(t))
348 return 0;
349 #ifdef RC_IRE2
350 if (rc == RC_IRET)
351 return RC_IRE2;
352 #endif
353 #ifdef RC_FRE2
354 if (rc == RC_FRET)
355 return RC_FRE2;
356 #endif
357 if (rc & RC_FLOAT)
358 return RC_FLOAT;
359 return RC_INT;
362 /* we use our own 'finite' function to avoid potential problems with
363 non standard math libs */
364 /* XXX: endianness dependent */
365 ST_FUNC int ieee_finite(double d)
367 int p[4];
368 memcpy(p, &d, sizeof(double));
369 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
372 /* compiling intel long double natively */
373 #if (defined __i386__ || defined __x86_64__) \
374 && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
375 # define TCC_IS_NATIVE_387
376 #endif
378 ST_FUNC void test_lvalue(void)
380 if (!(vtop->r & VT_LVAL))
381 expect("lvalue");
384 ST_FUNC void check_vstack(void)
386 if (vtop != vstack - 1)
387 tcc_error("internal compiler error: vstack leak (%d)",
388 (int)(vtop - vstack + 1));
391 /* ------------------------------------------------------------------------- */
392 /* vstack debugging aid */
394 #if 0
395 void pv (const char *lbl, int a, int b)
397 int i;
398 for (i = a; i < a + b; ++i) {
399 SValue *p = &vtop[-i];
400 printf("%s vtop[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n",
401 lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);
404 #endif
406 /* ------------------------------------------------------------------------- */
407 /* start of translation unit info */
408 ST_FUNC void tcc_debug_start(TCCState *s1)
410 if (s1->do_debug) {
411 int i;
412 char buf[512];
414 /* file info: full path + filename */
415 section_sym = put_elf_sym(symtab_section, 0, 0,
416 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
417 text_section->sh_num, NULL);
418 getcwd(buf, sizeof(buf));
419 #ifdef _WIN32
420 normalize_slashes(buf);
421 #endif
422 pstrcat(buf, sizeof(buf), "/");
423 put_stabs_r(s1, buf, N_SO, 0, 0,
424 text_section->data_offset, text_section, section_sym);
425 put_stabs_r(s1, file->prev ? file->prev->filename : file->filename,
426 N_SO, 0, 0,
427 text_section->data_offset, text_section, section_sym);
428 for (i = 0; i < sizeof (default_debug) / sizeof (default_debug[0]); i++)
429 put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0);
431 new_file = last_line_num = 0;
432 func_ind = -1;
433 debug_next_type = sizeof(default_debug) / sizeof(default_debug[0]);
434 debug_hash = NULL;
435 n_debug_hash = 0;
437 /* we're currently 'including' the <command line> */
438 tcc_debug_bincl(s1);
441 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
442 symbols can be safely used */
443 put_elf_sym(symtab_section, 0, 0,
444 ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
445 SHN_ABS, file->filename);
448 /* put end of translation unit info */
449 ST_FUNC void tcc_debug_end(TCCState *s1)
451 if (!s1->do_debug)
452 return;
453 put_stabs_r(s1, NULL, N_SO, 0, 0,
454 text_section->data_offset, text_section, section_sym);
455 tcc_free(debug_hash);
458 static BufferedFile* put_new_file(TCCState *s1)
460 BufferedFile *f = file;
461 /* use upper file if from inline ":asm:" */
462 if (f->filename[0] == ':')
463 f = f->prev;
464 if (f && new_file) {
465 put_stabs_r(s1, f->filename, N_SOL, 0, 0, ind, text_section, section_sym);
466 new_file = last_line_num = 0;
468 return f;
471 /* put alternative filename */
472 ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename)
474 if (0 == strcmp(file->filename, filename))
475 return;
476 pstrcpy(file->filename, sizeof(file->filename), filename);
477 new_file = 1;
480 /* begin of #include */
481 ST_FUNC void tcc_debug_bincl(TCCState *s1)
483 if (!s1->do_debug)
484 return;
485 put_stabs(s1, file->filename, N_BINCL, 0, 0, 0);
486 new_file = 1;
489 /* end of #include */
490 ST_FUNC void tcc_debug_eincl(TCCState *s1)
492 if (!s1->do_debug)
493 return;
494 put_stabn(s1, N_EINCL, 0, 0, 0);
495 new_file = 1;
498 /* generate line number info */
499 static void tcc_debug_line(TCCState *s1)
501 BufferedFile *f;
502 if (!s1->do_debug
503 || cur_text_section != text_section
504 || !(f = put_new_file(s1))
505 || last_line_num == f->line_num)
506 return;
507 if (func_ind != -1) {
508 put_stabn(s1, N_SLINE, 0, f->line_num, ind - func_ind);
509 } else {
510 /* from tcc_assemble */
511 put_stabs_r(s1, NULL, N_SLINE, 0, f->line_num, ind, text_section, section_sym);
513 last_line_num = f->line_num;
516 static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned long value,
517 Section *sec, int sym_index)
519 struct debug_sym *s;
521 if (debug_info) {
522 debug_info->sym =
523 (struct debug_sym *)tcc_realloc (debug_info->sym,
524 sizeof(struct debug_sym) *
525 (debug_info->n_sym + 1));
526 s = debug_info->sym + debug_info->n_sym++;
527 s->type = type;
528 s->value = value;
529 s->str = tcc_strdup(str);
530 s->sec = sec;
531 s->sym_index = sym_index;
533 else if (sec)
534 put_stabs_r (s1, str, type, 0, 0, value, sec, sym_index);
535 else
536 put_stabs (s1, str, type, 0, 0, value);
539 static void tcc_debug_stabn(TCCState *s1, int type, int value)
541 if (!s1->do_debug)
542 return;
543 if (type == N_LBRAC) {
544 struct debug_info *info =
545 (struct debug_info *) tcc_mallocz(sizeof (*info));
547 info->start = value;
548 info->parent = debug_info;
549 if (debug_info) {
550 if (debug_info->child) {
551 if (debug_info->child->last)
552 debug_info->child->last->next = info;
553 else
554 debug_info->child->next = info;
555 debug_info->child->last = info;
557 else
558 debug_info->child = info;
560 else
561 debug_info_root = info;
562 debug_info = info;
564 else {
565 debug_info->end = value;
566 debug_info = debug_info->parent;
570 static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result)
572 int type;
573 int n = 0;
574 int debug_type = -1;
575 Sym *t = s;
576 CString str;
578 for (;;) {
579 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE);
580 if ((type & VT_BTYPE) != VT_BYTE)
581 type &= ~VT_DEFSIGN;
582 if (type == VT_PTR || type == (VT_PTR | VT_ARRAY))
583 n++, t = t->type.ref;
584 else
585 break;
587 if ((type & VT_BTYPE) == VT_STRUCT) {
588 int i;
590 t = t->type.ref;
591 for (i = 0; i < n_debug_hash; i++) {
592 if (t == debug_hash[i].type) {
593 debug_type = debug_hash[i].debug_type;
594 break;
597 if (debug_type == -1) {
598 debug_type = ++debug_next_type;
599 debug_hash = (struct debug_hash *)
600 tcc_realloc (debug_hash,
601 (n_debug_hash + 1) * sizeof(*debug_hash));
602 debug_hash[n_debug_hash].debug_type = debug_type;
603 debug_hash[n_debug_hash++].type = t;
604 cstr_new (&str);
605 cstr_printf (&str, "%s:T%d=%c%d",
606 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
607 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL),
608 debug_type,
609 IS_UNION (t->type.t) ? 'u' : 's',
610 t->c);
611 while (t->next) {
612 int pos, size, align;
614 t = t->next;
615 cstr_printf (&str, "%s:",
616 (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
617 ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL));
618 tcc_get_debug_info (s1, t, &str);
619 if (t->type.t & VT_BITFIELD) {
620 pos = t->c * 8 + BIT_POS(t->type.t);
621 size = BIT_SIZE(t->type.t);
623 else {
624 pos = t->c * 8;
625 size = type_size(&t->type, &align) * 8;
627 cstr_printf (&str, ",%d,%d;", pos, size);
629 cstr_printf (&str, ";");
630 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0);
631 cstr_free (&str);
634 else if (IS_ENUM(type)) {
635 Sym *e = t = t->type.ref;
637 debug_type = ++debug_next_type;
638 cstr_new (&str);
639 cstr_printf (&str, "%s:T%d=e",
640 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
641 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL),
642 debug_type);
643 while (t->next) {
644 t = t->next;
645 cstr_printf (&str, "%s:",
646 (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
647 ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL));
648 cstr_printf (&str, e->type.t & VT_UNSIGNED ? "%u," : "%d,",
649 (int)t->enum_val);
651 cstr_printf (&str, ";");
652 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0);
653 cstr_free (&str);
655 else if ((type & VT_BTYPE) != VT_FUNC) {
656 type &= ~VT_STRUCT_MASK;
657 for (debug_type = 1;
658 debug_type <= sizeof(default_debug) / sizeof(default_debug[0]);
659 debug_type++)
660 if (default_debug[debug_type - 1].type == type)
661 break;
662 if (debug_type > sizeof(default_debug) / sizeof(default_debug[0]))
663 return;
665 if (n > 0)
666 cstr_printf (result, "%d=", ++debug_next_type);
667 t = s;
668 for (;;) {
669 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE);
670 if ((type & VT_BTYPE) != VT_BYTE)
671 type &= ~VT_DEFSIGN;
672 if (type == VT_PTR)
673 cstr_printf (result, "%d=*", ++debug_next_type);
674 else if (type == (VT_PTR | VT_ARRAY))
675 cstr_printf (result, "%d=ar1;0;%d;",
676 ++debug_next_type, t->type.ref->c - 1);
677 else if (type == VT_FUNC) {
678 cstr_printf (result, "%d=f", ++debug_next_type);
679 tcc_get_debug_info (s1, t->type.ref, result);
680 return;
682 else
683 break;
684 t = t->type.ref;
686 cstr_printf (result, "%d", debug_type);
689 static void tcc_debug_finish (TCCState *s1, struct debug_info *cur)
691 while (cur) {
692 int i;
693 struct debug_info *next = cur->next;
695 for (i = 0; i < cur->n_sym; i++) {
696 struct debug_sym *s = &cur->sym[i];
698 if (s->sec)
699 put_stabs_r(s1, s->str, s->type, 0, 0, s->value,
700 s->sec, s->sym_index);
701 else
702 put_stabs(s1, s->str, s->type, 0, 0, s->value);
703 tcc_free (s->str);
705 tcc_free (cur->sym);
706 put_stabn(s1, N_LBRAC, 0, 0, cur->start);
707 tcc_debug_finish (s1, cur->child);
708 put_stabn(s1, N_RBRAC, 0, 0, cur->end);
709 tcc_free (cur);
710 cur = next;
714 static void tcc_add_debug_info(TCCState *s1, int param, Sym *s, Sym *e)
716 CString debug_str;
717 if (!s1->do_debug)
718 return;
719 cstr_new (&debug_str);
720 for (; s != e; s = s->prev) {
721 if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL)
722 continue;
723 cstr_reset (&debug_str);
724 cstr_printf (&debug_str, "%s:%s", get_tok_str(s->v, NULL), param ? "p" : "");
725 tcc_get_debug_info(s1, s, &debug_str);
726 tcc_debug_stabs(s1, debug_str.data, param ? N_PSYM : N_LSYM, s->c, NULL, 0);
728 cstr_free (&debug_str);
731 /* put function symbol */
732 static void tcc_debug_funcstart(TCCState *s1, Sym *sym)
734 CString debug_str;
735 BufferedFile *f;
736 if (!s1->do_debug)
737 return;
738 debug_info_root = NULL;
739 debug_info = NULL;
740 tcc_debug_stabn(s1, N_LBRAC, ind - func_ind);
741 if (!(f = put_new_file(s1)))
742 return;
743 cstr_new (&debug_str);
744 cstr_printf(&debug_str, "%s:%c", funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
745 tcc_get_debug_info(s1, sym->type.ref, &debug_str);
746 put_stabs_r(s1, debug_str.data, N_FUN, 0, f->line_num, 0, cur_text_section, sym->c);
747 cstr_free (&debug_str);
749 tcc_debug_line(s1);
752 /* put function size */
753 static void tcc_debug_funcend(TCCState *s1, int size)
755 if (!s1->do_debug)
756 return;
757 tcc_debug_stabn(s1, N_RBRAC, size);
758 tcc_debug_finish (s1, debug_info_root);
762 static void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bind, int sym_type)
764 Section *s;
765 CString str;
767 if (!s1->do_debug)
768 return;
769 if (sym_type == STT_FUNC || sym->v >= SYM_FIRST_ANOM)
770 return;
771 s = s1->sections[sh_num];
773 cstr_new (&str);
774 cstr_printf (&str, "%s:%c",
775 get_tok_str(sym->v, NULL),
776 sym_bind == STB_GLOBAL ? 'G' : local_scope ? 'V' : 'S'
778 tcc_get_debug_info(s1, sym, &str);
779 if (sym_bind == STB_GLOBAL)
780 tcc_debug_stabs(s1, str.data, N_GSYM, 0, NULL, 0);
781 else
782 tcc_debug_stabs(s1, str.data,
783 (sym->type.t & VT_STATIC) && data_section == s
784 ? N_STSYM : N_LCSYM, 0, s, sym->c);
785 cstr_free (&str);
788 static void tcc_debug_typedef(TCCState *s1, Sym *sym)
790 CString str;
792 if (!s1->do_debug)
793 return;
794 cstr_new (&str);
795 cstr_printf (&str, "%s:t",
796 (sym->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
797 ? "" : get_tok_str(sym->v & ~SYM_FIELD, NULL));
798 tcc_get_debug_info(s1, sym, &str);
799 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0);
800 cstr_free (&str);
803 /* ------------------------------------------------------------------------- */
804 /* for section layout see lib/tcov.c */
806 static void tcc_tcov_block_end(int line);
808 static void tcc_tcov_block_begin(void)
810 SValue sv;
811 void *ptr;
812 unsigned long last_offset = tcov_data.offset;
814 tcc_tcov_block_end (0);
815 if (tcc_state->test_coverage == 0 || nocode_wanted)
816 return;
818 if (tcov_data.last_file_name == 0 ||
819 strcmp ((const char *)(tcov_section->data + tcov_data.last_file_name),
820 file->true_filename) != 0) {
821 char wd[1024];
822 CString cstr;
824 if (tcov_data.last_func_name)
825 section_ptr_add(tcov_section, 1);
826 if (tcov_data.last_file_name)
827 section_ptr_add(tcov_section, 1);
828 tcov_data.last_func_name = 0;
829 cstr_new (&cstr);
830 if (file->true_filename[0] == '/') {
831 tcov_data.last_file_name = tcov_section->data_offset;
832 cstr_printf (&cstr, "%s", file->true_filename);
834 else {
835 getcwd (wd, sizeof(wd));
836 tcov_data.last_file_name = tcov_section->data_offset + strlen(wd) + 1;
837 cstr_printf (&cstr, "%s/%s", wd, file->true_filename);
839 ptr = section_ptr_add(tcov_section, cstr.size + 1);
840 strcpy((char *)ptr, cstr.data);
841 #ifdef _WIN32
842 normalize_slashes((char *)ptr);
843 #endif
844 cstr_free (&cstr);
846 if (tcov_data.last_func_name == 0 ||
847 strcmp ((const char *)(tcov_section->data + tcov_data.last_func_name),
848 funcname) != 0) {
849 size_t len;
851 if (tcov_data.last_func_name)
852 section_ptr_add(tcov_section, 1);
853 tcov_data.last_func_name = tcov_section->data_offset;
854 len = strlen (funcname);
855 ptr = section_ptr_add(tcov_section, len + 1);
856 strcpy((char *)ptr, funcname);
857 section_ptr_add(tcov_section, -tcov_section->data_offset & 7);
858 ptr = section_ptr_add(tcov_section, 8);
859 write64le (ptr, file->line_num);
861 if (ind == tcov_data.ind && tcov_data.line == file->line_num)
862 tcov_data.offset = last_offset;
863 else {
864 Sym label = {0};
865 label.type.t = VT_LLONG | VT_STATIC;
867 ptr = section_ptr_add(tcov_section, 16);
868 tcov_data.line = file->line_num;
869 write64le (ptr, (tcov_data.line << 8) | 0xff);
870 put_extern_sym(&label, tcov_section,
871 ((unsigned char *)ptr - tcov_section->data) + 8, 0);
872 sv.type = label.type;
873 sv.r = VT_SYM | VT_LVAL | VT_CONST;
874 sv.r2 = VT_CONST;
875 sv.c.i = 0;
876 sv.sym = &label;
877 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || \
878 defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 || \
879 defined TCC_TARGET_RISCV64
880 gen_increment_tcov (&sv);
881 #else
882 vpushv(&sv);
883 inc(0, TOK_INC);
884 vpop();
885 #endif
886 tcov_data.offset = (unsigned char *)ptr - tcov_section->data;
887 tcov_data.ind = ind;
891 static void tcc_tcov_block_end(int line)
893 if (tcc_state->test_coverage == 0)
894 return;
895 if (tcov_data.offset) {
896 void *ptr = tcov_section->data + tcov_data.offset;
897 unsigned long long nline = line ? line : file->line_num;
899 write64le (ptr, (read64le (ptr) & 0xfffffffffull) | (nline << 36));
900 tcov_data.offset = 0;
904 static void tcc_tcov_check_line(int start)
906 if (tcc_state->test_coverage == 0)
907 return;
908 if (tcov_data.line != file->line_num) {
909 if ((tcov_data.line + 1) != file->line_num) {
910 tcc_tcov_block_end (tcov_data.line);
911 if (start)
912 tcc_tcov_block_begin ();
914 else
915 tcov_data.line = file->line_num;
919 static void tcc_tcov_start(void)
921 if (tcc_state->test_coverage == 0)
922 return;
923 memset (&tcov_data, 0, sizeof (tcov_data));
924 if (tcov_section == NULL) {
925 tcov_section = new_section(tcc_state, ".tcov", SHT_PROGBITS,
926 SHF_ALLOC | SHF_WRITE);
927 section_ptr_add(tcov_section, 4); // pointer to executable name
931 static void tcc_tcov_end(void)
933 if (tcc_state->test_coverage == 0)
934 return;
935 if (tcov_data.last_func_name)
936 section_ptr_add(tcov_section, 1);
937 if (tcov_data.last_file_name)
938 section_ptr_add(tcov_section, 1);
941 /* ------------------------------------------------------------------------- */
942 /* initialize vstack and types. This must be done also for tcc -E */
943 ST_FUNC void tccgen_init(TCCState *s1)
945 vtop = vstack - 1;
946 memset(vtop, 0, sizeof *vtop);
948 /* define some often used types */
949 int_type.t = VT_INT;
951 char_type.t = VT_BYTE;
952 if (s1->char_is_unsigned)
953 char_type.t |= VT_UNSIGNED;
954 char_pointer_type = char_type;
955 mk_pointer(&char_pointer_type);
957 func_old_type.t = VT_FUNC;
958 func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);
959 func_old_type.ref->f.func_call = FUNC_CDECL;
960 func_old_type.ref->f.func_type = FUNC_OLD;
961 #ifdef precedence_parser
962 init_prec();
963 #endif
964 cstr_new(&initstr);
967 ST_FUNC int tccgen_compile(TCCState *s1)
969 cur_text_section = NULL;
970 funcname = "";
971 anon_sym = SYM_FIRST_ANOM;
972 section_sym = 0;
973 const_wanted = 0;
974 nocode_wanted = 0x80000000;
975 local_scope = 0;
976 debug_modes = s1->do_debug | s1->test_coverage << 1;
978 tcc_debug_start(s1);
979 tcc_tcov_start ();
980 #ifdef TCC_TARGET_ARM
981 arm_init(s1);
982 #endif
983 #ifdef INC_DEBUG
984 printf("%s: **** new file\n", file->filename);
985 #endif
986 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
987 next();
988 decl(VT_CONST);
989 gen_inline_functions(s1);
990 check_vstack();
991 /* end of translation unit info */
992 tcc_debug_end(s1);
993 tcc_tcov_end ();
994 return 0;
997 ST_FUNC void tccgen_finish(TCCState *s1)
999 cstr_free(&initstr);
1000 free_inline_functions(s1);
1001 sym_pop(&global_stack, NULL, 0);
1002 sym_pop(&local_stack, NULL, 0);
1003 /* free preprocessor macros */
1004 free_defines(NULL);
1005 /* free sym_pools */
1006 dynarray_reset(&sym_pools, &nb_sym_pools);
1007 sym_free_first = NULL;
1010 /* ------------------------------------------------------------------------- */
1011 ST_FUNC ElfSym *elfsym(Sym *s)
1013 if (!s || !s->c)
1014 return NULL;
1015 return &((ElfSym *)symtab_section->data)[s->c];
1018 /* apply storage attributes to Elf symbol */
1019 ST_FUNC void update_storage(Sym *sym)
1021 ElfSym *esym;
1022 int sym_bind, old_sym_bind;
1024 esym = elfsym(sym);
1025 if (!esym)
1026 return;
1028 if (sym->a.visibility)
1029 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
1030 | sym->a.visibility;
1032 if (sym->type.t & (VT_STATIC | VT_INLINE))
1033 sym_bind = STB_LOCAL;
1034 else if (sym->a.weak)
1035 sym_bind = STB_WEAK;
1036 else
1037 sym_bind = STB_GLOBAL;
1038 old_sym_bind = ELFW(ST_BIND)(esym->st_info);
1039 if (sym_bind != old_sym_bind) {
1040 esym->st_info = ELFW(ST_INFO)(sym_bind, ELFW(ST_TYPE)(esym->st_info));
1043 #ifdef TCC_TARGET_PE
1044 if (sym->a.dllimport)
1045 esym->st_other |= ST_PE_IMPORT;
1046 if (sym->a.dllexport)
1047 esym->st_other |= ST_PE_EXPORT;
1048 #endif
1050 #if 0
1051 printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n",
1052 get_tok_str(sym->v, NULL),
1053 sym_bind == STB_WEAK ? 'w' : sym_bind == STB_LOCAL ? 'l' : 'g',
1054 sym->a.visibility,
1055 sym->a.dllexport,
1056 sym->a.dllimport
1058 #endif
1061 /* ------------------------------------------------------------------------- */
1062 /* update sym->c so that it points to an external symbol in section
1063 'section' with value 'value' */
1065 ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
1066 addr_t value, unsigned long size,
1067 int can_add_underscore)
1069 int sym_type, sym_bind, info, other, t;
1070 ElfSym *esym;
1071 const char *name;
1072 char buf1[256];
1074 if (!sym->c) {
1075 name = get_tok_str(sym->v, NULL);
1076 t = sym->type.t;
1077 if ((t & VT_BTYPE) == VT_FUNC) {
1078 sym_type = STT_FUNC;
1079 } else if ((t & VT_BTYPE) == VT_VOID) {
1080 sym_type = STT_NOTYPE;
1081 if ((t & (VT_BTYPE|VT_ASM_FUNC)) == VT_ASM_FUNC)
1082 sym_type = STT_FUNC;
1083 } else {
1084 sym_type = STT_OBJECT;
1086 if (t & (VT_STATIC | VT_INLINE))
1087 sym_bind = STB_LOCAL;
1088 else
1089 sym_bind = STB_GLOBAL;
1090 other = 0;
1092 #ifdef TCC_TARGET_PE
1093 if (sym_type == STT_FUNC && sym->type.ref) {
1094 Sym *ref = sym->type.ref;
1095 if (ref->a.nodecorate) {
1096 can_add_underscore = 0;
1098 if (ref->f.func_call == FUNC_STDCALL && can_add_underscore) {
1099 sprintf(buf1, "_%s@%d", name, ref->f.func_args * PTR_SIZE);
1100 name = buf1;
1101 other |= ST_PE_STDCALL;
1102 can_add_underscore = 0;
1105 #endif
1107 if (sym->asm_label) {
1108 name = get_tok_str(sym->asm_label, NULL);
1109 can_add_underscore = 0;
1112 if (tcc_state->leading_underscore && can_add_underscore) {
1113 buf1[0] = '_';
1114 pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
1115 name = buf1;
1118 info = ELFW(ST_INFO)(sym_bind, sym_type);
1119 sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name);
1121 if (debug_modes)
1122 tcc_debug_extern_sym(tcc_state, sym, sh_num, sym_bind, sym_type);
1124 } else {
1125 esym = elfsym(sym);
1126 esym->st_value = value;
1127 esym->st_size = size;
1128 esym->st_shndx = sh_num;
1130 update_storage(sym);
1133 ST_FUNC void put_extern_sym(Sym *sym, Section *section,
1134 addr_t value, unsigned long size)
1136 int sh_num = section ? section->sh_num : SHN_UNDEF;
1137 put_extern_sym2(sym, sh_num, value, size, 1);
1140 /* add a new relocation entry to symbol 'sym' in section 's' */
1141 ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
1142 addr_t addend)
1144 int c = 0;
1146 if (nocode_wanted && s == cur_text_section)
1147 return;
1149 if (sym) {
1150 if (0 == sym->c)
1151 put_extern_sym(sym, NULL, 0, 0);
1152 c = sym->c;
1155 /* now we can add ELF relocation info */
1156 put_elf_reloca(symtab_section, s, offset, type, c, addend);
1159 #if PTR_SIZE == 4
1160 ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
1162 greloca(s, sym, offset, type, 0);
1164 #endif
1166 /* ------------------------------------------------------------------------- */
1167 /* symbol allocator */
1168 static Sym *__sym_malloc(void)
1170 Sym *sym_pool, *sym, *last_sym;
1171 int i;
1173 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
1174 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
1176 last_sym = sym_free_first;
1177 sym = sym_pool;
1178 for(i = 0; i < SYM_POOL_NB; i++) {
1179 sym->next = last_sym;
1180 last_sym = sym;
1181 sym++;
1183 sym_free_first = last_sym;
1184 return last_sym;
1187 static inline Sym *sym_malloc(void)
1189 Sym *sym;
1190 #ifndef SYM_DEBUG
1191 sym = sym_free_first;
1192 if (!sym)
1193 sym = __sym_malloc();
1194 sym_free_first = sym->next;
1195 return sym;
1196 #else
1197 sym = tcc_malloc(sizeof(Sym));
1198 return sym;
1199 #endif
1202 ST_INLN void sym_free(Sym *sym)
1204 #ifndef SYM_DEBUG
1205 sym->next = sym_free_first;
1206 sym_free_first = sym;
1207 #else
1208 tcc_free(sym);
1209 #endif
1212 /* push, without hashing */
1213 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c)
1215 Sym *s;
1217 s = sym_malloc();
1218 memset(s, 0, sizeof *s);
1219 s->v = v;
1220 s->type.t = t;
1221 s->c = c;
1222 /* add in stack */
1223 s->prev = *ps;
1224 *ps = s;
1225 return s;
1228 /* find a symbol and return its associated structure. 's' is the top
1229 of the symbol stack */
1230 ST_FUNC Sym *sym_find2(Sym *s, int v)
1232 while (s) {
1233 if (s->v == v)
1234 return s;
1235 else if (s->v == -1)
1236 return NULL;
1237 s = s->prev;
1239 return NULL;
1242 /* structure lookup */
1243 ST_INLN Sym *struct_find(int v)
1245 v -= TOK_IDENT;
1246 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1247 return NULL;
1248 return table_ident[v]->sym_struct;
1251 /* find an identifier */
1252 ST_INLN Sym *sym_find(int v)
1254 v -= TOK_IDENT;
1255 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1256 return NULL;
1257 return table_ident[v]->sym_identifier;
1260 static int sym_scope(Sym *s)
1262 if (IS_ENUM_VAL (s->type.t))
1263 return s->type.ref->sym_scope;
1264 else
1265 return s->sym_scope;
1268 /* push a given symbol on the symbol stack */
1269 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
1271 Sym *s, **ps;
1272 TokenSym *ts;
1274 if (local_stack)
1275 ps = &local_stack;
1276 else
1277 ps = &global_stack;
1278 s = sym_push2(ps, v, type->t, c);
1279 s->type.ref = type->ref;
1280 s->r = r;
1281 /* don't record fields or anonymous symbols */
1282 /* XXX: simplify */
1283 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1284 /* record symbol in token array */
1285 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1286 if (v & SYM_STRUCT)
1287 ps = &ts->sym_struct;
1288 else
1289 ps = &ts->sym_identifier;
1290 s->prev_tok = *ps;
1291 *ps = s;
1292 s->sym_scope = local_scope;
1293 if (s->prev_tok && sym_scope(s->prev_tok) == s->sym_scope)
1294 tcc_error("redeclaration of '%s'",
1295 get_tok_str(v & ~SYM_STRUCT, NULL));
1297 return s;
1300 /* push a global identifier */
1301 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
1303 Sym *s, **ps;
1304 s = sym_push2(&global_stack, v, t, c);
1305 s->r = VT_CONST | VT_SYM;
1306 /* don't record anonymous symbol */
1307 if (v < SYM_FIRST_ANOM) {
1308 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
1309 /* modify the top most local identifier, so that sym_identifier will
1310 point to 's' when popped; happens when called from inline asm */
1311 while (*ps != NULL && (*ps)->sym_scope)
1312 ps = &(*ps)->prev_tok;
1313 s->prev_tok = *ps;
1314 *ps = s;
1316 return s;
1319 /* pop symbols until top reaches 'b'. If KEEP is non-zero don't really
1320 pop them yet from the list, but do remove them from the token array. */
1321 ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep)
1323 Sym *s, *ss, **ps;
1324 TokenSym *ts;
1325 int v;
1327 s = *ptop;
1328 while(s != b) {
1329 ss = s->prev;
1330 v = s->v;
1331 /* remove symbol in token array */
1332 /* XXX: simplify */
1333 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1334 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1335 if (v & SYM_STRUCT)
1336 ps = &ts->sym_struct;
1337 else
1338 ps = &ts->sym_identifier;
1339 *ps = s->prev_tok;
1341 if (!keep)
1342 sym_free(s);
1343 s = ss;
1345 if (!keep)
1346 *ptop = b;
1349 /* ------------------------------------------------------------------------- */
1350 static void vcheck_cmp(void)
1352 /* cannot let cpu flags if other instruction are generated. Also
1353 avoid leaving VT_JMP anywhere except on the top of the stack
1354 because it would complicate the code generator.
1356 Don't do this when nocode_wanted. vtop might come from
1357 !nocode_wanted regions (see 88_codeopt.c) and transforming
1358 it to a register without actually generating code is wrong
1359 as their value might still be used for real. All values
1360 we push under nocode_wanted will eventually be popped
1361 again, so that the VT_CMP/VT_JMP value will be in vtop
1362 when code is unsuppressed again. */
1364 if (vtop->r == VT_CMP && !nocode_wanted)
1365 gv(RC_INT);
1368 static void vsetc(CType *type, int r, CValue *vc)
1370 if (vtop >= vstack + (VSTACK_SIZE - 1))
1371 tcc_error("memory full (vstack)");
1372 vcheck_cmp();
1373 vtop++;
1374 vtop->type = *type;
1375 vtop->r = r;
1376 vtop->r2 = VT_CONST;
1377 vtop->c = *vc;
1378 vtop->sym = NULL;
1381 ST_FUNC void vswap(void)
1383 SValue tmp;
1385 vcheck_cmp();
1386 tmp = vtop[0];
1387 vtop[0] = vtop[-1];
1388 vtop[-1] = tmp;
1391 /* pop stack value */
1392 ST_FUNC void vpop(void)
1394 int v;
1395 v = vtop->r & VT_VALMASK;
1396 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1397 /* for x86, we need to pop the FP stack */
1398 if (v == TREG_ST0) {
1399 o(0xd8dd); /* fstp %st(0) */
1400 } else
1401 #endif
1402 if (v == VT_CMP) {
1403 /* need to put correct jump if && or || without test */
1404 gsym(vtop->jtrue);
1405 gsym(vtop->jfalse);
1407 vtop--;
1410 /* push constant of type "type" with useless value */
1411 static void vpush(CType *type)
1413 vset(type, VT_CONST, 0);
1416 /* push arbitrary 64bit constant */
1417 static void vpush64(int ty, unsigned long long v)
1419 CValue cval;
1420 CType ctype;
1421 ctype.t = ty;
1422 ctype.ref = NULL;
1423 cval.i = v;
1424 vsetc(&ctype, VT_CONST, &cval);
1427 /* push integer constant */
1428 ST_FUNC void vpushi(int v)
1430 vpush64(VT_INT, v);
1433 /* push a pointer sized constant */
1434 static void vpushs(addr_t v)
1436 vpush64(VT_SIZE_T, v);
1439 /* push long long constant */
1440 static inline void vpushll(long long v)
1442 vpush64(VT_LLONG, v);
1445 ST_FUNC void vset(CType *type, int r, int v)
1447 CValue cval;
1448 cval.i = v;
1449 vsetc(type, r, &cval);
1452 static void vseti(int r, int v)
1454 CType type;
1455 type.t = VT_INT;
1456 type.ref = NULL;
1457 vset(&type, r, v);
1460 ST_FUNC void vpushv(SValue *v)
1462 if (vtop >= vstack + (VSTACK_SIZE - 1))
1463 tcc_error("memory full (vstack)");
1464 vtop++;
1465 *vtop = *v;
1468 static void vdup(void)
1470 vpushv(vtop);
1473 /* rotate n first stack elements to the bottom
1474 I1 ... In -> I2 ... In I1 [top is right]
1476 ST_FUNC void vrotb(int n)
1478 int i;
1479 SValue tmp;
1481 vcheck_cmp();
1482 tmp = vtop[-n + 1];
1483 for(i=-n+1;i!=0;i++)
1484 vtop[i] = vtop[i+1];
1485 vtop[0] = tmp;
1488 /* rotate the n elements before entry e towards the top
1489 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1491 ST_FUNC void vrote(SValue *e, int n)
1493 int i;
1494 SValue tmp;
1496 vcheck_cmp();
1497 tmp = *e;
1498 for(i = 0;i < n - 1; i++)
1499 e[-i] = e[-i - 1];
1500 e[-n + 1] = tmp;
1503 /* rotate n first stack elements to the top
1504 I1 ... In -> In I1 ... I(n-1) [top is right]
1506 ST_FUNC void vrott(int n)
1508 vrote(vtop, n);
1511 /* ------------------------------------------------------------------------- */
1512 /* vtop->r = VT_CMP means CPU-flags have been set from comparison or test. */
1514 /* called from generators to set the result from relational ops */
1515 ST_FUNC void vset_VT_CMP(int op)
1517 vtop->r = VT_CMP;
1518 vtop->cmp_op = op;
1519 vtop->jfalse = 0;
1520 vtop->jtrue = 0;
1523 /* called once before asking generators to load VT_CMP to a register */
1524 static void vset_VT_JMP(void)
1526 int op = vtop->cmp_op;
1528 if (vtop->jtrue || vtop->jfalse) {
1529 /* we need to jump to 'mov $0,%R' or 'mov $1,%R' */
1530 int inv = op & (op < 2); /* small optimization */
1531 vseti(VT_JMP+inv, gvtst(inv, 0));
1532 } else {
1533 /* otherwise convert flags (rsp. 0/1) to register */
1534 vtop->c.i = op;
1535 if (op < 2) /* doesn't seem to happen */
1536 vtop->r = VT_CONST;
1540 /* Set CPU Flags, doesn't yet jump */
1541 static void gvtst_set(int inv, int t)
1543 int *p;
1545 if (vtop->r != VT_CMP) {
1546 vpushi(0);
1547 gen_op(TOK_NE);
1548 if (vtop->r != VT_CMP) /* must be VT_CONST then */
1549 vset_VT_CMP(vtop->c.i != 0);
1552 p = inv ? &vtop->jfalse : &vtop->jtrue;
1553 *p = gjmp_append(*p, t);
1556 /* Generate value test
1558 * Generate a test for any value (jump, comparison and integers) */
1559 static int gvtst(int inv, int t)
1561 int op, x, u;
1563 gvtst_set(inv, t);
1564 t = vtop->jtrue, u = vtop->jfalse;
1565 if (inv)
1566 x = u, u = t, t = x;
1567 op = vtop->cmp_op;
1569 /* jump to the wanted target */
1570 if (op > 1)
1571 t = gjmp_cond(op ^ inv, t);
1572 else if (op != inv)
1573 t = gjmp(t);
1574 /* resolve complementary jumps to here */
1575 gsym(u);
1577 vtop--;
1578 return t;
1581 /* generate a zero or nozero test */
1582 static void gen_test_zero(int op)
1584 if (vtop->r == VT_CMP) {
1585 int j;
1586 if (op == TOK_EQ) {
1587 j = vtop->jfalse;
1588 vtop->jfalse = vtop->jtrue;
1589 vtop->jtrue = j;
1590 vtop->cmp_op ^= 1;
1592 } else {
1593 vpushi(0);
1594 gen_op(op);
1598 /* ------------------------------------------------------------------------- */
1599 /* push a symbol value of TYPE */
1600 ST_FUNC void vpushsym(CType *type, Sym *sym)
1602 CValue cval;
1603 cval.i = 0;
1604 vsetc(type, VT_CONST | VT_SYM, &cval);
1605 vtop->sym = sym;
1608 /* Return a static symbol pointing to a section */
1609 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
1611 int v;
1612 Sym *sym;
1614 v = anon_sym++;
1615 sym = sym_push(v, type, VT_CONST | VT_SYM, 0);
1616 sym->type.t |= VT_STATIC;
1617 put_extern_sym(sym, sec, offset, size);
1618 return sym;
1621 /* push a reference to a section offset by adding a dummy symbol */
1622 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
1624 vpushsym(type, get_sym_ref(type, sec, offset, size));
1627 /* define a new external reference to a symbol 'v' of type 'u' */
1628 ST_FUNC Sym *external_global_sym(int v, CType *type)
1630 Sym *s;
1632 s = sym_find(v);
1633 if (!s) {
1634 /* push forward reference */
1635 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
1636 s->type.ref = type->ref;
1637 } else if (IS_ASM_SYM(s)) {
1638 s->type.t = type->t | (s->type.t & VT_EXTERN);
1639 s->type.ref = type->ref;
1640 update_storage(s);
1642 return s;
1645 /* create an external reference with no specific type similar to asm labels.
1646 This avoids type conflicts if the symbol is used from C too */
1647 ST_FUNC Sym *external_helper_sym(int v)
1649 CType ct = { VT_ASM_FUNC, NULL };
1650 return external_global_sym(v, &ct);
1653 /* push a reference to an helper function (such as memmove) */
1654 ST_FUNC void vpush_helper_func(int v)
1656 vpushsym(&func_old_type, external_helper_sym(v));
1659 /* Merge symbol attributes. */
1660 static void merge_symattr(struct SymAttr *sa, struct SymAttr *sa1)
1662 if (sa1->aligned && !sa->aligned)
1663 sa->aligned = sa1->aligned;
1664 sa->packed |= sa1->packed;
1665 sa->weak |= sa1->weak;
1666 if (sa1->visibility != STV_DEFAULT) {
1667 int vis = sa->visibility;
1668 if (vis == STV_DEFAULT
1669 || vis > sa1->visibility)
1670 vis = sa1->visibility;
1671 sa->visibility = vis;
1673 sa->dllexport |= sa1->dllexport;
1674 sa->nodecorate |= sa1->nodecorate;
1675 sa->dllimport |= sa1->dllimport;
1678 /* Merge function attributes. */
1679 static void merge_funcattr(struct FuncAttr *fa, struct FuncAttr *fa1)
1681 if (fa1->func_call && !fa->func_call)
1682 fa->func_call = fa1->func_call;
1683 if (fa1->func_type && !fa->func_type)
1684 fa->func_type = fa1->func_type;
1685 if (fa1->func_args && !fa->func_args)
1686 fa->func_args = fa1->func_args;
1687 if (fa1->func_noreturn)
1688 fa->func_noreturn = 1;
1689 if (fa1->func_ctor)
1690 fa->func_ctor = 1;
1691 if (fa1->func_dtor)
1692 fa->func_dtor = 1;
1695 /* Merge attributes. */
1696 static void merge_attr(AttributeDef *ad, AttributeDef *ad1)
1698 merge_symattr(&ad->a, &ad1->a);
1699 merge_funcattr(&ad->f, &ad1->f);
1701 if (ad1->section)
1702 ad->section = ad1->section;
1703 if (ad1->alias_target)
1704 ad->alias_target = ad1->alias_target;
1705 if (ad1->asm_label)
1706 ad->asm_label = ad1->asm_label;
1707 if (ad1->attr_mode)
1708 ad->attr_mode = ad1->attr_mode;
1711 /* Merge some type attributes. */
1712 static void patch_type(Sym *sym, CType *type)
1714 if (!(type->t & VT_EXTERN) || IS_ENUM_VAL(sym->type.t)) {
1715 if (!(sym->type.t & VT_EXTERN))
1716 tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL));
1717 sym->type.t &= ~VT_EXTERN;
1720 if (IS_ASM_SYM(sym)) {
1721 /* stay static if both are static */
1722 sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
1723 sym->type.ref = type->ref;
1726 if (!is_compatible_types(&sym->type, type)) {
1727 tcc_error("incompatible types for redefinition of '%s'",
1728 get_tok_str(sym->v, NULL));
1730 } else if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
1731 int static_proto = sym->type.t & VT_STATIC;
1732 /* warn if static follows non-static function declaration */
1733 if ((type->t & VT_STATIC) && !static_proto
1734 /* XXX this test for inline shouldn't be here. Until we
1735 implement gnu-inline mode again it silences a warning for
1736 mingw caused by our workarounds. */
1737 && !((type->t | sym->type.t) & VT_INLINE))
1738 tcc_warning("static storage ignored for redefinition of '%s'",
1739 get_tok_str(sym->v, NULL));
1741 /* set 'inline' if both agree or if one has static */
1742 if ((type->t | sym->type.t) & VT_INLINE) {
1743 if (!((type->t ^ sym->type.t) & VT_INLINE)
1744 || ((type->t | sym->type.t) & VT_STATIC))
1745 static_proto |= VT_INLINE;
1748 if (0 == (type->t & VT_EXTERN)) {
1749 struct FuncAttr f = sym->type.ref->f;
1750 /* put complete type, use static from prototype */
1751 sym->type.t = (type->t & ~(VT_STATIC|VT_INLINE)) | static_proto;
1752 sym->type.ref = type->ref;
1753 merge_funcattr(&sym->type.ref->f, &f);
1754 } else {
1755 sym->type.t &= ~VT_INLINE | static_proto;
1758 if (sym->type.ref->f.func_type == FUNC_OLD
1759 && type->ref->f.func_type != FUNC_OLD) {
1760 sym->type.ref = type->ref;
1763 } else {
1764 if ((sym->type.t & VT_ARRAY) && type->ref->c >= 0) {
1765 /* set array size if it was omitted in extern declaration */
1766 sym->type.ref->c = type->ref->c;
1768 if ((type->t ^ sym->type.t) & VT_STATIC)
1769 tcc_warning("storage mismatch for redefinition of '%s'",
1770 get_tok_str(sym->v, NULL));
1774 /* Merge some storage attributes. */
1775 static void patch_storage(Sym *sym, AttributeDef *ad, CType *type)
1777 if (type)
1778 patch_type(sym, type);
1780 #ifdef TCC_TARGET_PE
1781 if (sym->a.dllimport != ad->a.dllimport)
1782 tcc_error("incompatible dll linkage for redefinition of '%s'",
1783 get_tok_str(sym->v, NULL));
1784 #endif
1785 merge_symattr(&sym->a, &ad->a);
1786 if (ad->asm_label)
1787 sym->asm_label = ad->asm_label;
1788 update_storage(sym);
1791 /* copy sym to other stack */
1792 static Sym *sym_copy(Sym *s0, Sym **ps)
1794 Sym *s;
1795 s = sym_malloc(), *s = *s0;
1796 s->prev = *ps, *ps = s;
1797 if (s->v < SYM_FIRST_ANOM) {
1798 ps = &table_ident[s->v - TOK_IDENT]->sym_identifier;
1799 s->prev_tok = *ps, *ps = s;
1801 return s;
1804 /* copy s->type.ref to stack 'ps' for VT_FUNC and VT_PTR */
1805 static void sym_copy_ref(Sym *s, Sym **ps)
1807 int bt = s->type.t & VT_BTYPE;
1808 if (bt == VT_FUNC || bt == VT_PTR || (bt == VT_STRUCT && s->sym_scope)) {
1809 Sym **sp = &s->type.ref;
1810 for (s = *sp, *sp = NULL; s; s = s->next) {
1811 Sym *s2 = sym_copy(s, ps);
1812 sp = &(*sp = s2)->next;
1813 sym_copy_ref(s2, ps);
1818 /* define a new external reference to a symbol 'v' */
1819 static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad)
1821 Sym *s;
1823 /* look for global symbol */
1824 s = sym_find(v);
1825 while (s && s->sym_scope)
1826 s = s->prev_tok;
1828 if (!s) {
1829 /* push forward reference */
1830 s = global_identifier_push(v, type->t, 0);
1831 s->r |= r;
1832 s->a = ad->a;
1833 s->asm_label = ad->asm_label;
1834 s->type.ref = type->ref;
1835 /* copy type to the global stack */
1836 if (local_stack)
1837 sym_copy_ref(s, &global_stack);
1838 } else {
1839 patch_storage(s, ad, type);
1841 /* push variables on local_stack if any */
1842 if (local_stack && (s->type.t & VT_BTYPE) != VT_FUNC)
1843 s = sym_copy(s, &local_stack);
1844 return s;
1847 /* save registers up to (vtop - n) stack entry */
1848 ST_FUNC void save_regs(int n)
1850 SValue *p, *p1;
1851 for(p = vstack, p1 = vtop - n; p <= p1; p++)
1852 save_reg(p->r);
1855 /* save r to the memory stack, and mark it as being free */
1856 ST_FUNC void save_reg(int r)
1858 save_reg_upstack(r, 0);
1861 /* save r to the memory stack, and mark it as being free,
1862 if seen up to (vtop - n) stack entry */
1863 ST_FUNC void save_reg_upstack(int r, int n)
1865 int l, size, align, bt;
1866 SValue *p, *p1, sv;
1868 if ((r &= VT_VALMASK) >= VT_CONST)
1869 return;
1870 if (nocode_wanted)
1871 return;
1872 l = 0;
1873 for(p = vstack, p1 = vtop - n; p <= p1; p++) {
1874 if ((p->r & VT_VALMASK) == r || p->r2 == r) {
1875 /* must save value on stack if not already done */
1876 if (!l) {
1877 bt = p->type.t & VT_BTYPE;
1878 if (bt == VT_VOID)
1879 continue;
1880 if ((p->r & VT_LVAL) || bt == VT_FUNC)
1881 bt = VT_PTR;
1882 sv.type.t = bt;
1883 size = type_size(&sv.type, &align);
1884 l = get_temp_local_var(size,align);
1885 sv.r = VT_LOCAL | VT_LVAL;
1886 sv.c.i = l;
1887 store(p->r & VT_VALMASK, &sv);
1888 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1889 /* x86 specific: need to pop fp register ST0 if saved */
1890 if (r == TREG_ST0) {
1891 o(0xd8dd); /* fstp %st(0) */
1893 #endif
1894 /* special long long case */
1895 if (p->r2 < VT_CONST && USING_TWO_WORDS(bt)) {
1896 sv.c.i += PTR_SIZE;
1897 store(p->r2, &sv);
1900 /* mark that stack entry as being saved on the stack */
1901 if (p->r & VT_LVAL) {
1902 /* also clear the bounded flag because the
1903 relocation address of the function was stored in
1904 p->c.i */
1905 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
1906 } else {
1907 p->r = VT_LVAL | VT_LOCAL;
1909 p->sym = NULL;
1910 p->r2 = VT_CONST;
1911 p->c.i = l;
1916 #ifdef TCC_TARGET_ARM
1917 /* find a register of class 'rc2' with at most one reference on stack.
1918 * If none, call get_reg(rc) */
1919 ST_FUNC int get_reg_ex(int rc, int rc2)
1921 int r;
1922 SValue *p;
1924 for(r=0;r<NB_REGS;r++) {
1925 if (reg_classes[r] & rc2) {
1926 int n;
1927 n=0;
1928 for(p = vstack; p <= vtop; p++) {
1929 if ((p->r & VT_VALMASK) == r ||
1930 p->r2 == r)
1931 n++;
1933 if (n <= 1)
1934 return r;
1937 return get_reg(rc);
1939 #endif
1941 /* find a free register of class 'rc'. If none, save one register */
1942 ST_FUNC int get_reg(int rc)
1944 int r;
1945 SValue *p;
1947 /* find a free register */
1948 for(r=0;r<NB_REGS;r++) {
1949 if (reg_classes[r] & rc) {
1950 if (nocode_wanted)
1951 return r;
1952 for(p=vstack;p<=vtop;p++) {
1953 if ((p->r & VT_VALMASK) == r ||
1954 p->r2 == r)
1955 goto notfound;
1957 return r;
1959 notfound: ;
1962 /* no register left : free the first one on the stack (VERY
1963 IMPORTANT to start from the bottom to ensure that we don't
1964 spill registers used in gen_opi()) */
1965 for(p=vstack;p<=vtop;p++) {
1966 /* look at second register (if long long) */
1967 r = p->r2;
1968 if (r < VT_CONST && (reg_classes[r] & rc))
1969 goto save_found;
1970 r = p->r & VT_VALMASK;
1971 if (r < VT_CONST && (reg_classes[r] & rc)) {
1972 save_found:
1973 save_reg(r);
1974 return r;
1977 /* Should never comes here */
1978 return -1;
1981 /* find a free temporary local variable (return the offset on stack) match the size and align. If none, add new temporary stack variable*/
1982 static int get_temp_local_var(int size,int align){
1983 int i;
1984 struct temp_local_variable *temp_var;
1985 int found_var;
1986 SValue *p;
1987 int r;
1988 char free;
1989 char found;
1990 found=0;
1991 for(i=0;i<nb_temp_local_vars;i++){
1992 temp_var=&arr_temp_local_vars[i];
1993 if(temp_var->size<size||align!=temp_var->align){
1994 continue;
1996 /*check if temp_var is free*/
1997 free=1;
1998 for(p=vstack;p<=vtop;p++) {
1999 r=p->r&VT_VALMASK;
2000 if(r==VT_LOCAL||r==VT_LLOCAL){
2001 if(p->c.i==temp_var->location){
2002 free=0;
2003 break;
2007 if(free){
2008 found_var=temp_var->location;
2009 found=1;
2010 break;
2013 if(!found){
2014 loc = (loc - size) & -align;
2015 if(nb_temp_local_vars<MAX_TEMP_LOCAL_VARIABLE_NUMBER){
2016 temp_var=&arr_temp_local_vars[i];
2017 temp_var->location=loc;
2018 temp_var->size=size;
2019 temp_var->align=align;
2020 nb_temp_local_vars++;
2022 found_var=loc;
2024 return found_var;
2027 static void clear_temp_local_var_list(){
2028 nb_temp_local_vars=0;
2031 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
2032 if needed */
2033 static void move_reg(int r, int s, int t)
2035 SValue sv;
2037 if (r != s) {
2038 save_reg(r);
2039 sv.type.t = t;
2040 sv.type.ref = NULL;
2041 sv.r = s;
2042 sv.c.i = 0;
2043 load(r, &sv);
2047 /* get address of vtop (vtop MUST BE an lvalue) */
2048 ST_FUNC void gaddrof(void)
2050 vtop->r &= ~VT_LVAL;
2051 /* tricky: if saved lvalue, then we can go back to lvalue */
2052 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
2053 vtop->r = (vtop->r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
2056 #ifdef CONFIG_TCC_BCHECK
2057 /* generate a bounded pointer addition */
2058 static void gen_bounded_ptr_add(void)
2060 int save = (vtop[-1].r & VT_VALMASK) == VT_LOCAL;
2061 if (save) {
2062 vpushv(&vtop[-1]);
2063 vrott(3);
2065 vpush_helper_func(TOK___bound_ptr_add);
2066 vrott(3);
2067 gfunc_call(2);
2068 vtop -= save;
2069 vpushi(0);
2070 /* returned pointer is in REG_IRET */
2071 vtop->r = REG_IRET | VT_BOUNDED;
2072 if (nocode_wanted)
2073 return;
2074 /* relocation offset of the bounding function call point */
2075 vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(ElfW_Rel));
2078 /* patch pointer addition in vtop so that pointer dereferencing is
2079 also tested */
2080 static void gen_bounded_ptr_deref(void)
2082 addr_t func;
2083 int size, align;
2084 ElfW_Rel *rel;
2085 Sym *sym;
2087 if (nocode_wanted)
2088 return;
2090 size = type_size(&vtop->type, &align);
2091 switch(size) {
2092 case 1: func = TOK___bound_ptr_indir1; break;
2093 case 2: func = TOK___bound_ptr_indir2; break;
2094 case 4: func = TOK___bound_ptr_indir4; break;
2095 case 8: func = TOK___bound_ptr_indir8; break;
2096 case 12: func = TOK___bound_ptr_indir12; break;
2097 case 16: func = TOK___bound_ptr_indir16; break;
2098 default:
2099 /* may happen with struct member access */
2100 return;
2102 sym = external_helper_sym(func);
2103 if (!sym->c)
2104 put_extern_sym(sym, NULL, 0, 0);
2105 /* patch relocation */
2106 /* XXX: find a better solution ? */
2107 rel = (ElfW_Rel *)(cur_text_section->reloc->data + vtop->c.i);
2108 rel->r_info = ELFW(R_INFO)(sym->c, ELFW(R_TYPE)(rel->r_info));
2111 /* generate lvalue bound code */
2112 static void gbound(void)
2114 CType type1;
2116 vtop->r &= ~VT_MUSTBOUND;
2117 /* if lvalue, then use checking code before dereferencing */
2118 if (vtop->r & VT_LVAL) {
2119 /* if not VT_BOUNDED value, then make one */
2120 if (!(vtop->r & VT_BOUNDED)) {
2121 /* must save type because we must set it to int to get pointer */
2122 type1 = vtop->type;
2123 vtop->type.t = VT_PTR;
2124 gaddrof();
2125 vpushi(0);
2126 gen_bounded_ptr_add();
2127 vtop->r |= VT_LVAL;
2128 vtop->type = type1;
2130 /* then check for dereferencing */
2131 gen_bounded_ptr_deref();
2135 /* we need to call __bound_ptr_add before we start to load function
2136 args into registers */
2137 ST_FUNC void gbound_args(int nb_args)
2139 int i, v;
2140 SValue *sv;
2142 for (i = 1; i <= nb_args; ++i)
2143 if (vtop[1 - i].r & VT_MUSTBOUND) {
2144 vrotb(i);
2145 gbound();
2146 vrott(i);
2149 sv = vtop - nb_args;
2150 if (sv->r & VT_SYM) {
2151 v = sv->sym->v;
2152 if (v == TOK_setjmp
2153 || v == TOK__setjmp
2154 #ifndef TCC_TARGET_PE
2155 || v == TOK_sigsetjmp
2156 || v == TOK___sigsetjmp
2157 #endif
2159 vpush_helper_func(TOK___bound_setjmp);
2160 vpushv(sv + 1);
2161 gfunc_call(1);
2162 func_bound_add_epilog = 1;
2164 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
2165 if (v == TOK_alloca)
2166 func_bound_add_epilog = 1;
2167 #endif
2168 #if TARGETOS_NetBSD
2169 if (v == TOK_longjmp) /* undo rename to __longjmp14 */
2170 sv->sym->asm_label = TOK___bound_longjmp;
2171 #endif
2175 /* Add bounds for local symbols from S to E (via ->prev) */
2176 static void add_local_bounds(Sym *s, Sym *e)
2178 for (; s != e; s = s->prev) {
2179 if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL)
2180 continue;
2181 /* Add arrays/structs/unions because we always take address */
2182 if ((s->type.t & VT_ARRAY)
2183 || (s->type.t & VT_BTYPE) == VT_STRUCT
2184 || s->a.addrtaken) {
2185 /* add local bound info */
2186 int align, size = type_size(&s->type, &align);
2187 addr_t *bounds_ptr = section_ptr_add(lbounds_section,
2188 2 * sizeof(addr_t));
2189 bounds_ptr[0] = s->c;
2190 bounds_ptr[1] = size;
2194 #endif
2196 /* Wrapper around sym_pop, that potentially also registers local bounds. */
2197 static void pop_local_syms(Sym *b, int keep)
2199 #ifdef CONFIG_TCC_BCHECK
2200 if (tcc_state->do_bounds_check && !keep && (local_scope || !func_var))
2201 add_local_bounds(local_stack, b);
2202 #endif
2203 if (debug_modes)
2204 tcc_add_debug_info (tcc_state, !local_scope, local_stack, b);
2205 sym_pop(&local_stack, b, keep);
2208 static void incr_bf_adr(int o)
2210 vtop->type = char_pointer_type;
2211 gaddrof();
2212 vpushs(o);
2213 gen_op('+');
2214 vtop->type.t = VT_BYTE | VT_UNSIGNED;
2215 vtop->r |= VT_LVAL;
2218 /* single-byte load mode for packed or otherwise unaligned bitfields */
2219 static void load_packed_bf(CType *type, int bit_pos, int bit_size)
2221 int n, o, bits;
2222 save_reg_upstack(vtop->r, 1);
2223 vpush64(type->t & VT_BTYPE, 0); // B X
2224 bits = 0, o = bit_pos >> 3, bit_pos &= 7;
2225 do {
2226 vswap(); // X B
2227 incr_bf_adr(o);
2228 vdup(); // X B B
2229 n = 8 - bit_pos;
2230 if (n > bit_size)
2231 n = bit_size;
2232 if (bit_pos)
2233 vpushi(bit_pos), gen_op(TOK_SHR), bit_pos = 0; // X B Y
2234 if (n < 8)
2235 vpushi((1 << n) - 1), gen_op('&');
2236 gen_cast(type);
2237 if (bits)
2238 vpushi(bits), gen_op(TOK_SHL);
2239 vrotb(3); // B Y X
2240 gen_op('|'); // B X
2241 bits += n, bit_size -= n, o = 1;
2242 } while (bit_size);
2243 vswap(), vpop();
2244 if (!(type->t & VT_UNSIGNED)) {
2245 n = ((type->t & VT_BTYPE) == VT_LLONG ? 64 : 32) - bits;
2246 vpushi(n), gen_op(TOK_SHL);
2247 vpushi(n), gen_op(TOK_SAR);
2251 /* single-byte store mode for packed or otherwise unaligned bitfields */
2252 static void store_packed_bf(int bit_pos, int bit_size)
2254 int bits, n, o, m, c;
2255 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2256 vswap(); // X B
2257 save_reg_upstack(vtop->r, 1);
2258 bits = 0, o = bit_pos >> 3, bit_pos &= 7;
2259 do {
2260 incr_bf_adr(o); // X B
2261 vswap(); //B X
2262 c ? vdup() : gv_dup(); // B V X
2263 vrott(3); // X B V
2264 if (bits)
2265 vpushi(bits), gen_op(TOK_SHR);
2266 if (bit_pos)
2267 vpushi(bit_pos), gen_op(TOK_SHL);
2268 n = 8 - bit_pos;
2269 if (n > bit_size)
2270 n = bit_size;
2271 if (n < 8) {
2272 m = ((1 << n) - 1) << bit_pos;
2273 vpushi(m), gen_op('&'); // X B V1
2274 vpushv(vtop-1); // X B V1 B
2275 vpushi(m & 0x80 ? ~m & 0x7f : ~m);
2276 gen_op('&'); // X B V1 B1
2277 gen_op('|'); // X B V2
2279 vdup(), vtop[-1] = vtop[-2]; // X B B V2
2280 vstore(), vpop(); // X B
2281 bits += n, bit_size -= n, bit_pos = 0, o = 1;
2282 } while (bit_size);
2283 vpop(), vpop();
2286 static int adjust_bf(SValue *sv, int bit_pos, int bit_size)
2288 int t;
2289 if (0 == sv->type.ref)
2290 return 0;
2291 t = sv->type.ref->auxtype;
2292 if (t != -1 && t != VT_STRUCT) {
2293 sv->type.t = (sv->type.t & ~(VT_BTYPE | VT_LONG)) | t;
2294 sv->r |= VT_LVAL;
2296 return t;
2299 /* store vtop a register belonging to class 'rc'. lvalues are
2300 converted to values. Cannot be used if cannot be converted to
2301 register value (such as structures). */
2302 ST_FUNC int gv(int rc)
2304 int r, r2, r_ok, r2_ok, rc2, bt;
2305 int bit_pos, bit_size, size, align;
2307 /* NOTE: get_reg can modify vstack[] */
2308 if (vtop->type.t & VT_BITFIELD) {
2309 CType type;
2311 bit_pos = BIT_POS(vtop->type.t);
2312 bit_size = BIT_SIZE(vtop->type.t);
2313 /* remove bit field info to avoid loops */
2314 vtop->type.t &= ~VT_STRUCT_MASK;
2316 type.ref = NULL;
2317 type.t = vtop->type.t & VT_UNSIGNED;
2318 if ((vtop->type.t & VT_BTYPE) == VT_BOOL)
2319 type.t |= VT_UNSIGNED;
2321 r = adjust_bf(vtop, bit_pos, bit_size);
2323 if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
2324 type.t |= VT_LLONG;
2325 else
2326 type.t |= VT_INT;
2328 if (r == VT_STRUCT) {
2329 load_packed_bf(&type, bit_pos, bit_size);
2330 } else {
2331 int bits = (type.t & VT_BTYPE) == VT_LLONG ? 64 : 32;
2332 /* cast to int to propagate signedness in following ops */
2333 gen_cast(&type);
2334 /* generate shifts */
2335 vpushi(bits - (bit_pos + bit_size));
2336 gen_op(TOK_SHL);
2337 vpushi(bits - bit_size);
2338 /* NOTE: transformed to SHR if unsigned */
2339 gen_op(TOK_SAR);
2341 r = gv(rc);
2342 } else {
2343 if (is_float(vtop->type.t) &&
2344 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2345 /* CPUs usually cannot use float constants, so we store them
2346 generically in data segment */
2347 init_params p = { rodata_section };
2348 unsigned long offset;
2349 size = type_size(&vtop->type, &align);
2350 if (NODATA_WANTED)
2351 size = 0, align = 1;
2352 offset = section_add(p.sec, size, align);
2353 vpush_ref(&vtop->type, p.sec, offset, size);
2354 vswap();
2355 init_putv(&p, &vtop->type, offset);
2356 vtop->r |= VT_LVAL;
2358 #ifdef CONFIG_TCC_BCHECK
2359 if (vtop->r & VT_MUSTBOUND)
2360 gbound();
2361 #endif
2363 bt = vtop->type.t & VT_BTYPE;
2365 #ifdef TCC_TARGET_RISCV64
2366 /* XXX mega hack */
2367 if (bt == VT_LDOUBLE && rc == RC_FLOAT)
2368 rc = RC_INT;
2369 #endif
2370 rc2 = RC2_TYPE(bt, rc);
2372 /* need to reload if:
2373 - constant
2374 - lvalue (need to dereference pointer)
2375 - already a register, but not in the right class */
2376 r = vtop->r & VT_VALMASK;
2377 r_ok = !(vtop->r & VT_LVAL) && (r < VT_CONST) && (reg_classes[r] & rc);
2378 r2_ok = !rc2 || ((vtop->r2 < VT_CONST) && (reg_classes[vtop->r2] & rc2));
2380 if (!r_ok || !r2_ok) {
2381 if (!r_ok)
2382 r = get_reg(rc);
2383 if (rc2) {
2384 int load_type = (bt == VT_QFLOAT) ? VT_DOUBLE : VT_PTRDIFF_T;
2385 int original_type = vtop->type.t;
2387 /* two register type load :
2388 expand to two words temporarily */
2389 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2390 /* load constant */
2391 unsigned long long ll = vtop->c.i;
2392 vtop->c.i = ll; /* first word */
2393 load(r, vtop);
2394 vtop->r = r; /* save register value */
2395 vpushi(ll >> 32); /* second word */
2396 } else if (vtop->r & VT_LVAL) {
2397 /* We do not want to modifier the long long pointer here.
2398 So we save any other instances down the stack */
2399 save_reg_upstack(vtop->r, 1);
2400 /* load from memory */
2401 vtop->type.t = load_type;
2402 load(r, vtop);
2403 vdup();
2404 vtop[-1].r = r; /* save register value */
2405 /* increment pointer to get second word */
2406 vtop->type.t = VT_PTRDIFF_T;
2407 gaddrof();
2408 vpushs(PTR_SIZE);
2409 gen_op('+');
2410 vtop->r |= VT_LVAL;
2411 vtop->type.t = load_type;
2412 } else {
2413 /* move registers */
2414 if (!r_ok)
2415 load(r, vtop);
2416 if (r2_ok && vtop->r2 < VT_CONST)
2417 goto done;
2418 vdup();
2419 vtop[-1].r = r; /* save register value */
2420 vtop->r = vtop[-1].r2;
2422 /* Allocate second register. Here we rely on the fact that
2423 get_reg() tries first to free r2 of an SValue. */
2424 r2 = get_reg(rc2);
2425 load(r2, vtop);
2426 vpop();
2427 /* write second register */
2428 vtop->r2 = r2;
2429 done:
2430 vtop->type.t = original_type;
2431 } else {
2432 if (vtop->r == VT_CMP)
2433 vset_VT_JMP();
2434 /* one register type load */
2435 load(r, vtop);
2438 vtop->r = r;
2439 #ifdef TCC_TARGET_C67
2440 /* uses register pairs for doubles */
2441 if (bt == VT_DOUBLE)
2442 vtop->r2 = r+1;
2443 #endif
2445 return r;
2448 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2449 ST_FUNC void gv2(int rc1, int rc2)
2451 /* generate more generic register first. But VT_JMP or VT_CMP
2452 values must be generated first in all cases to avoid possible
2453 reload errors */
2454 if (vtop->r != VT_CMP && rc1 <= rc2) {
2455 vswap();
2456 gv(rc1);
2457 vswap();
2458 gv(rc2);
2459 /* test if reload is needed for first register */
2460 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2461 vswap();
2462 gv(rc1);
2463 vswap();
2465 } else {
2466 gv(rc2);
2467 vswap();
2468 gv(rc1);
2469 vswap();
2470 /* test if reload is needed for first register */
2471 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
2472 gv(rc2);
2477 #if PTR_SIZE == 4
2478 /* expand 64bit on stack in two ints */
2479 ST_FUNC void lexpand(void)
2481 int u, v;
2482 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
2483 v = vtop->r & (VT_VALMASK | VT_LVAL);
2484 if (v == VT_CONST) {
2485 vdup();
2486 vtop[0].c.i >>= 32;
2487 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
2488 vdup();
2489 vtop[0].c.i += 4;
2490 } else {
2491 gv(RC_INT);
2492 vdup();
2493 vtop[0].r = vtop[-1].r2;
2494 vtop[0].r2 = vtop[-1].r2 = VT_CONST;
2496 vtop[0].type.t = vtop[-1].type.t = VT_INT | u;
2498 #endif
2500 #if PTR_SIZE == 4
2501 /* build a long long from two ints */
2502 static void lbuild(int t)
2504 gv2(RC_INT, RC_INT);
2505 vtop[-1].r2 = vtop[0].r;
2506 vtop[-1].type.t = t;
2507 vpop();
2509 #endif
2511 /* convert stack entry to register and duplicate its value in another
2512 register */
2513 static void gv_dup(void)
2515 int t, rc, r;
2517 t = vtop->type.t;
2518 #if PTR_SIZE == 4
2519 if ((t & VT_BTYPE) == VT_LLONG) {
2520 if (t & VT_BITFIELD) {
2521 gv(RC_INT);
2522 t = vtop->type.t;
2524 lexpand();
2525 gv_dup();
2526 vswap();
2527 vrotb(3);
2528 gv_dup();
2529 vrotb(4);
2530 /* stack: H L L1 H1 */
2531 lbuild(t);
2532 vrotb(3);
2533 vrotb(3);
2534 vswap();
2535 lbuild(t);
2536 vswap();
2537 return;
2539 #endif
2540 /* duplicate value */
2541 rc = RC_TYPE(t);
2542 gv(rc);
2543 r = get_reg(rc);
2544 vdup();
2545 load(r, vtop);
2546 vtop->r = r;
2549 #if PTR_SIZE == 4
2550 /* generate CPU independent (unsigned) long long operations */
2551 static void gen_opl(int op)
2553 int t, a, b, op1, c, i;
2554 int func;
2555 unsigned short reg_iret = REG_IRET;
2556 unsigned short reg_lret = REG_IRE2;
2557 SValue tmp;
2559 switch(op) {
2560 case '/':
2561 case TOK_PDIV:
2562 func = TOK___divdi3;
2563 goto gen_func;
2564 case TOK_UDIV:
2565 func = TOK___udivdi3;
2566 goto gen_func;
2567 case '%':
2568 func = TOK___moddi3;
2569 goto gen_mod_func;
2570 case TOK_UMOD:
2571 func = TOK___umoddi3;
2572 gen_mod_func:
2573 #ifdef TCC_ARM_EABI
2574 reg_iret = TREG_R2;
2575 reg_lret = TREG_R3;
2576 #endif
2577 gen_func:
2578 /* call generic long long function */
2579 vpush_helper_func(func);
2580 vrott(3);
2581 gfunc_call(2);
2582 vpushi(0);
2583 vtop->r = reg_iret;
2584 vtop->r2 = reg_lret;
2585 break;
2586 case '^':
2587 case '&':
2588 case '|':
2589 case '*':
2590 case '+':
2591 case '-':
2592 //pv("gen_opl A",0,2);
2593 t = vtop->type.t;
2594 vswap();
2595 lexpand();
2596 vrotb(3);
2597 lexpand();
2598 /* stack: L1 H1 L2 H2 */
2599 tmp = vtop[0];
2600 vtop[0] = vtop[-3];
2601 vtop[-3] = tmp;
2602 tmp = vtop[-2];
2603 vtop[-2] = vtop[-3];
2604 vtop[-3] = tmp;
2605 vswap();
2606 /* stack: H1 H2 L1 L2 */
2607 //pv("gen_opl B",0,4);
2608 if (op == '*') {
2609 vpushv(vtop - 1);
2610 vpushv(vtop - 1);
2611 gen_op(TOK_UMULL);
2612 lexpand();
2613 /* stack: H1 H2 L1 L2 ML MH */
2614 for(i=0;i<4;i++)
2615 vrotb(6);
2616 /* stack: ML MH H1 H2 L1 L2 */
2617 tmp = vtop[0];
2618 vtop[0] = vtop[-2];
2619 vtop[-2] = tmp;
2620 /* stack: ML MH H1 L2 H2 L1 */
2621 gen_op('*');
2622 vrotb(3);
2623 vrotb(3);
2624 gen_op('*');
2625 /* stack: ML MH M1 M2 */
2626 gen_op('+');
2627 gen_op('+');
2628 } else if (op == '+' || op == '-') {
2629 /* XXX: add non carry method too (for MIPS or alpha) */
2630 if (op == '+')
2631 op1 = TOK_ADDC1;
2632 else
2633 op1 = TOK_SUBC1;
2634 gen_op(op1);
2635 /* stack: H1 H2 (L1 op L2) */
2636 vrotb(3);
2637 vrotb(3);
2638 gen_op(op1 + 1); /* TOK_xxxC2 */
2639 } else {
2640 gen_op(op);
2641 /* stack: H1 H2 (L1 op L2) */
2642 vrotb(3);
2643 vrotb(3);
2644 /* stack: (L1 op L2) H1 H2 */
2645 gen_op(op);
2646 /* stack: (L1 op L2) (H1 op H2) */
2648 /* stack: L H */
2649 lbuild(t);
2650 break;
2651 case TOK_SAR:
2652 case TOK_SHR:
2653 case TOK_SHL:
2654 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
2655 t = vtop[-1].type.t;
2656 vswap();
2657 lexpand();
2658 vrotb(3);
2659 /* stack: L H shift */
2660 c = (int)vtop->c.i;
2661 /* constant: simpler */
2662 /* NOTE: all comments are for SHL. the other cases are
2663 done by swapping words */
2664 vpop();
2665 if (op != TOK_SHL)
2666 vswap();
2667 if (c >= 32) {
2668 /* stack: L H */
2669 vpop();
2670 if (c > 32) {
2671 vpushi(c - 32);
2672 gen_op(op);
2674 if (op != TOK_SAR) {
2675 vpushi(0);
2676 } else {
2677 gv_dup();
2678 vpushi(31);
2679 gen_op(TOK_SAR);
2681 vswap();
2682 } else {
2683 vswap();
2684 gv_dup();
2685 /* stack: H L L */
2686 vpushi(c);
2687 gen_op(op);
2688 vswap();
2689 vpushi(32 - c);
2690 if (op == TOK_SHL)
2691 gen_op(TOK_SHR);
2692 else
2693 gen_op(TOK_SHL);
2694 vrotb(3);
2695 /* stack: L L H */
2696 vpushi(c);
2697 if (op == TOK_SHL)
2698 gen_op(TOK_SHL);
2699 else
2700 gen_op(TOK_SHR);
2701 gen_op('|');
2703 if (op != TOK_SHL)
2704 vswap();
2705 lbuild(t);
2706 } else {
2707 /* XXX: should provide a faster fallback on x86 ? */
2708 switch(op) {
2709 case TOK_SAR:
2710 func = TOK___ashrdi3;
2711 goto gen_func;
2712 case TOK_SHR:
2713 func = TOK___lshrdi3;
2714 goto gen_func;
2715 case TOK_SHL:
2716 func = TOK___ashldi3;
2717 goto gen_func;
2720 break;
2721 default:
2722 /* compare operations */
2723 t = vtop->type.t;
2724 vswap();
2725 lexpand();
2726 vrotb(3);
2727 lexpand();
2728 /* stack: L1 H1 L2 H2 */
2729 tmp = vtop[-1];
2730 vtop[-1] = vtop[-2];
2731 vtop[-2] = tmp;
2732 /* stack: L1 L2 H1 H2 */
2733 save_regs(4);
2734 /* compare high */
2735 op1 = op;
2736 /* when values are equal, we need to compare low words. since
2737 the jump is inverted, we invert the test too. */
2738 if (op1 == TOK_LT)
2739 op1 = TOK_LE;
2740 else if (op1 == TOK_GT)
2741 op1 = TOK_GE;
2742 else if (op1 == TOK_ULT)
2743 op1 = TOK_ULE;
2744 else if (op1 == TOK_UGT)
2745 op1 = TOK_UGE;
2746 a = 0;
2747 b = 0;
2748 gen_op(op1);
2749 if (op == TOK_NE) {
2750 b = gvtst(0, 0);
2751 } else {
2752 a = gvtst(1, 0);
2753 if (op != TOK_EQ) {
2754 /* generate non equal test */
2755 vpushi(0);
2756 vset_VT_CMP(TOK_NE);
2757 b = gvtst(0, 0);
2760 /* compare low. Always unsigned */
2761 op1 = op;
2762 if (op1 == TOK_LT)
2763 op1 = TOK_ULT;
2764 else if (op1 == TOK_LE)
2765 op1 = TOK_ULE;
2766 else if (op1 == TOK_GT)
2767 op1 = TOK_UGT;
2768 else if (op1 == TOK_GE)
2769 op1 = TOK_UGE;
2770 gen_op(op1);
2771 #if 0//def TCC_TARGET_I386
2772 if (op == TOK_NE) { gsym(b); break; }
2773 if (op == TOK_EQ) { gsym(a); break; }
2774 #endif
2775 gvtst_set(1, a);
2776 gvtst_set(0, b);
2777 break;
2780 #endif
2782 static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
2784 uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
2785 return (a ^ b) >> 63 ? -x : x;
2788 static int gen_opic_lt(uint64_t a, uint64_t b)
2790 return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
2793 /* handle integer constant optimizations and various machine
2794 independent opt */
2795 static void gen_opic(int op)
2797 SValue *v1 = vtop - 1;
2798 SValue *v2 = vtop;
2799 int t1 = v1->type.t & VT_BTYPE;
2800 int t2 = v2->type.t & VT_BTYPE;
2801 int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2802 int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2803 uint64_t l1 = c1 ? v1->c.i : 0;
2804 uint64_t l2 = c2 ? v2->c.i : 0;
2805 int shm = (t1 == VT_LLONG) ? 63 : 31;
2807 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
2808 l1 = ((uint32_t)l1 |
2809 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
2810 if (t2 != VT_LLONG && (PTR_SIZE != 8 || t2 != VT_PTR))
2811 l2 = ((uint32_t)l2 |
2812 (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
2814 if (c1 && c2) {
2815 switch(op) {
2816 case '+': l1 += l2; break;
2817 case '-': l1 -= l2; break;
2818 case '&': l1 &= l2; break;
2819 case '^': l1 ^= l2; break;
2820 case '|': l1 |= l2; break;
2821 case '*': l1 *= l2; break;
2823 case TOK_PDIV:
2824 case '/':
2825 case '%':
2826 case TOK_UDIV:
2827 case TOK_UMOD:
2828 /* if division by zero, generate explicit division */
2829 if (l2 == 0) {
2830 if (const_wanted && !(nocode_wanted & unevalmask))
2831 tcc_error("division by zero in constant");
2832 goto general_case;
2834 switch(op) {
2835 default: l1 = gen_opic_sdiv(l1, l2); break;
2836 case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
2837 case TOK_UDIV: l1 = l1 / l2; break;
2838 case TOK_UMOD: l1 = l1 % l2; break;
2840 break;
2841 case TOK_SHL: l1 <<= (l2 & shm); break;
2842 case TOK_SHR: l1 >>= (l2 & shm); break;
2843 case TOK_SAR:
2844 l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
2845 break;
2846 /* tests */
2847 case TOK_ULT: l1 = l1 < l2; break;
2848 case TOK_UGE: l1 = l1 >= l2; break;
2849 case TOK_EQ: l1 = l1 == l2; break;
2850 case TOK_NE: l1 = l1 != l2; break;
2851 case TOK_ULE: l1 = l1 <= l2; break;
2852 case TOK_UGT: l1 = l1 > l2; break;
2853 case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
2854 case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
2855 case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
2856 case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
2857 /* logical */
2858 case TOK_LAND: l1 = l1 && l2; break;
2859 case TOK_LOR: l1 = l1 || l2; break;
2860 default:
2861 goto general_case;
2863 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
2864 l1 = ((uint32_t)l1 |
2865 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
2866 v1->c.i = l1;
2867 vtop--;
2868 } else {
2869 /* if commutative ops, put c2 as constant */
2870 if (c1 && (op == '+' || op == '&' || op == '^' ||
2871 op == '|' || op == '*' || op == TOK_EQ || op == TOK_NE)) {
2872 vswap();
2873 c2 = c1; //c = c1, c1 = c2, c2 = c;
2874 l2 = l1; //l = l1, l1 = l2, l2 = l;
2876 if (!const_wanted &&
2877 c1 && ((l1 == 0 &&
2878 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
2879 (l1 == -1 && op == TOK_SAR))) {
2880 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
2881 vtop--;
2882 } else if (!const_wanted &&
2883 c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
2884 (op == '|' &&
2885 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||
2886 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
2887 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
2888 if (l2 == 1)
2889 vtop->c.i = 0;
2890 vswap();
2891 vtop--;
2892 } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
2893 op == TOK_PDIV) &&
2894 l2 == 1) ||
2895 ((op == '+' || op == '-' || op == '|' || op == '^' ||
2896 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
2897 l2 == 0) ||
2898 (op == '&' &&
2899 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {
2900 /* filter out NOP operations like x*1, x-0, x&-1... */
2901 vtop--;
2902 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
2903 /* try to use shifts instead of muls or divs */
2904 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
2905 int n = -1;
2906 while (l2) {
2907 l2 >>= 1;
2908 n++;
2910 vtop->c.i = n;
2911 if (op == '*')
2912 op = TOK_SHL;
2913 else if (op == TOK_PDIV)
2914 op = TOK_SAR;
2915 else
2916 op = TOK_SHR;
2918 goto general_case;
2919 } else if (c2 && (op == '+' || op == '-') &&
2920 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
2921 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
2922 /* symbol + constant case */
2923 if (op == '-')
2924 l2 = -l2;
2925 l2 += vtop[-1].c.i;
2926 /* The backends can't always deal with addends to symbols
2927 larger than +-1<<31. Don't construct such. */
2928 if ((int)l2 != l2)
2929 goto general_case;
2930 vtop--;
2931 vtop->c.i = l2;
2932 } else {
2933 general_case:
2934 /* call low level op generator */
2935 if (t1 == VT_LLONG || t2 == VT_LLONG ||
2936 (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
2937 gen_opl(op);
2938 else
2939 gen_opi(op);
2944 #if defined TCC_TARGET_X86_64 || defined TCC_TARGET_I386
2945 # define gen_negf gen_opf
2946 #elif defined TCC_TARGET_ARM
2947 void gen_negf(int op)
2949 /* arm will detect 0-x and replace by vneg */
2950 vpushi(0), vswap(), gen_op('-');
2952 #else
2953 /* XXX: implement in gen_opf() for other backends too */
2954 void gen_negf(int op)
2956 /* In IEEE negate(x) isn't subtract(0,x). Without NaNs it's
2957 subtract(-0, x), but with them it's really a sign flip
2958 operation. We implement this with bit manipulation and have
2959 to do some type reinterpretation for this, which TCC can do
2960 only via memory. */
2962 int align, size, bt;
2964 size = type_size(&vtop->type, &align);
2965 bt = vtop->type.t & VT_BTYPE;
2966 save_reg(gv(RC_TYPE(bt)));
2967 vdup();
2968 incr_bf_adr(size - 1);
2969 vdup();
2970 vpushi(0x80); /* flip sign */
2971 gen_op('^');
2972 vstore();
2973 vpop();
2975 #endif
2977 /* generate a floating point operation with constant propagation */
2978 static void gen_opif(int op)
2980 int c1, c2;
2981 SValue *v1, *v2;
2982 #if defined _MSC_VER && defined __x86_64__
2983 /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
2984 volatile
2985 #endif
2986 long double f1, f2;
2988 v1 = vtop - 1;
2989 v2 = vtop;
2990 if (op == TOK_NEG)
2991 v1 = v2;
2993 /* currently, we cannot do computations with forward symbols */
2994 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2995 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2996 if (c1 && c2) {
2997 if (v1->type.t == VT_FLOAT) {
2998 f1 = v1->c.f;
2999 f2 = v2->c.f;
3000 } else if (v1->type.t == VT_DOUBLE) {
3001 f1 = v1->c.d;
3002 f2 = v2->c.d;
3003 } else {
3004 f1 = v1->c.ld;
3005 f2 = v2->c.ld;
3007 /* NOTE: we only do constant propagation if finite number (not
3008 NaN or infinity) (ANSI spec) */
3009 if (!(ieee_finite(f1) || !ieee_finite(f2)) && !const_wanted)
3010 goto general_case;
3011 switch(op) {
3012 case '+': f1 += f2; break;
3013 case '-': f1 -= f2; break;
3014 case '*': f1 *= f2; break;
3015 case '/':
3016 if (f2 == 0.0) {
3017 union { float f; unsigned u; } x1, x2, y;
3018 /* If not in initializer we need to potentially generate
3019 FP exceptions at runtime, otherwise we want to fold. */
3020 if (!const_wanted)
3021 goto general_case;
3022 /* the run-time result of 0.0/0.0 on x87, also of other compilers
3023 when used to compile the f1 /= f2 below, would be -nan */
3024 x1.f = f1, x2.f = f2;
3025 if (f1 == 0.0)
3026 y.u = 0x7fc00000; /* nan */
3027 else
3028 y.u = 0x7f800000; /* infinity */
3029 y.u |= (x1.u ^ x2.u) & 0x80000000; /* set sign */
3030 f1 = y.f;
3031 break;
3033 f1 /= f2;
3034 break;
3035 case TOK_NEG:
3036 f1 = -f1;
3037 goto unary_result;
3038 /* XXX: also handles tests ? */
3039 default:
3040 goto general_case;
3042 vtop--;
3043 unary_result:
3044 /* XXX: overflow test ? */
3045 if (v1->type.t == VT_FLOAT) {
3046 v1->c.f = f1;
3047 } else if (v1->type.t == VT_DOUBLE) {
3048 v1->c.d = f1;
3049 } else {
3050 v1->c.ld = f1;
3052 } else {
3053 general_case:
3054 if (op == TOK_NEG) {
3055 gen_negf(op);
3056 } else {
3057 gen_opf(op);
3062 /* print a type. If 'varstr' is not NULL, then the variable is also
3063 printed in the type */
3064 /* XXX: union */
3065 /* XXX: add array and function pointers */
3066 static void type_to_str(char *buf, int buf_size,
3067 CType *type, const char *varstr)
3069 int bt, v, t;
3070 Sym *s, *sa;
3071 char buf1[256];
3072 const char *tstr;
3074 t = type->t;
3075 bt = t & VT_BTYPE;
3076 buf[0] = '\0';
3078 if (t & VT_EXTERN)
3079 pstrcat(buf, buf_size, "extern ");
3080 if (t & VT_STATIC)
3081 pstrcat(buf, buf_size, "static ");
3082 if (t & VT_TYPEDEF)
3083 pstrcat(buf, buf_size, "typedef ");
3084 if (t & VT_INLINE)
3085 pstrcat(buf, buf_size, "inline ");
3086 if (bt != VT_PTR) {
3087 if (t & VT_VOLATILE)
3088 pstrcat(buf, buf_size, "volatile ");
3089 if (t & VT_CONSTANT)
3090 pstrcat(buf, buf_size, "const ");
3092 if (((t & VT_DEFSIGN) && bt == VT_BYTE)
3093 || ((t & VT_UNSIGNED)
3094 && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
3095 && !IS_ENUM(t)
3097 pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed ");
3099 buf_size -= strlen(buf);
3100 buf += strlen(buf);
3102 switch(bt) {
3103 case VT_VOID:
3104 tstr = "void";
3105 goto add_tstr;
3106 case VT_BOOL:
3107 tstr = "_Bool";
3108 goto add_tstr;
3109 case VT_BYTE:
3110 tstr = "char";
3111 goto add_tstr;
3112 case VT_SHORT:
3113 tstr = "short";
3114 goto add_tstr;
3115 case VT_INT:
3116 tstr = "int";
3117 goto maybe_long;
3118 case VT_LLONG:
3119 tstr = "long long";
3120 maybe_long:
3121 if (t & VT_LONG)
3122 tstr = "long";
3123 if (!IS_ENUM(t))
3124 goto add_tstr;
3125 tstr = "enum ";
3126 goto tstruct;
3127 case VT_FLOAT:
3128 tstr = "float";
3129 goto add_tstr;
3130 case VT_DOUBLE:
3131 tstr = "double";
3132 if (!(t & VT_LONG))
3133 goto add_tstr;
3134 case VT_LDOUBLE:
3135 tstr = "long double";
3136 add_tstr:
3137 pstrcat(buf, buf_size, tstr);
3138 break;
3139 case VT_STRUCT:
3140 tstr = "struct ";
3141 if (IS_UNION(t))
3142 tstr = "union ";
3143 tstruct:
3144 pstrcat(buf, buf_size, tstr);
3145 v = type->ref->v & ~SYM_STRUCT;
3146 if (v >= SYM_FIRST_ANOM)
3147 pstrcat(buf, buf_size, "<anonymous>");
3148 else
3149 pstrcat(buf, buf_size, get_tok_str(v, NULL));
3150 break;
3151 case VT_FUNC:
3152 s = type->ref;
3153 buf1[0]=0;
3154 if (varstr && '*' == *varstr) {
3155 pstrcat(buf1, sizeof(buf1), "(");
3156 pstrcat(buf1, sizeof(buf1), varstr);
3157 pstrcat(buf1, sizeof(buf1), ")");
3159 pstrcat(buf1, buf_size, "(");
3160 sa = s->next;
3161 while (sa != NULL) {
3162 char buf2[256];
3163 type_to_str(buf2, sizeof(buf2), &sa->type, NULL);
3164 pstrcat(buf1, sizeof(buf1), buf2);
3165 sa = sa->next;
3166 if (sa)
3167 pstrcat(buf1, sizeof(buf1), ", ");
3169 if (s->f.func_type == FUNC_ELLIPSIS)
3170 pstrcat(buf1, sizeof(buf1), ", ...");
3171 pstrcat(buf1, sizeof(buf1), ")");
3172 type_to_str(buf, buf_size, &s->type, buf1);
3173 goto no_var;
3174 case VT_PTR:
3175 s = type->ref;
3176 if (t & (VT_ARRAY|VT_VLA)) {
3177 if (varstr && '*' == *varstr)
3178 snprintf(buf1, sizeof(buf1), "(%s)[%d]", varstr, s->c);
3179 else
3180 snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c);
3181 type_to_str(buf, buf_size, &s->type, buf1);
3182 goto no_var;
3184 pstrcpy(buf1, sizeof(buf1), "*");
3185 if (t & VT_CONSTANT)
3186 pstrcat(buf1, buf_size, "const ");
3187 if (t & VT_VOLATILE)
3188 pstrcat(buf1, buf_size, "volatile ");
3189 if (varstr)
3190 pstrcat(buf1, sizeof(buf1), varstr);
3191 type_to_str(buf, buf_size, &s->type, buf1);
3192 goto no_var;
3194 if (varstr) {
3195 pstrcat(buf, buf_size, " ");
3196 pstrcat(buf, buf_size, varstr);
3198 no_var: ;
3201 static void type_incompatibility_error(CType* st, CType* dt, const char* fmt)
3203 char buf1[256], buf2[256];
3204 type_to_str(buf1, sizeof(buf1), st, NULL);
3205 type_to_str(buf2, sizeof(buf2), dt, NULL);
3206 tcc_error(fmt, buf1, buf2);
3209 static void type_incompatibility_warning(CType* st, CType* dt, const char* fmt)
3211 char buf1[256], buf2[256];
3212 type_to_str(buf1, sizeof(buf1), st, NULL);
3213 type_to_str(buf2, sizeof(buf2), dt, NULL);
3214 tcc_warning(fmt, buf1, buf2);
3217 static int pointed_size(CType *type)
3219 int align;
3220 return type_size(pointed_type(type), &align);
3223 static inline int is_null_pointer(SValue *p)
3225 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
3226 return 0;
3227 return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
3228 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
3229 ((p->type.t & VT_BTYPE) == VT_PTR &&
3230 (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0) &&
3231 ((pointed_type(&p->type)->t & VT_BTYPE) == VT_VOID) &&
3232 0 == (pointed_type(&p->type)->t & (VT_CONSTANT | VT_VOLATILE))
3236 /* compare function types. OLD functions match any new functions */
3237 static int is_compatible_func(CType *type1, CType *type2)
3239 Sym *s1, *s2;
3241 s1 = type1->ref;
3242 s2 = type2->ref;
3243 if (s1->f.func_call != s2->f.func_call)
3244 return 0;
3245 if (s1->f.func_type != s2->f.func_type
3246 && s1->f.func_type != FUNC_OLD
3247 && s2->f.func_type != FUNC_OLD)
3248 return 0;
3249 for (;;) {
3250 if (!is_compatible_unqualified_types(&s1->type, &s2->type))
3251 return 0;
3252 if (s1->f.func_type == FUNC_OLD || s2->f.func_type == FUNC_OLD )
3253 return 1;
3254 s1 = s1->next;
3255 s2 = s2->next;
3256 if (!s1)
3257 return !s2;
3258 if (!s2)
3259 return 0;
3263 /* return true if type1 and type2 are the same. If unqualified is
3264 true, qualifiers on the types are ignored.
3266 static int compare_types(CType *type1, CType *type2, int unqualified)
3268 int bt1, t1, t2;
3270 t1 = type1->t & VT_TYPE;
3271 t2 = type2->t & VT_TYPE;
3272 if (unqualified) {
3273 /* strip qualifiers before comparing */
3274 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
3275 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
3278 /* Default Vs explicit signedness only matters for char */
3279 if ((t1 & VT_BTYPE) != VT_BYTE) {
3280 t1 &= ~VT_DEFSIGN;
3281 t2 &= ~VT_DEFSIGN;
3283 /* XXX: bitfields ? */
3284 if (t1 != t2)
3285 return 0;
3287 if ((t1 & VT_ARRAY)
3288 && !(type1->ref->c < 0
3289 || type2->ref->c < 0
3290 || type1->ref->c == type2->ref->c))
3291 return 0;
3293 /* test more complicated cases */
3294 bt1 = t1 & VT_BTYPE;
3295 if (bt1 == VT_PTR) {
3296 type1 = pointed_type(type1);
3297 type2 = pointed_type(type2);
3298 return is_compatible_types(type1, type2);
3299 } else if (bt1 == VT_STRUCT) {
3300 return (type1->ref == type2->ref);
3301 } else if (bt1 == VT_FUNC) {
3302 return is_compatible_func(type1, type2);
3303 } else if (IS_ENUM(type1->t) && IS_ENUM(type2->t)) {
3304 /* If both are enums then they must be the same, if only one is then
3305 t1 and t2 must be equal, which was checked above already. */
3306 return type1->ref == type2->ref;
3307 } else {
3308 return 1;
3312 /* Check if OP1 and OP2 can be "combined" with operation OP, the combined
3313 type is stored in DEST if non-null (except for pointer plus/minus) . */
3314 static int combine_types(CType *dest, SValue *op1, SValue *op2, int op)
3316 CType *type1 = &op1->type, *type2 = &op2->type, type;
3317 int t1 = type1->t, t2 = type2->t, bt1 = t1 & VT_BTYPE, bt2 = t2 & VT_BTYPE;
3318 int ret = 1;
3320 type.t = VT_VOID;
3321 type.ref = NULL;
3323 if (bt1 == VT_VOID || bt2 == VT_VOID) {
3324 ret = op == '?' ? 1 : 0;
3325 /* NOTE: as an extension, we accept void on only one side */
3326 type.t = VT_VOID;
3327 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
3328 if (op == '+') ; /* Handled in caller */
3329 /* http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6 */
3330 /* If one is a null ptr constant the result type is the other. */
3331 else if (is_null_pointer (op2)) type = *type1;
3332 else if (is_null_pointer (op1)) type = *type2;
3333 else if (bt1 != bt2) {
3334 /* accept comparison or cond-expr between pointer and integer
3335 with a warning */
3336 if ((op == '?' || TOK_ISCOND(op))
3337 && (is_integer_btype(bt1) || is_integer_btype(bt2)))
3338 tcc_warning("pointer/integer mismatch in %s",
3339 op == '?' ? "conditional expression" : "comparison");
3340 else if (op != '-' || !is_integer_btype(bt2))
3341 ret = 0;
3342 type = *(bt1 == VT_PTR ? type1 : type2);
3343 } else {
3344 CType *pt1 = pointed_type(type1);
3345 CType *pt2 = pointed_type(type2);
3346 int pbt1 = pt1->t & VT_BTYPE;
3347 int pbt2 = pt2->t & VT_BTYPE;
3348 int newquals, copied = 0;
3349 if (pbt1 != VT_VOID && pbt2 != VT_VOID
3350 && !compare_types(pt1, pt2, 1/*unqualif*/)) {
3351 if (op != '?' && !TOK_ISCOND(op))
3352 ret = 0;
3353 else
3354 type_incompatibility_warning(type1, type2,
3355 op == '?'
3356 ? "pointer type mismatch in conditional expression ('%s' and '%s')"
3357 : "pointer type mismatch in comparison('%s' and '%s')");
3359 if (op == '?') {
3360 /* pointers to void get preferred, otherwise the
3361 pointed to types minus qualifs should be compatible */
3362 type = *((pbt1 == VT_VOID) ? type1 : type2);
3363 /* combine qualifs */
3364 newquals = ((pt1->t | pt2->t) & (VT_CONSTANT | VT_VOLATILE));
3365 if ((~pointed_type(&type)->t & (VT_CONSTANT | VT_VOLATILE))
3366 & newquals)
3368 /* copy the pointer target symbol */
3369 type.ref = sym_push(SYM_FIELD, &type.ref->type,
3370 0, type.ref->c);
3371 copied = 1;
3372 pointed_type(&type)->t |= newquals;
3374 /* pointers to incomplete arrays get converted to
3375 pointers to completed ones if possible */
3376 if (pt1->t & VT_ARRAY
3377 && pt2->t & VT_ARRAY
3378 && pointed_type(&type)->ref->c < 0
3379 && (pt1->ref->c > 0 || pt2->ref->c > 0))
3381 if (!copied)
3382 type.ref = sym_push(SYM_FIELD, &type.ref->type,
3383 0, type.ref->c);
3384 pointed_type(&type)->ref =
3385 sym_push(SYM_FIELD, &pointed_type(&type)->ref->type,
3386 0, pointed_type(&type)->ref->c);
3387 pointed_type(&type)->ref->c =
3388 0 < pt1->ref->c ? pt1->ref->c : pt2->ref->c;
3392 if (TOK_ISCOND(op))
3393 type.t = VT_SIZE_T;
3394 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
3395 if (op != '?' || !compare_types(type1, type2, 1))
3396 ret = 0;
3397 type = *type1;
3398 } else if (is_float(bt1) || is_float(bt2)) {
3399 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3400 type.t = VT_LDOUBLE;
3401 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3402 type.t = VT_DOUBLE;
3403 } else {
3404 type.t = VT_FLOAT;
3406 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3407 /* cast to biggest op */
3408 type.t = VT_LLONG | VT_LONG;
3409 if (bt1 == VT_LLONG)
3410 type.t &= t1;
3411 if (bt2 == VT_LLONG)
3412 type.t &= t2;
3413 /* convert to unsigned if it does not fit in a long long */
3414 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
3415 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
3416 type.t |= VT_UNSIGNED;
3417 } else {
3418 /* integer operations */
3419 type.t = VT_INT | (VT_LONG & (t1 | t2));
3420 /* convert to unsigned if it does not fit in an integer */
3421 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
3422 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
3423 type.t |= VT_UNSIGNED;
3425 if (dest)
3426 *dest = type;
3427 return ret;
3430 /* generic gen_op: handles types problems */
3431 ST_FUNC void gen_op(int op)
3433 int t1, t2, bt1, bt2, t;
3434 CType type1, combtype;
3436 redo:
3437 t1 = vtop[-1].type.t;
3438 t2 = vtop[0].type.t;
3439 bt1 = t1 & VT_BTYPE;
3440 bt2 = t2 & VT_BTYPE;
3442 if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
3443 if (bt2 == VT_FUNC) {
3444 mk_pointer(&vtop->type);
3445 gaddrof();
3447 if (bt1 == VT_FUNC) {
3448 vswap();
3449 mk_pointer(&vtop->type);
3450 gaddrof();
3451 vswap();
3453 goto redo;
3454 } else if (!combine_types(&combtype, vtop - 1, vtop, op)) {
3455 tcc_error_noabort("invalid operand types for binary operation");
3456 vpop();
3457 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
3458 /* at least one operand is a pointer */
3459 /* relational op: must be both pointers */
3460 int align;
3461 if (TOK_ISCOND(op))
3462 goto std_op;
3463 /* if both pointers, then it must be the '-' op */
3464 if (bt1 == VT_PTR && bt2 == VT_PTR) {
3465 if (op != '-')
3466 tcc_error("cannot use pointers here");
3467 vpush_type_size(pointed_type(&vtop[-1].type), &align);
3468 vrott(3);
3469 gen_opic(op);
3470 vtop->type.t = VT_PTRDIFF_T;
3471 vswap();
3472 gen_op(TOK_PDIV);
3473 } else {
3474 /* exactly one pointer : must be '+' or '-'. */
3475 if (op != '-' && op != '+')
3476 tcc_error("cannot use pointers here");
3477 /* Put pointer as first operand */
3478 if (bt2 == VT_PTR) {
3479 vswap();
3480 t = t1, t1 = t2, t2 = t;
3482 #if PTR_SIZE == 4
3483 if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG)
3484 /* XXX: truncate here because gen_opl can't handle ptr + long long */
3485 gen_cast_s(VT_INT);
3486 #endif
3487 type1 = vtop[-1].type;
3488 vpush_type_size(pointed_type(&vtop[-1].type), &align);
3489 gen_op('*');
3490 #ifdef CONFIG_TCC_BCHECK
3491 if (tcc_state->do_bounds_check && !const_wanted) {
3492 /* if bounded pointers, we generate a special code to
3493 test bounds */
3494 if (op == '-') {
3495 vpushi(0);
3496 vswap();
3497 gen_op('-');
3499 gen_bounded_ptr_add();
3500 } else
3501 #endif
3503 gen_opic(op);
3505 type1.t &= ~(VT_ARRAY|VT_VLA);
3506 /* put again type if gen_opic() swaped operands */
3507 vtop->type = type1;
3509 } else {
3510 /* floats can only be used for a few operations */
3511 if (is_float(combtype.t)
3512 && op != '+' && op != '-' && op != '*' && op != '/'
3513 && !TOK_ISCOND(op))
3514 tcc_error("invalid operands for binary operation");
3515 else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
3516 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
3517 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))
3518 t |= VT_UNSIGNED;
3519 t |= (VT_LONG & t1);
3520 combtype.t = t;
3522 std_op:
3523 t = t2 = combtype.t;
3524 /* XXX: currently, some unsigned operations are explicit, so
3525 we modify them here */
3526 if (t & VT_UNSIGNED) {
3527 if (op == TOK_SAR)
3528 op = TOK_SHR;
3529 else if (op == '/')
3530 op = TOK_UDIV;
3531 else if (op == '%')
3532 op = TOK_UMOD;
3533 else if (op == TOK_LT)
3534 op = TOK_ULT;
3535 else if (op == TOK_GT)
3536 op = TOK_UGT;
3537 else if (op == TOK_LE)
3538 op = TOK_ULE;
3539 else if (op == TOK_GE)
3540 op = TOK_UGE;
3542 vswap();
3543 gen_cast_s(t);
3544 vswap();
3545 /* special case for shifts and long long: we keep the shift as
3546 an integer */
3547 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
3548 t2 = VT_INT;
3549 gen_cast_s(t2);
3550 if (is_float(t))
3551 gen_opif(op);
3552 else
3553 gen_opic(op);
3554 if (TOK_ISCOND(op)) {
3555 /* relational op: the result is an int */
3556 vtop->type.t = VT_INT;
3557 } else {
3558 vtop->type.t = t;
3561 // Make sure that we have converted to an rvalue:
3562 if (vtop->r & VT_LVAL)
3563 gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
3566 #if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 || defined TCC_TARGET_ARM
3567 #define gen_cvt_itof1 gen_cvt_itof
3568 #else
3569 /* generic itof for unsigned long long case */
3570 static void gen_cvt_itof1(int t)
3572 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
3573 (VT_LLONG | VT_UNSIGNED)) {
3575 if (t == VT_FLOAT)
3576 vpush_helper_func(TOK___floatundisf);
3577 #if LDOUBLE_SIZE != 8
3578 else if (t == VT_LDOUBLE)
3579 vpush_helper_func(TOK___floatundixf);
3580 #endif
3581 else
3582 vpush_helper_func(TOK___floatundidf);
3583 vrott(2);
3584 gfunc_call(1);
3585 vpushi(0);
3586 PUT_R_RET(vtop, t);
3587 } else {
3588 gen_cvt_itof(t);
3591 #endif
3593 #if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
3594 #define gen_cvt_ftoi1 gen_cvt_ftoi
3595 #else
3596 /* generic ftoi for unsigned long long case */
3597 static void gen_cvt_ftoi1(int t)
3599 int st;
3600 if (t == (VT_LLONG | VT_UNSIGNED)) {
3601 /* not handled natively */
3602 st = vtop->type.t & VT_BTYPE;
3603 if (st == VT_FLOAT)
3604 vpush_helper_func(TOK___fixunssfdi);
3605 #if LDOUBLE_SIZE != 8
3606 else if (st == VT_LDOUBLE)
3607 vpush_helper_func(TOK___fixunsxfdi);
3608 #endif
3609 else
3610 vpush_helper_func(TOK___fixunsdfdi);
3611 vrott(2);
3612 gfunc_call(1);
3613 vpushi(0);
3614 PUT_R_RET(vtop, t);
3615 } else {
3616 gen_cvt_ftoi(t);
3619 #endif
3621 /* special delayed cast for char/short */
3622 static void force_charshort_cast(void)
3624 int sbt = BFGET(vtop->r, VT_MUSTCAST) == 2 ? VT_LLONG : VT_INT;
3625 int dbt = vtop->type.t;
3626 vtop->r &= ~VT_MUSTCAST;
3627 vtop->type.t = sbt;
3628 gen_cast_s(dbt == VT_BOOL ? VT_BYTE|VT_UNSIGNED : dbt);
3629 vtop->type.t = dbt;
3632 static void gen_cast_s(int t)
3634 CType type;
3635 type.t = t;
3636 type.ref = NULL;
3637 gen_cast(&type);
3640 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
3641 static void gen_cast(CType *type)
3643 int sbt, dbt, sf, df, c;
3644 int dbt_bt, sbt_bt, ds, ss, bits, trunc;
3646 /* special delayed cast for char/short */
3647 if (vtop->r & VT_MUSTCAST)
3648 force_charshort_cast();
3650 /* bitfields first get cast to ints */
3651 if (vtop->type.t & VT_BITFIELD)
3652 gv(RC_INT);
3654 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
3655 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3656 if (sbt == VT_FUNC)
3657 sbt = VT_PTR;
3659 again:
3660 if (sbt != dbt) {
3661 sf = is_float(sbt);
3662 df = is_float(dbt);
3663 dbt_bt = dbt & VT_BTYPE;
3664 sbt_bt = sbt & VT_BTYPE;
3665 if (dbt_bt == VT_VOID)
3666 goto done;
3667 if (sbt_bt == VT_VOID) {
3668 error:
3669 cast_error(&vtop->type, type);
3672 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3673 #if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
3674 c &= (dbt != VT_LDOUBLE) | !!nocode_wanted;
3675 #endif
3676 if (c) {
3677 /* constant case: we can do it now */
3678 /* XXX: in ISOC, cannot do it if error in convert */
3679 if (sbt == VT_FLOAT)
3680 vtop->c.ld = vtop->c.f;
3681 else if (sbt == VT_DOUBLE)
3682 vtop->c.ld = vtop->c.d;
3684 if (df) {
3685 if (sbt_bt == VT_LLONG) {
3686 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
3687 vtop->c.ld = vtop->c.i;
3688 else
3689 vtop->c.ld = -(long double)-vtop->c.i;
3690 } else if(!sf) {
3691 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
3692 vtop->c.ld = (uint32_t)vtop->c.i;
3693 else
3694 vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
3697 if (dbt == VT_FLOAT)
3698 vtop->c.f = (float)vtop->c.ld;
3699 else if (dbt == VT_DOUBLE)
3700 vtop->c.d = (double)vtop->c.ld;
3701 } else if (sf && dbt == VT_BOOL) {
3702 vtop->c.i = (vtop->c.ld != 0);
3703 } else {
3704 if(sf)
3705 vtop->c.i = vtop->c.ld;
3706 else if (sbt_bt == VT_LLONG || (PTR_SIZE == 8 && sbt == VT_PTR))
3708 else if (sbt & VT_UNSIGNED)
3709 vtop->c.i = (uint32_t)vtop->c.i;
3710 else
3711 vtop->c.i = ((uint32_t)vtop->c.i | -(vtop->c.i & 0x80000000));
3713 if (dbt_bt == VT_LLONG || (PTR_SIZE == 8 && dbt == VT_PTR))
3715 else if (dbt == VT_BOOL)
3716 vtop->c.i = (vtop->c.i != 0);
3717 else {
3718 uint32_t m = dbt_bt == VT_BYTE ? 0xff :
3719 dbt_bt == VT_SHORT ? 0xffff :
3720 0xffffffff;
3721 vtop->c.i &= m;
3722 if (!(dbt & VT_UNSIGNED))
3723 vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
3726 goto done;
3728 } else if (dbt == VT_BOOL
3729 && (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM))
3730 == (VT_CONST | VT_SYM)) {
3731 /* addresses are considered non-zero (see tcctest.c:sinit23) */
3732 vtop->r = VT_CONST;
3733 vtop->c.i = 1;
3734 goto done;
3737 /* cannot generate code for global or static initializers */
3738 if (STATIC_DATA_WANTED)
3739 goto done;
3741 /* non constant case: generate code */
3742 if (dbt == VT_BOOL) {
3743 gen_test_zero(TOK_NE);
3744 goto done;
3747 if (sf || df) {
3748 if (sf && df) {
3749 /* convert from fp to fp */
3750 gen_cvt_ftof(dbt);
3751 } else if (df) {
3752 /* convert int to fp */
3753 gen_cvt_itof1(dbt);
3754 } else {
3755 /* convert fp to int */
3756 sbt = dbt;
3757 if (dbt_bt != VT_LLONG && dbt_bt != VT_INT)
3758 sbt = VT_INT;
3759 gen_cvt_ftoi1(sbt);
3760 goto again; /* may need char/short cast */
3762 goto done;
3765 ds = btype_size(dbt_bt);
3766 ss = btype_size(sbt_bt);
3767 if (ds == 0 || ss == 0)
3768 goto error;
3770 if (IS_ENUM(type->t) && type->ref->c < 0)
3771 tcc_error("cast to incomplete type");
3773 /* same size and no sign conversion needed */
3774 if (ds == ss && ds >= 4)
3775 goto done;
3776 if (dbt_bt == VT_PTR || sbt_bt == VT_PTR) {
3777 tcc_warning("cast between pointer and integer of different size");
3778 if (sbt_bt == VT_PTR) {
3779 /* put integer type to allow logical operations below */
3780 vtop->type.t = (PTR_SIZE == 8 ? VT_LLONG : VT_INT);
3784 /* processor allows { int a = 0, b = *(char*)&a; }
3785 That means that if we cast to less width, we can just
3786 change the type and read it still later. */
3787 #define ALLOW_SUBTYPE_ACCESS 1
3789 if (ALLOW_SUBTYPE_ACCESS && (vtop->r & VT_LVAL)) {
3790 /* value still in memory */
3791 if (ds <= ss)
3792 goto done;
3793 /* ss <= 4 here */
3794 if (ds <= 4 && !(dbt == (VT_SHORT | VT_UNSIGNED) && sbt == VT_BYTE)) {
3795 gv(RC_INT);
3796 goto done; /* no 64bit envolved */
3799 gv(RC_INT);
3801 trunc = 0;
3802 #if PTR_SIZE == 4
3803 if (ds == 8) {
3804 /* generate high word */
3805 if (sbt & VT_UNSIGNED) {
3806 vpushi(0);
3807 gv(RC_INT);
3808 } else {
3809 gv_dup();
3810 vpushi(31);
3811 gen_op(TOK_SAR);
3813 lbuild(dbt);
3814 } else if (ss == 8) {
3815 /* from long long: just take low order word */
3816 lexpand();
3817 vpop();
3819 ss = 4;
3821 #elif PTR_SIZE == 8
3822 if (ds == 8) {
3823 /* need to convert from 32bit to 64bit */
3824 if (sbt & VT_UNSIGNED) {
3825 #if defined(TCC_TARGET_RISCV64)
3826 /* RISC-V keeps 32bit vals in registers sign-extended.
3827 So here we need a zero-extension. */
3828 trunc = 32;
3829 #else
3830 goto done;
3831 #endif
3832 } else {
3833 gen_cvt_sxtw();
3834 goto done;
3836 ss = ds, ds = 4, dbt = sbt;
3837 } else if (ss == 8) {
3838 /* RISC-V keeps 32bit vals in registers sign-extended.
3839 So here we need a sign-extension for signed types and
3840 zero-extension. for unsigned types. */
3841 #if !defined(TCC_TARGET_RISCV64)
3842 trunc = 32; /* zero upper 32 bits for non RISC-V targets */
3843 #endif
3844 } else {
3845 ss = 4;
3847 #endif
3849 if (ds >= ss)
3850 goto done;
3851 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM64
3852 if (ss == 4) {
3853 gen_cvt_csti(dbt);
3854 goto done;
3856 #endif
3857 bits = (ss - ds) * 8;
3858 /* for unsigned, gen_op will convert SAR to SHR */
3859 vtop->type.t = (ss == 8 ? VT_LLONG : VT_INT) | (dbt & VT_UNSIGNED);
3860 vpushi(bits);
3861 gen_op(TOK_SHL);
3862 vpushi(bits - trunc);
3863 gen_op(TOK_SAR);
3864 vpushi(trunc);
3865 gen_op(TOK_SHR);
3867 done:
3868 vtop->type = *type;
3869 vtop->type.t &= ~ ( VT_CONSTANT | VT_VOLATILE | VT_ARRAY );
3872 /* return type size as known at compile time. Put alignment at 'a' */
3873 ST_FUNC int type_size(CType *type, int *a)
3875 Sym *s;
3876 int bt;
3878 bt = type->t & VT_BTYPE;
3879 if (bt == VT_STRUCT) {
3880 /* struct/union */
3881 s = type->ref;
3882 *a = s->r;
3883 return s->c;
3884 } else if (bt == VT_PTR) {
3885 if (type->t & VT_ARRAY) {
3886 int ts;
3888 s = type->ref;
3889 ts = type_size(&s->type, a);
3891 if (ts < 0 && s->c < 0)
3892 ts = -ts;
3894 return ts * s->c;
3895 } else {
3896 *a = PTR_SIZE;
3897 return PTR_SIZE;
3899 } else if (IS_ENUM(type->t) && type->ref->c < 0) {
3900 *a = 0;
3901 return -1; /* incomplete enum */
3902 } else if (bt == VT_LDOUBLE) {
3903 *a = LDOUBLE_ALIGN;
3904 return LDOUBLE_SIZE;
3905 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
3906 #ifdef TCC_TARGET_I386
3907 #ifdef TCC_TARGET_PE
3908 *a = 8;
3909 #else
3910 *a = 4;
3911 #endif
3912 #elif defined(TCC_TARGET_ARM)
3913 #ifdef TCC_ARM_EABI
3914 *a = 8;
3915 #else
3916 *a = 4;
3917 #endif
3918 #else
3919 *a = 8;
3920 #endif
3921 return 8;
3922 } else if (bt == VT_INT || bt == VT_FLOAT) {
3923 *a = 4;
3924 return 4;
3925 } else if (bt == VT_SHORT) {
3926 *a = 2;
3927 return 2;
3928 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
3929 *a = 8;
3930 return 16;
3931 } else {
3932 /* char, void, function, _Bool */
3933 *a = 1;
3934 return 1;
3938 /* push type size as known at runtime time on top of value stack. Put
3939 alignment at 'a' */
3940 static void vpush_type_size(CType *type, int *a)
3942 if (type->t & VT_VLA) {
3943 type_size(&type->ref->type, a);
3944 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
3945 } else {
3946 int size = type_size(type, a);
3947 if (size < 0)
3948 tcc_error("unknown type size");
3949 #if PTR_SIZE == 8
3950 vpushll(size);
3951 #else
3952 vpushi(size);
3953 #endif
3957 /* return the pointed type of t */
3958 static inline CType *pointed_type(CType *type)
3960 return &type->ref->type;
3963 /* modify type so that its it is a pointer to type. */
3964 ST_FUNC void mk_pointer(CType *type)
3966 Sym *s;
3967 s = sym_push(SYM_FIELD, type, 0, -1);
3968 type->t = VT_PTR | (type->t & VT_STORAGE);
3969 type->ref = s;
3972 /* return true if type1 and type2 are exactly the same (including
3973 qualifiers).
3975 static int is_compatible_types(CType *type1, CType *type2)
3977 return compare_types(type1,type2,0);
3980 /* return true if type1 and type2 are the same (ignoring qualifiers).
3982 static int is_compatible_unqualified_types(CType *type1, CType *type2)
3984 return compare_types(type1,type2,1);
3987 static void cast_error(CType *st, CType *dt)
3989 type_incompatibility_error(st, dt, "cannot convert '%s' to '%s'");
3992 /* verify type compatibility to store vtop in 'dt' type */
3993 static void verify_assign_cast(CType *dt)
3995 CType *st, *type1, *type2;
3996 int dbt, sbt, qualwarn, lvl;
3998 st = &vtop->type; /* source type */
3999 dbt = dt->t & VT_BTYPE;
4000 sbt = st->t & VT_BTYPE;
4001 if (dt->t & VT_CONSTANT)
4002 tcc_warning("assignment of read-only location");
4003 switch(dbt) {
4004 case VT_VOID:
4005 if (sbt != dbt)
4006 tcc_error("assignment to void expression");
4007 break;
4008 case VT_PTR:
4009 /* special cases for pointers */
4010 /* '0' can also be a pointer */
4011 if (is_null_pointer(vtop))
4012 break;
4013 /* accept implicit pointer to integer cast with warning */
4014 if (is_integer_btype(sbt)) {
4015 tcc_warning("assignment makes pointer from integer without a cast");
4016 break;
4018 type1 = pointed_type(dt);
4019 if (sbt == VT_PTR)
4020 type2 = pointed_type(st);
4021 else if (sbt == VT_FUNC)
4022 type2 = st; /* a function is implicitly a function pointer */
4023 else
4024 goto error;
4025 if (is_compatible_types(type1, type2))
4026 break;
4027 for (qualwarn = lvl = 0;; ++lvl) {
4028 if (((type2->t & VT_CONSTANT) && !(type1->t & VT_CONSTANT)) ||
4029 ((type2->t & VT_VOLATILE) && !(type1->t & VT_VOLATILE)))
4030 qualwarn = 1;
4031 dbt = type1->t & (VT_BTYPE|VT_LONG);
4032 sbt = type2->t & (VT_BTYPE|VT_LONG);
4033 if (dbt != VT_PTR || sbt != VT_PTR)
4034 break;
4035 type1 = pointed_type(type1);
4036 type2 = pointed_type(type2);
4038 if (!is_compatible_unqualified_types(type1, type2)) {
4039 if ((dbt == VT_VOID || sbt == VT_VOID) && lvl == 0) {
4040 /* void * can match anything */
4041 } else if (dbt == sbt
4042 && is_integer_btype(sbt & VT_BTYPE)
4043 && IS_ENUM(type1->t) + IS_ENUM(type2->t)
4044 + !!((type1->t ^ type2->t) & VT_UNSIGNED) < 2) {
4045 /* Like GCC don't warn by default for merely changes
4046 in pointer target signedness. Do warn for different
4047 base types, though, in particular for unsigned enums
4048 and signed int targets. */
4049 } else {
4050 tcc_warning("assignment from incompatible pointer type");
4051 break;
4054 if (qualwarn)
4055 tcc_warning_c(warn_discarded_qualifiers)("assignment discards qualifiers from pointer target type");
4056 break;
4057 case VT_BYTE:
4058 case VT_SHORT:
4059 case VT_INT:
4060 case VT_LLONG:
4061 if (sbt == VT_PTR || sbt == VT_FUNC) {
4062 tcc_warning("assignment makes integer from pointer without a cast");
4063 } else if (sbt == VT_STRUCT) {
4064 goto case_VT_STRUCT;
4066 /* XXX: more tests */
4067 break;
4068 case VT_STRUCT:
4069 case_VT_STRUCT:
4070 if (!is_compatible_unqualified_types(dt, st)) {
4071 error:
4072 cast_error(st, dt);
4074 break;
4078 static void gen_assign_cast(CType *dt)
4080 verify_assign_cast(dt);
4081 gen_cast(dt);
4084 /* store vtop in lvalue pushed on stack */
4085 ST_FUNC void vstore(void)
4087 int sbt, dbt, ft, r, size, align, bit_size, bit_pos, delayed_cast;
4089 ft = vtop[-1].type.t;
4090 sbt = vtop->type.t & VT_BTYPE;
4091 dbt = ft & VT_BTYPE;
4093 verify_assign_cast(&vtop[-1].type);
4095 if (sbt == VT_STRUCT) {
4096 /* if structure, only generate pointer */
4097 /* structure assignment : generate memcpy */
4098 /* XXX: optimize if small size */
4099 size = type_size(&vtop->type, &align);
4101 /* destination */
4102 vswap();
4103 #ifdef CONFIG_TCC_BCHECK
4104 if (vtop->r & VT_MUSTBOUND)
4105 gbound(); /* check would be wrong after gaddrof() */
4106 #endif
4107 vtop->type.t = VT_PTR;
4108 gaddrof();
4110 /* address of memcpy() */
4111 #ifdef TCC_ARM_EABI
4112 if(!(align & 7))
4113 vpush_helper_func(TOK_memmove8);
4114 else if(!(align & 3))
4115 vpush_helper_func(TOK_memmove4);
4116 else
4117 #endif
4118 /* Use memmove, rather than memcpy, as dest and src may be same: */
4119 vpush_helper_func(TOK_memmove);
4121 vswap();
4122 /* source */
4123 vpushv(vtop - 2);
4124 #ifdef CONFIG_TCC_BCHECK
4125 if (vtop->r & VT_MUSTBOUND)
4126 gbound();
4127 #endif
4128 vtop->type.t = VT_PTR;
4129 gaddrof();
4130 /* type size */
4131 vpushi(size);
4132 gfunc_call(3);
4133 /* leave source on stack */
4135 } else if (ft & VT_BITFIELD) {
4136 /* bitfield store handling */
4138 /* save lvalue as expression result (example: s.b = s.a = n;) */
4139 vdup(), vtop[-1] = vtop[-2];
4141 bit_pos = BIT_POS(ft);
4142 bit_size = BIT_SIZE(ft);
4143 /* remove bit field info to avoid loops */
4144 vtop[-1].type.t = ft & ~VT_STRUCT_MASK;
4146 if (dbt == VT_BOOL) {
4147 gen_cast(&vtop[-1].type);
4148 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
4150 r = adjust_bf(vtop - 1, bit_pos, bit_size);
4151 if (dbt != VT_BOOL) {
4152 gen_cast(&vtop[-1].type);
4153 dbt = vtop[-1].type.t & VT_BTYPE;
4155 if (r == VT_STRUCT) {
4156 store_packed_bf(bit_pos, bit_size);
4157 } else {
4158 unsigned long long mask = (1ULL << bit_size) - 1;
4159 if (dbt != VT_BOOL) {
4160 /* mask source */
4161 if (dbt == VT_LLONG)
4162 vpushll(mask);
4163 else
4164 vpushi((unsigned)mask);
4165 gen_op('&');
4167 /* shift source */
4168 vpushi(bit_pos);
4169 gen_op(TOK_SHL);
4170 vswap();
4171 /* duplicate destination */
4172 vdup();
4173 vrott(3);
4174 /* load destination, mask and or with source */
4175 if (dbt == VT_LLONG)
4176 vpushll(~(mask << bit_pos));
4177 else
4178 vpushi(~((unsigned)mask << bit_pos));
4179 gen_op('&');
4180 gen_op('|');
4181 /* store result */
4182 vstore();
4183 /* ... and discard */
4184 vpop();
4186 } else if (dbt == VT_VOID) {
4187 --vtop;
4188 } else {
4189 /* optimize char/short casts */
4190 delayed_cast = 0;
4191 if ((dbt == VT_BYTE || dbt == VT_SHORT)
4192 && is_integer_btype(sbt)
4194 if ((vtop->r & VT_MUSTCAST)
4195 && btype_size(dbt) > btype_size(sbt)
4197 force_charshort_cast();
4198 delayed_cast = 1;
4199 } else {
4200 gen_cast(&vtop[-1].type);
4203 #ifdef CONFIG_TCC_BCHECK
4204 /* bound check case */
4205 if (vtop[-1].r & VT_MUSTBOUND) {
4206 vswap();
4207 gbound();
4208 vswap();
4210 #endif
4211 gv(RC_TYPE(dbt)); /* generate value */
4213 if (delayed_cast) {
4214 vtop->r |= BFVAL(VT_MUSTCAST, (sbt == VT_LLONG) + 1);
4215 //tcc_warning("deley cast %x -> %x", sbt, dbt);
4216 vtop->type.t = ft & VT_TYPE;
4219 /* if lvalue was saved on stack, must read it */
4220 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
4221 SValue sv;
4222 r = get_reg(RC_INT);
4223 sv.type.t = VT_PTRDIFF_T;
4224 sv.r = VT_LOCAL | VT_LVAL;
4225 sv.c.i = vtop[-1].c.i;
4226 load(r, &sv);
4227 vtop[-1].r = r | VT_LVAL;
4230 r = vtop->r & VT_VALMASK;
4231 /* two word case handling :
4232 store second register at word + 4 (or +8 for x86-64) */
4233 if (USING_TWO_WORDS(dbt)) {
4234 int load_type = (dbt == VT_QFLOAT) ? VT_DOUBLE : VT_PTRDIFF_T;
4235 vtop[-1].type.t = load_type;
4236 store(r, vtop - 1);
4237 vswap();
4238 /* convert to int to increment easily */
4239 vtop->type.t = VT_PTRDIFF_T;
4240 gaddrof();
4241 vpushs(PTR_SIZE);
4242 gen_op('+');
4243 vtop->r |= VT_LVAL;
4244 vswap();
4245 vtop[-1].type.t = load_type;
4246 /* XXX: it works because r2 is spilled last ! */
4247 store(vtop->r2, vtop - 1);
4248 } else {
4249 /* single word */
4250 store(r, vtop - 1);
4252 vswap();
4253 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4257 /* post defines POST/PRE add. c is the token ++ or -- */
4258 ST_FUNC void inc(int post, int c)
4260 test_lvalue();
4261 vdup(); /* save lvalue */
4262 if (post) {
4263 gv_dup(); /* duplicate value */
4264 vrotb(3);
4265 vrotb(3);
4267 /* add constant */
4268 vpushi(c - TOK_MID);
4269 gen_op('+');
4270 vstore(); /* store value */
4271 if (post)
4272 vpop(); /* if post op, return saved value */
4275 ST_FUNC void parse_mult_str (CString *astr, const char *msg)
4277 /* read the string */
4278 if (tok != TOK_STR)
4279 expect(msg);
4280 cstr_new(astr);
4281 while (tok == TOK_STR) {
4282 /* XXX: add \0 handling too ? */
4283 cstr_cat(astr, tokc.str.data, -1);
4284 next();
4286 cstr_ccat(astr, '\0');
4289 /* If I is >= 1 and a power of two, returns log2(i)+1.
4290 If I is 0 returns 0. */
4291 ST_FUNC int exact_log2p1(int i)
4293 int ret;
4294 if (!i)
4295 return 0;
4296 for (ret = 1; i >= 1 << 8; ret += 8)
4297 i >>= 8;
4298 if (i >= 1 << 4)
4299 ret += 4, i >>= 4;
4300 if (i >= 1 << 2)
4301 ret += 2, i >>= 2;
4302 if (i >= 1 << 1)
4303 ret++;
4304 return ret;
4307 /* Parse __attribute__((...)) GNUC extension. */
4308 static void parse_attribute(AttributeDef *ad)
4310 int t, n;
4311 CString astr;
4313 redo:
4314 if (tok != TOK_ATTRIBUTE1 && tok != TOK_ATTRIBUTE2)
4315 return;
4316 next();
4317 skip('(');
4318 skip('(');
4319 while (tok != ')') {
4320 if (tok < TOK_IDENT)
4321 expect("attribute name");
4322 t = tok;
4323 next();
4324 switch(t) {
4325 case TOK_CLEANUP1:
4326 case TOK_CLEANUP2:
4328 Sym *s;
4330 skip('(');
4331 s = sym_find(tok);
4332 if (!s) {
4333 tcc_warning_c(warn_implicit_function_declaration)(
4334 "implicit declaration of function '%s'", get_tok_str(tok, &tokc));
4335 s = external_global_sym(tok, &func_old_type);
4336 } else if ((s->type.t & VT_BTYPE) != VT_FUNC)
4337 tcc_error("'%s' is not declared as function", get_tok_str(tok, &tokc));
4338 ad->cleanup_func = s;
4339 next();
4340 skip(')');
4341 break;
4343 case TOK_CONSTRUCTOR1:
4344 case TOK_CONSTRUCTOR2:
4345 ad->f.func_ctor = 1;
4346 break;
4347 case TOK_DESTRUCTOR1:
4348 case TOK_DESTRUCTOR2:
4349 ad->f.func_dtor = 1;
4350 break;
4351 case TOK_ALWAYS_INLINE1:
4352 case TOK_ALWAYS_INLINE2:
4353 ad->f.func_alwinl = 1;
4354 break;
4355 case TOK_SECTION1:
4356 case TOK_SECTION2:
4357 skip('(');
4358 parse_mult_str(&astr, "section name");
4359 ad->section = find_section(tcc_state, (char *)astr.data);
4360 skip(')');
4361 cstr_free(&astr);
4362 break;
4363 case TOK_ALIAS1:
4364 case TOK_ALIAS2:
4365 skip('(');
4366 parse_mult_str(&astr, "alias(\"target\")");
4367 ad->alias_target = /* save string as token, for later */
4368 tok_alloc((char*)astr.data, astr.size-1)->tok;
4369 skip(')');
4370 cstr_free(&astr);
4371 break;
4372 case TOK_VISIBILITY1:
4373 case TOK_VISIBILITY2:
4374 skip('(');
4375 parse_mult_str(&astr,
4376 "visibility(\"default|hidden|internal|protected\")");
4377 if (!strcmp (astr.data, "default"))
4378 ad->a.visibility = STV_DEFAULT;
4379 else if (!strcmp (astr.data, "hidden"))
4380 ad->a.visibility = STV_HIDDEN;
4381 else if (!strcmp (astr.data, "internal"))
4382 ad->a.visibility = STV_INTERNAL;
4383 else if (!strcmp (astr.data, "protected"))
4384 ad->a.visibility = STV_PROTECTED;
4385 else
4386 expect("visibility(\"default|hidden|internal|protected\")");
4387 skip(')');
4388 cstr_free(&astr);
4389 break;
4390 case TOK_ALIGNED1:
4391 case TOK_ALIGNED2:
4392 if (tok == '(') {
4393 next();
4394 n = expr_const();
4395 if (n <= 0 || (n & (n - 1)) != 0)
4396 tcc_error("alignment must be a positive power of two");
4397 skip(')');
4398 } else {
4399 n = MAX_ALIGN;
4401 ad->a.aligned = exact_log2p1(n);
4402 if (n != 1 << (ad->a.aligned - 1))
4403 tcc_error("alignment of %d is larger than implemented", n);
4404 break;
4405 case TOK_PACKED1:
4406 case TOK_PACKED2:
4407 ad->a.packed = 1;
4408 break;
4409 case TOK_WEAK1:
4410 case TOK_WEAK2:
4411 ad->a.weak = 1;
4412 break;
4413 case TOK_UNUSED1:
4414 case TOK_UNUSED2:
4415 /* currently, no need to handle it because tcc does not
4416 track unused objects */
4417 break;
4418 case TOK_NORETURN1:
4419 case TOK_NORETURN2:
4420 ad->f.func_noreturn = 1;
4421 break;
4422 case TOK_CDECL1:
4423 case TOK_CDECL2:
4424 case TOK_CDECL3:
4425 ad->f.func_call = FUNC_CDECL;
4426 break;
4427 case TOK_STDCALL1:
4428 case TOK_STDCALL2:
4429 case TOK_STDCALL3:
4430 ad->f.func_call = FUNC_STDCALL;
4431 break;
4432 #ifdef TCC_TARGET_I386
4433 case TOK_REGPARM1:
4434 case TOK_REGPARM2:
4435 skip('(');
4436 n = expr_const();
4437 if (n > 3)
4438 n = 3;
4439 else if (n < 0)
4440 n = 0;
4441 if (n > 0)
4442 ad->f.func_call = FUNC_FASTCALL1 + n - 1;
4443 skip(')');
4444 break;
4445 case TOK_FASTCALL1:
4446 case TOK_FASTCALL2:
4447 case TOK_FASTCALL3:
4448 ad->f.func_call = FUNC_FASTCALLW;
4449 break;
4450 #endif
4451 case TOK_MODE:
4452 skip('(');
4453 switch(tok) {
4454 case TOK_MODE_DI:
4455 ad->attr_mode = VT_LLONG + 1;
4456 break;
4457 case TOK_MODE_QI:
4458 ad->attr_mode = VT_BYTE + 1;
4459 break;
4460 case TOK_MODE_HI:
4461 ad->attr_mode = VT_SHORT + 1;
4462 break;
4463 case TOK_MODE_SI:
4464 case TOK_MODE_word:
4465 ad->attr_mode = VT_INT + 1;
4466 break;
4467 default:
4468 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
4469 break;
4471 next();
4472 skip(')');
4473 break;
4474 case TOK_DLLEXPORT:
4475 ad->a.dllexport = 1;
4476 break;
4477 case TOK_NODECORATE:
4478 ad->a.nodecorate = 1;
4479 break;
4480 case TOK_DLLIMPORT:
4481 ad->a.dllimport = 1;
4482 break;
4483 default:
4484 tcc_warning_c(warn_unsupported)("'%s' attribute ignored", get_tok_str(t, NULL));
4485 /* skip parameters */
4486 if (tok == '(') {
4487 int parenthesis = 0;
4488 do {
4489 if (tok == '(')
4490 parenthesis++;
4491 else if (tok == ')')
4492 parenthesis--;
4493 next();
4494 } while (parenthesis && tok != -1);
4496 break;
4498 if (tok != ',')
4499 break;
4500 next();
4502 skip(')');
4503 skip(')');
4504 goto redo;
4507 static Sym * find_field (CType *type, int v, int *cumofs)
4509 Sym *s = type->ref;
4510 v |= SYM_FIELD;
4511 while ((s = s->next) != NULL) {
4512 if ((s->v & SYM_FIELD) &&
4513 (s->type.t & VT_BTYPE) == VT_STRUCT &&
4514 (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
4515 Sym *ret = find_field (&s->type, v, cumofs);
4516 if (ret) {
4517 *cumofs += s->c;
4518 return ret;
4521 if (s->v == v)
4522 break;
4524 return s;
4527 static void check_fields (CType *type, int check)
4529 Sym *s = type->ref;
4531 while ((s = s->next) != NULL) {
4532 int v = s->v & ~SYM_FIELD;
4533 if (v < SYM_FIRST_ANOM) {
4534 TokenSym *ts = table_ident[v - TOK_IDENT];
4535 if (check && (ts->tok & SYM_FIELD))
4536 tcc_error("duplicate member '%s'", get_tok_str(v, NULL));
4537 ts->tok ^= SYM_FIELD;
4538 } else if ((s->type.t & VT_BTYPE) == VT_STRUCT)
4539 check_fields (&s->type, check);
4543 static void struct_layout(CType *type, AttributeDef *ad)
4545 int size, align, maxalign, offset, c, bit_pos, bit_size;
4546 int packed, a, bt, prevbt, prev_bit_size;
4547 int pcc = !tcc_state->ms_bitfields;
4548 int pragma_pack = *tcc_state->pack_stack_ptr;
4549 Sym *f;
4551 maxalign = 1;
4552 offset = 0;
4553 c = 0;
4554 bit_pos = 0;
4555 prevbt = VT_STRUCT; /* make it never match */
4556 prev_bit_size = 0;
4558 //#define BF_DEBUG
4560 for (f = type->ref->next; f; f = f->next) {
4561 if (f->type.t & VT_BITFIELD)
4562 bit_size = BIT_SIZE(f->type.t);
4563 else
4564 bit_size = -1;
4565 size = type_size(&f->type, &align);
4566 a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0;
4567 packed = 0;
4569 if (pcc && bit_size == 0) {
4570 /* in pcc mode, packing does not affect zero-width bitfields */
4572 } else {
4573 /* in pcc mode, attribute packed overrides if set. */
4574 if (pcc && (f->a.packed || ad->a.packed))
4575 align = packed = 1;
4577 /* pragma pack overrides align if lesser and packs bitfields always */
4578 if (pragma_pack) {
4579 packed = 1;
4580 if (pragma_pack < align)
4581 align = pragma_pack;
4582 /* in pcc mode pragma pack also overrides individual align */
4583 if (pcc && pragma_pack < a)
4584 a = 0;
4587 /* some individual align was specified */
4588 if (a)
4589 align = a;
4591 if (type->ref->type.t == VT_UNION) {
4592 if (pcc && bit_size >= 0)
4593 size = (bit_size + 7) >> 3;
4594 offset = 0;
4595 if (size > c)
4596 c = size;
4598 } else if (bit_size < 0) {
4599 if (pcc)
4600 c += (bit_pos + 7) >> 3;
4601 c = (c + align - 1) & -align;
4602 offset = c;
4603 if (size > 0)
4604 c += size;
4605 bit_pos = 0;
4606 prevbt = VT_STRUCT;
4607 prev_bit_size = 0;
4609 } else {
4610 /* A bit-field. Layout is more complicated. There are two
4611 options: PCC (GCC) compatible and MS compatible */
4612 if (pcc) {
4613 /* In PCC layout a bit-field is placed adjacent to the
4614 preceding bit-fields, except if:
4615 - it has zero-width
4616 - an individual alignment was given
4617 - it would overflow its base type container and
4618 there is no packing */
4619 if (bit_size == 0) {
4620 new_field:
4621 c = (c + ((bit_pos + 7) >> 3) + align - 1) & -align;
4622 bit_pos = 0;
4623 } else if (f->a.aligned) {
4624 goto new_field;
4625 } else if (!packed) {
4626 int a8 = align * 8;
4627 int ofs = ((c * 8 + bit_pos) % a8 + bit_size + a8 - 1) / a8;
4628 if (ofs > size / align)
4629 goto new_field;
4632 /* in pcc mode, long long bitfields have type int if they fit */
4633 if (size == 8 && bit_size <= 32)
4634 f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT, size = 4;
4636 while (bit_pos >= align * 8)
4637 c += align, bit_pos -= align * 8;
4638 offset = c;
4640 /* In PCC layout named bit-fields influence the alignment
4641 of the containing struct using the base types alignment,
4642 except for packed fields (which here have correct align). */
4643 if (f->v & SYM_FIRST_ANOM
4644 // && bit_size // ??? gcc on ARM/rpi does that
4646 align = 1;
4648 } else {
4649 bt = f->type.t & VT_BTYPE;
4650 if ((bit_pos + bit_size > size * 8)
4651 || (bit_size > 0) == (bt != prevbt)
4653 c = (c + align - 1) & -align;
4654 offset = c;
4655 bit_pos = 0;
4656 /* In MS bitfield mode a bit-field run always uses
4657 at least as many bits as the underlying type.
4658 To start a new run it's also required that this
4659 or the last bit-field had non-zero width. */
4660 if (bit_size || prev_bit_size)
4661 c += size;
4663 /* In MS layout the records alignment is normally
4664 influenced by the field, except for a zero-width
4665 field at the start of a run (but by further zero-width
4666 fields it is again). */
4667 if (bit_size == 0 && prevbt != bt)
4668 align = 1;
4669 prevbt = bt;
4670 prev_bit_size = bit_size;
4673 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
4674 | (bit_pos << VT_STRUCT_SHIFT);
4675 bit_pos += bit_size;
4677 if (align > maxalign)
4678 maxalign = align;
4680 #ifdef BF_DEBUG
4681 printf("set field %s offset %-2d size %-2d align %-2d",
4682 get_tok_str(f->v & ~SYM_FIELD, NULL), offset, size, align);
4683 if (f->type.t & VT_BITFIELD) {
4684 printf(" pos %-2d bits %-2d",
4685 BIT_POS(f->type.t),
4686 BIT_SIZE(f->type.t)
4689 printf("\n");
4690 #endif
4692 f->c = offset;
4693 f->r = 0;
4696 if (pcc)
4697 c += (bit_pos + 7) >> 3;
4699 /* store size and alignment */
4700 a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1;
4701 if (a < maxalign)
4702 a = maxalign;
4703 type->ref->r = a;
4704 if (pragma_pack && pragma_pack < maxalign && 0 == pcc) {
4705 /* can happen if individual align for some member was given. In
4706 this case MSVC ignores maxalign when aligning the size */
4707 a = pragma_pack;
4708 if (a < bt)
4709 a = bt;
4711 c = (c + a - 1) & -a;
4712 type->ref->c = c;
4714 #ifdef BF_DEBUG
4715 printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout);
4716 #endif
4718 /* check whether we can access bitfields by their type */
4719 for (f = type->ref->next; f; f = f->next) {
4720 int s, px, cx, c0;
4721 CType t;
4723 if (0 == (f->type.t & VT_BITFIELD))
4724 continue;
4725 f->type.ref = f;
4726 f->auxtype = -1;
4727 bit_size = BIT_SIZE(f->type.t);
4728 if (bit_size == 0)
4729 continue;
4730 bit_pos = BIT_POS(f->type.t);
4731 size = type_size(&f->type, &align);
4733 if (bit_pos + bit_size <= size * 8 && f->c + size <= c
4734 #ifdef TCC_TARGET_ARM
4735 && !(f->c & (align - 1))
4736 #endif
4738 continue;
4740 /* try to access the field using a different type */
4741 c0 = -1, s = align = 1;
4742 t.t = VT_BYTE;
4743 for (;;) {
4744 px = f->c * 8 + bit_pos;
4745 cx = (px >> 3) & -align;
4746 px = px - (cx << 3);
4747 if (c0 == cx)
4748 break;
4749 s = (px + bit_size + 7) >> 3;
4750 if (s > 4) {
4751 t.t = VT_LLONG;
4752 } else if (s > 2) {
4753 t.t = VT_INT;
4754 } else if (s > 1) {
4755 t.t = VT_SHORT;
4756 } else {
4757 t.t = VT_BYTE;
4759 s = type_size(&t, &align);
4760 c0 = cx;
4763 if (px + bit_size <= s * 8 && cx + s <= c
4764 #ifdef TCC_TARGET_ARM
4765 && !(cx & (align - 1))
4766 #endif
4768 /* update offset and bit position */
4769 f->c = cx;
4770 bit_pos = px;
4771 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
4772 | (bit_pos << VT_STRUCT_SHIFT);
4773 if (s != size)
4774 f->auxtype = t.t;
4775 #ifdef BF_DEBUG
4776 printf("FIX field %s offset %-2d size %-2d align %-2d "
4777 "pos %-2d bits %-2d\n",
4778 get_tok_str(f->v & ~SYM_FIELD, NULL),
4779 cx, s, align, px, bit_size);
4780 #endif
4781 } else {
4782 /* fall back to load/store single-byte wise */
4783 f->auxtype = VT_STRUCT;
4784 #ifdef BF_DEBUG
4785 printf("FIX field %s : load byte-wise\n",
4786 get_tok_str(f->v & ~SYM_FIELD, NULL));
4787 #endif
4792 /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
4793 static void struct_decl(CType *type, int u)
4795 int v, c, size, align, flexible;
4796 int bit_size, bsize, bt;
4797 Sym *s, *ss, **ps;
4798 AttributeDef ad, ad1;
4799 CType type1, btype;
4801 memset(&ad, 0, sizeof ad);
4802 next();
4803 parse_attribute(&ad);
4804 if (tok != '{') {
4805 v = tok;
4806 next();
4807 /* struct already defined ? return it */
4808 if (v < TOK_IDENT)
4809 expect("struct/union/enum name");
4810 s = struct_find(v);
4811 if (s && (s->sym_scope == local_scope || tok != '{')) {
4812 if (u == s->type.t)
4813 goto do_decl;
4814 if (u == VT_ENUM && IS_ENUM(s->type.t))
4815 goto do_decl;
4816 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
4818 } else {
4819 v = anon_sym++;
4821 /* Record the original enum/struct/union token. */
4822 type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u;
4823 type1.ref = NULL;
4824 /* we put an undefined size for struct/union */
4825 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
4826 s->r = 0; /* default alignment is zero as gcc */
4827 do_decl:
4828 type->t = s->type.t;
4829 type->ref = s;
4831 if (tok == '{') {
4832 next();
4833 if (s->c != -1)
4834 tcc_error("struct/union/enum already defined");
4835 s->c = -2;
4836 /* cannot be empty */
4837 /* non empty enums are not allowed */
4838 ps = &s->next;
4839 if (u == VT_ENUM) {
4840 long long ll = 0, pl = 0, nl = 0;
4841 CType t;
4842 t.ref = s;
4843 /* enum symbols have static storage */
4844 t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;
4845 for(;;) {
4846 v = tok;
4847 if (v < TOK_UIDENT)
4848 expect("identifier");
4849 ss = sym_find(v);
4850 if (ss && !local_stack)
4851 tcc_error("redefinition of enumerator '%s'",
4852 get_tok_str(v, NULL));
4853 next();
4854 if (tok == '=') {
4855 next();
4856 ll = expr_const64();
4858 ss = sym_push(v, &t, VT_CONST, 0);
4859 ss->enum_val = ll;
4860 *ps = ss, ps = &ss->next;
4861 if (ll < nl)
4862 nl = ll;
4863 if (ll > pl)
4864 pl = ll;
4865 if (tok != ',')
4866 break;
4867 next();
4868 ll++;
4869 /* NOTE: we accept a trailing comma */
4870 if (tok == '}')
4871 break;
4873 skip('}');
4874 /* set integral type of the enum */
4875 t.t = VT_INT;
4876 if (nl >= 0) {
4877 if (pl != (unsigned)pl)
4878 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
4879 t.t |= VT_UNSIGNED;
4880 } else if (pl != (int)pl || nl != (int)nl)
4881 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
4882 s->type.t = type->t = t.t | VT_ENUM;
4883 s->c = 0;
4884 /* set type for enum members */
4885 for (ss = s->next; ss; ss = ss->next) {
4886 ll = ss->enum_val;
4887 if (ll == (int)ll) /* default is int if it fits */
4888 continue;
4889 if (t.t & VT_UNSIGNED) {
4890 ss->type.t |= VT_UNSIGNED;
4891 if (ll == (unsigned)ll)
4892 continue;
4894 ss->type.t = (ss->type.t & ~VT_BTYPE)
4895 | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
4897 } else {
4898 c = 0;
4899 flexible = 0;
4900 while (tok != '}') {
4901 if (!parse_btype(&btype, &ad1)) {
4902 skip(';');
4903 continue;
4905 while (1) {
4906 if (flexible)
4907 tcc_error("flexible array member '%s' not at the end of struct",
4908 get_tok_str(v, NULL));
4909 bit_size = -1;
4910 v = 0;
4911 type1 = btype;
4912 if (tok != ':') {
4913 if (tok != ';')
4914 type_decl(&type1, &ad1, &v, TYPE_DIRECT);
4915 if (v == 0) {
4916 if ((type1.t & VT_BTYPE) != VT_STRUCT)
4917 expect("identifier");
4918 else {
4919 int v = btype.ref->v;
4920 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
4921 if (tcc_state->ms_extensions == 0)
4922 expect("identifier");
4926 if (type_size(&type1, &align) < 0) {
4927 if ((u == VT_STRUCT) && (type1.t & VT_ARRAY) && c)
4928 flexible = 1;
4929 else
4930 tcc_error("field '%s' has incomplete type",
4931 get_tok_str(v, NULL));
4933 if ((type1.t & VT_BTYPE) == VT_FUNC ||
4934 (type1.t & VT_BTYPE) == VT_VOID ||
4935 (type1.t & VT_STORAGE))
4936 tcc_error("invalid type for '%s'",
4937 get_tok_str(v, NULL));
4939 if (tok == ':') {
4940 next();
4941 bit_size = expr_const();
4942 /* XXX: handle v = 0 case for messages */
4943 if (bit_size < 0)
4944 tcc_error("negative width in bit-field '%s'",
4945 get_tok_str(v, NULL));
4946 if (v && bit_size == 0)
4947 tcc_error("zero width for bit-field '%s'",
4948 get_tok_str(v, NULL));
4949 parse_attribute(&ad1);
4951 size = type_size(&type1, &align);
4952 if (bit_size >= 0) {
4953 bt = type1.t & VT_BTYPE;
4954 if (bt != VT_INT &&
4955 bt != VT_BYTE &&
4956 bt != VT_SHORT &&
4957 bt != VT_BOOL &&
4958 bt != VT_LLONG)
4959 tcc_error("bitfields must have scalar type");
4960 bsize = size * 8;
4961 if (bit_size > bsize) {
4962 tcc_error("width of '%s' exceeds its type",
4963 get_tok_str(v, NULL));
4964 } else if (bit_size == bsize
4965 && !ad.a.packed && !ad1.a.packed) {
4966 /* no need for bit fields */
4968 } else if (bit_size == 64) {
4969 tcc_error("field width 64 not implemented");
4970 } else {
4971 type1.t = (type1.t & ~VT_STRUCT_MASK)
4972 | VT_BITFIELD
4973 | (bit_size << (VT_STRUCT_SHIFT + 6));
4976 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
4977 /* Remember we've seen a real field to check
4978 for placement of flexible array member. */
4979 c = 1;
4981 /* If member is a struct or bit-field, enforce
4982 placing into the struct (as anonymous). */
4983 if (v == 0 &&
4984 ((type1.t & VT_BTYPE) == VT_STRUCT ||
4985 bit_size >= 0)) {
4986 v = anon_sym++;
4988 if (v) {
4989 ss = sym_push(v | SYM_FIELD, &type1, 0, 0);
4990 ss->a = ad1.a;
4991 *ps = ss;
4992 ps = &ss->next;
4994 if (tok == ';' || tok == TOK_EOF)
4995 break;
4996 skip(',');
4998 skip(';');
5000 skip('}');
5001 parse_attribute(&ad);
5002 if (ad.cleanup_func) {
5003 tcc_warning("attribute '__cleanup__' ignored on type");
5005 check_fields(type, 1);
5006 check_fields(type, 0);
5007 struct_layout(type, &ad);
5012 static void sym_to_attr(AttributeDef *ad, Sym *s)
5014 merge_symattr(&ad->a, &s->a);
5015 merge_funcattr(&ad->f, &s->f);
5018 /* Add type qualifiers to a type. If the type is an array then the qualifiers
5019 are added to the element type, copied because it could be a typedef. */
5020 static void parse_btype_qualify(CType *type, int qualifiers)
5022 while (type->t & VT_ARRAY) {
5023 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
5024 type = &type->ref->type;
5026 type->t |= qualifiers;
5029 /* return 0 if no type declaration. otherwise, return the basic type
5030 and skip it.
5032 static int parse_btype(CType *type, AttributeDef *ad)
5034 int t, u, bt, st, type_found, typespec_found, g, n;
5035 Sym *s;
5036 CType type1;
5038 memset(ad, 0, sizeof(AttributeDef));
5039 type_found = 0;
5040 typespec_found = 0;
5041 t = VT_INT;
5042 bt = st = -1;
5043 type->ref = NULL;
5045 while(1) {
5046 switch(tok) {
5047 case TOK_EXTENSION:
5048 /* currently, we really ignore extension */
5049 next();
5050 continue;
5052 /* basic types */
5053 case TOK_CHAR:
5054 u = VT_BYTE;
5055 basic_type:
5056 next();
5057 basic_type1:
5058 if (u == VT_SHORT || u == VT_LONG) {
5059 if (st != -1 || (bt != -1 && bt != VT_INT))
5060 tmbt: tcc_error("too many basic types");
5061 st = u;
5062 } else {
5063 if (bt != -1 || (st != -1 && u != VT_INT))
5064 goto tmbt;
5065 bt = u;
5067 if (u != VT_INT)
5068 t = (t & ~(VT_BTYPE|VT_LONG)) | u;
5069 typespec_found = 1;
5070 break;
5071 case TOK_VOID:
5072 u = VT_VOID;
5073 goto basic_type;
5074 case TOK_SHORT:
5075 u = VT_SHORT;
5076 goto basic_type;
5077 case TOK_INT:
5078 u = VT_INT;
5079 goto basic_type;
5080 case TOK_ALIGNAS:
5081 { int n;
5082 AttributeDef ad1;
5083 next();
5084 skip('(');
5085 memset(&ad1, 0, sizeof(AttributeDef));
5086 if (parse_btype(&type1, &ad1)) {
5087 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5088 if (ad1.a.aligned)
5089 n = 1 << (ad1.a.aligned - 1);
5090 else
5091 type_size(&type1, &n);
5092 } else {
5093 n = expr_const();
5094 if (n <= 0 || (n & (n - 1)) != 0)
5095 tcc_error("alignment must be a positive power of two");
5097 skip(')');
5098 ad->a.aligned = exact_log2p1(n);
5100 continue;
5101 case TOK_LONG:
5102 if ((t & VT_BTYPE) == VT_DOUBLE) {
5103 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
5104 } else if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
5105 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LLONG;
5106 } else {
5107 u = VT_LONG;
5108 goto basic_type;
5110 next();
5111 break;
5112 #ifdef TCC_TARGET_ARM64
5113 case TOK_UINT128:
5114 /* GCC's __uint128_t appears in some Linux header files. Make it a
5115 synonym for long double to get the size and alignment right. */
5116 u = VT_LDOUBLE;
5117 goto basic_type;
5118 #endif
5119 case TOK_BOOL:
5120 u = VT_BOOL;
5121 goto basic_type;
5122 case TOK_FLOAT:
5123 u = VT_FLOAT;
5124 goto basic_type;
5125 case TOK_DOUBLE:
5126 if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
5127 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
5128 } else {
5129 u = VT_DOUBLE;
5130 goto basic_type;
5132 next();
5133 break;
5134 case TOK_ENUM:
5135 struct_decl(&type1, VT_ENUM);
5136 basic_type2:
5137 u = type1.t;
5138 type->ref = type1.ref;
5139 goto basic_type1;
5140 case TOK_STRUCT:
5141 struct_decl(&type1, VT_STRUCT);
5142 goto basic_type2;
5143 case TOK_UNION:
5144 struct_decl(&type1, VT_UNION);
5145 goto basic_type2;
5147 /* type modifiers */
5148 case TOK__Atomic:
5149 next();
5150 type->t = t;
5151 parse_btype_qualify(type, VT_ATOMIC);
5152 t = type->t;
5153 if (tok == '(') {
5154 parse_expr_type(&type1);
5155 /* remove all storage modifiers except typedef */
5156 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
5157 if (type1.ref)
5158 sym_to_attr(ad, type1.ref);
5159 goto basic_type2;
5161 break;
5162 case TOK_CONST1:
5163 case TOK_CONST2:
5164 case TOK_CONST3:
5165 type->t = t;
5166 parse_btype_qualify(type, VT_CONSTANT);
5167 t = type->t;
5168 next();
5169 break;
5170 case TOK_VOLATILE1:
5171 case TOK_VOLATILE2:
5172 case TOK_VOLATILE3:
5173 type->t = t;
5174 parse_btype_qualify(type, VT_VOLATILE);
5175 t = type->t;
5176 next();
5177 break;
5178 case TOK_SIGNED1:
5179 case TOK_SIGNED2:
5180 case TOK_SIGNED3:
5181 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
5182 tcc_error("signed and unsigned modifier");
5183 t |= VT_DEFSIGN;
5184 next();
5185 typespec_found = 1;
5186 break;
5187 case TOK_REGISTER:
5188 case TOK_AUTO:
5189 case TOK_RESTRICT1:
5190 case TOK_RESTRICT2:
5191 case TOK_RESTRICT3:
5192 next();
5193 break;
5194 case TOK_UNSIGNED:
5195 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
5196 tcc_error("signed and unsigned modifier");
5197 t |= VT_DEFSIGN | VT_UNSIGNED;
5198 next();
5199 typespec_found = 1;
5200 break;
5202 /* storage */
5203 case TOK_EXTERN:
5204 g = VT_EXTERN;
5205 goto storage;
5206 case TOK_STATIC:
5207 g = VT_STATIC;
5208 goto storage;
5209 case TOK_TYPEDEF:
5210 g = VT_TYPEDEF;
5211 goto storage;
5212 storage:
5213 if (t & (VT_EXTERN|VT_STATIC|VT_TYPEDEF) & ~g)
5214 tcc_error("multiple storage classes");
5215 t |= g;
5216 next();
5217 break;
5218 case TOK_INLINE1:
5219 case TOK_INLINE2:
5220 case TOK_INLINE3:
5221 t |= VT_INLINE;
5222 next();
5223 break;
5224 case TOK_NORETURN3:
5225 next();
5226 ad->f.func_noreturn = 1;
5227 break;
5228 /* GNUC attribute */
5229 case TOK_ATTRIBUTE1:
5230 case TOK_ATTRIBUTE2:
5231 parse_attribute(ad);
5232 if (ad->attr_mode) {
5233 u = ad->attr_mode -1;
5234 t = (t & ~(VT_BTYPE|VT_LONG)) | u;
5236 continue;
5237 /* GNUC typeof */
5238 case TOK_TYPEOF1:
5239 case TOK_TYPEOF2:
5240 case TOK_TYPEOF3:
5241 next();
5242 parse_expr_type(&type1);
5243 /* remove all storage modifiers except typedef */
5244 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
5245 if (type1.ref)
5246 sym_to_attr(ad, type1.ref);
5247 goto basic_type2;
5248 default:
5249 if (typespec_found)
5250 goto the_end;
5251 s = sym_find(tok);
5252 if (!s || !(s->type.t & VT_TYPEDEF))
5253 goto the_end;
5255 n = tok, next();
5256 if (tok == ':' && !in_generic) {
5257 /* ignore if it's a label */
5258 unget_tok(n);
5259 goto the_end;
5262 t &= ~(VT_BTYPE|VT_LONG);
5263 u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u;
5264 type->t = (s->type.t & ~VT_TYPEDEF) | u;
5265 type->ref = s->type.ref;
5266 if (t)
5267 parse_btype_qualify(type, t);
5268 t = type->t;
5269 /* get attributes from typedef */
5270 sym_to_attr(ad, s);
5271 typespec_found = 1;
5272 st = bt = -2;
5273 break;
5275 type_found = 1;
5277 the_end:
5278 if (tcc_state->char_is_unsigned) {
5279 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
5280 t |= VT_UNSIGNED;
5282 /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
5283 bt = t & (VT_BTYPE|VT_LONG);
5284 if (bt == VT_LONG)
5285 t |= LONG_SIZE == 8 ? VT_LLONG : VT_INT;
5286 #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
5287 if (bt == VT_LDOUBLE)
5288 t = (t & ~(VT_BTYPE|VT_LONG)) | (VT_DOUBLE|VT_LONG);
5289 #endif
5290 type->t = t;
5291 return type_found;
5294 /* convert a function parameter type (array to pointer and function to
5295 function pointer) */
5296 static inline void convert_parameter_type(CType *pt)
5298 /* remove const and volatile qualifiers (XXX: const could be used
5299 to indicate a const function parameter */
5300 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
5301 /* array must be transformed to pointer according to ANSI C */
5302 pt->t &= ~VT_ARRAY;
5303 if ((pt->t & VT_BTYPE) == VT_FUNC) {
5304 mk_pointer(pt);
5308 ST_FUNC void parse_asm_str(CString *astr)
5310 skip('(');
5311 parse_mult_str(astr, "string constant");
5314 /* Parse an asm label and return the token */
5315 static int asm_label_instr(void)
5317 int v;
5318 CString astr;
5320 next();
5321 parse_asm_str(&astr);
5322 skip(')');
5323 #ifdef ASM_DEBUG
5324 printf("asm_alias: \"%s\"\n", (char *)astr.data);
5325 #endif
5326 v = tok_alloc(astr.data, astr.size - 1)->tok;
5327 cstr_free(&astr);
5328 return v;
5331 static int post_type(CType *type, AttributeDef *ad, int storage, int td)
5333 int n, l, t1, arg_size, align, unused_align;
5334 Sym **plast, *s, *first;
5335 AttributeDef ad1;
5336 CType pt;
5337 TokenString *vla_array_tok = NULL;
5338 int *vla_array_str = NULL;
5340 if (tok == '(') {
5341 /* function type, or recursive declarator (return if so) */
5342 next();
5343 if (TYPE_DIRECT == (td & (TYPE_DIRECT|TYPE_ABSTRACT)))
5344 return 0;
5345 if (tok == ')')
5346 l = 0;
5347 else if (parse_btype(&pt, &ad1))
5348 l = FUNC_NEW;
5349 else if (td & (TYPE_DIRECT|TYPE_ABSTRACT)) {
5350 merge_attr (ad, &ad1);
5351 return 0;
5352 } else
5353 l = FUNC_OLD;
5355 first = NULL;
5356 plast = &first;
5357 arg_size = 0;
5358 ++local_scope;
5359 if (l) {
5360 for(;;) {
5361 /* read param name and compute offset */
5362 if (l != FUNC_OLD) {
5363 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
5364 break;
5365 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT | TYPE_PARAM);
5366 if ((pt.t & VT_BTYPE) == VT_VOID)
5367 tcc_error("parameter declared as void");
5368 if (n == 0)
5369 n = SYM_FIELD;
5370 } else {
5371 n = tok;
5372 pt.t = VT_VOID; /* invalid type */
5373 pt.ref = NULL;
5374 next();
5376 if (n < TOK_UIDENT)
5377 expect("identifier");
5378 convert_parameter_type(&pt);
5379 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
5380 s = sym_push(n, &pt, 0, 0);
5381 *plast = s;
5382 plast = &s->next;
5383 if (tok == ')')
5384 break;
5385 skip(',');
5386 if (l == FUNC_NEW && tok == TOK_DOTS) {
5387 l = FUNC_ELLIPSIS;
5388 next();
5389 break;
5391 if (l == FUNC_NEW && !parse_btype(&pt, &ad1))
5392 tcc_error("invalid type");
5394 } else
5395 /* if no parameters, then old type prototype */
5396 l = FUNC_OLD;
5397 skip(')');
5398 /* remove parameter symbols from token table, keep on stack */
5399 if (first) {
5400 sym_pop(local_stack ? &local_stack : &global_stack, first->prev, 1);
5401 for (s = first; s; s = s->next)
5402 s->v |= SYM_FIELD;
5404 --local_scope;
5405 /* NOTE: const is ignored in returned type as it has a special
5406 meaning in gcc / C++ */
5407 type->t &= ~VT_CONSTANT;
5408 /* some ancient pre-K&R C allows a function to return an array
5409 and the array brackets to be put after the arguments, such
5410 that "int c()[]" means something like "int[] c()" */
5411 if (tok == '[') {
5412 next();
5413 skip(']'); /* only handle simple "[]" */
5414 mk_pointer(type);
5416 /* we push a anonymous symbol which will contain the function prototype */
5417 ad->f.func_args = arg_size;
5418 ad->f.func_type = l;
5419 s = sym_push(SYM_FIELD, type, 0, 0);
5420 s->a = ad->a;
5421 s->f = ad->f;
5422 s->next = first;
5423 type->t = VT_FUNC;
5424 type->ref = s;
5425 } else if (tok == '[') {
5426 int saved_nocode_wanted = nocode_wanted;
5427 /* array definition */
5428 next();
5429 n = -1;
5430 t1 = 0;
5431 if (td & TYPE_PARAM) while (1) {
5432 /* XXX The optional type-quals and static should only be accepted
5433 in parameter decls. The '*' as well, and then even only
5434 in prototypes (not function defs). */
5435 switch (tok) {
5436 case TOK_RESTRICT1: case TOK_RESTRICT2: case TOK_RESTRICT3:
5437 case TOK_CONST1:
5438 case TOK_VOLATILE1:
5439 case TOK_STATIC:
5440 case '*':
5441 next();
5442 continue;
5443 default:
5444 break;
5446 if (tok != ']') {
5447 int nest = 1;
5449 /* Code generation is not done now but has to be done
5450 at start of function. Save code here for later use. */
5451 nocode_wanted = 1;
5452 vla_array_tok = tok_str_alloc();
5453 for (;;) {
5454 if (tok == ']') {
5455 nest--;
5456 if (nest == 0)
5457 break;
5459 if (tok == '[')
5460 nest++;
5461 tok_str_add_tok(vla_array_tok);
5462 next();
5464 unget_tok(0);
5465 tok_str_add(vla_array_tok, -1);
5466 tok_str_add(vla_array_tok, 0);
5467 vla_array_str = vla_array_tok->str;
5468 begin_macro(vla_array_tok, 2);
5469 next();
5470 gexpr();
5471 end_macro();
5472 next();
5473 goto check;
5475 break;
5477 } else if (tok != ']') {
5478 if (!local_stack || (storage & VT_STATIC))
5479 vpushi(expr_const());
5480 else {
5481 /* VLAs (which can only happen with local_stack && !VT_STATIC)
5482 length must always be evaluated, even under nocode_wanted,
5483 so that its size slot is initialized (e.g. under sizeof
5484 or typeof). */
5485 nocode_wanted = 0;
5486 gexpr();
5488 check:
5489 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
5490 n = vtop->c.i;
5491 if (n < 0)
5492 tcc_error("invalid array size");
5493 } else {
5494 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
5495 tcc_error("size of variable length array should be an integer");
5496 n = 0;
5497 t1 = VT_VLA;
5500 skip(']');
5501 /* parse next post type */
5502 post_type(type, ad, storage, (td & ~(TYPE_DIRECT|TYPE_ABSTRACT)) | TYPE_NEST);
5504 if ((type->t & VT_BTYPE) == VT_FUNC)
5505 tcc_error("declaration of an array of functions");
5506 if ((type->t & VT_BTYPE) == VT_VOID
5507 || type_size(type, &unused_align) < 0)
5508 tcc_error("declaration of an array of incomplete type elements");
5510 t1 |= type->t & VT_VLA;
5512 if (t1 & VT_VLA) {
5513 if (n < 0) {
5514 if (td & TYPE_NEST)
5515 tcc_error("need explicit inner array size in VLAs");
5517 else {
5518 loc -= type_size(&int_type, &align);
5519 loc &= -align;
5520 n = loc;
5522 vpush_type_size(type, &align);
5523 gen_op('*');
5524 vset(&int_type, VT_LOCAL|VT_LVAL, n);
5525 vswap();
5526 vstore();
5529 if (n != -1)
5530 vpop();
5531 nocode_wanted = saved_nocode_wanted;
5533 /* we push an anonymous symbol which will contain the array
5534 element type */
5535 s = sym_push(SYM_FIELD, type, 0, n);
5536 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
5537 type->ref = s;
5538 if (vla_array_str) {
5539 if (t1 & VT_VLA)
5540 s->vla_array_str = vla_array_str;
5541 else
5542 tok_str_free_str(vla_array_str);
5545 return 1;
5548 /* Parse a type declarator (except basic type), and return the type
5549 in 'type'. 'td' is a bitmask indicating which kind of type decl is
5550 expected. 'type' should contain the basic type. 'ad' is the
5551 attribute definition of the basic type. It can be modified by
5552 type_decl(). If this (possibly abstract) declarator is a pointer chain
5553 it returns the innermost pointed to type (equals *type, but is a different
5554 pointer), otherwise returns type itself, that's used for recursive calls. */
5555 static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td)
5557 CType *post, *ret;
5558 int qualifiers, storage;
5560 /* recursive type, remove storage bits first, apply them later again */
5561 storage = type->t & VT_STORAGE;
5562 type->t &= ~VT_STORAGE;
5563 post = ret = type;
5565 while (tok == '*') {
5566 qualifiers = 0;
5567 redo:
5568 next();
5569 switch(tok) {
5570 case TOK__Atomic:
5571 qualifiers |= VT_ATOMIC;
5572 goto redo;
5573 case TOK_CONST1:
5574 case TOK_CONST2:
5575 case TOK_CONST3:
5576 qualifiers |= VT_CONSTANT;
5577 goto redo;
5578 case TOK_VOLATILE1:
5579 case TOK_VOLATILE2:
5580 case TOK_VOLATILE3:
5581 qualifiers |= VT_VOLATILE;
5582 goto redo;
5583 case TOK_RESTRICT1:
5584 case TOK_RESTRICT2:
5585 case TOK_RESTRICT3:
5586 goto redo;
5587 /* XXX: clarify attribute handling */
5588 case TOK_ATTRIBUTE1:
5589 case TOK_ATTRIBUTE2:
5590 parse_attribute(ad);
5591 break;
5593 mk_pointer(type);
5594 type->t |= qualifiers;
5595 if (ret == type)
5596 /* innermost pointed to type is the one for the first derivation */
5597 ret = pointed_type(type);
5600 if (tok == '(') {
5601 /* This is possibly a parameter type list for abstract declarators
5602 ('int ()'), use post_type for testing this. */
5603 if (!post_type(type, ad, 0, td)) {
5604 /* It's not, so it's a nested declarator, and the post operations
5605 apply to the innermost pointed to type (if any). */
5606 /* XXX: this is not correct to modify 'ad' at this point, but
5607 the syntax is not clear */
5608 parse_attribute(ad);
5609 post = type_decl(type, ad, v, td);
5610 skip(')');
5611 } else
5612 goto abstract;
5613 } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
5614 /* type identifier */
5615 *v = tok;
5616 next();
5617 } else {
5618 abstract:
5619 if (!(td & TYPE_ABSTRACT))
5620 expect("identifier");
5621 *v = 0;
5623 post_type(post, ad, storage, td & ~(TYPE_DIRECT|TYPE_ABSTRACT));
5624 parse_attribute(ad);
5625 type->t |= storage;
5626 return ret;
5629 /* indirection with full error checking and bound check */
5630 ST_FUNC void indir(void)
5632 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
5633 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
5634 return;
5635 expect("pointer");
5637 if (vtop->r & VT_LVAL)
5638 gv(RC_INT);
5639 vtop->type = *pointed_type(&vtop->type);
5640 /* Arrays and functions are never lvalues */
5641 if (!(vtop->type.t & (VT_ARRAY | VT_VLA))
5642 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
5643 vtop->r |= VT_LVAL;
5644 /* if bound checking, the referenced pointer must be checked */
5645 #ifdef CONFIG_TCC_BCHECK
5646 if (tcc_state->do_bounds_check)
5647 vtop->r |= VT_MUSTBOUND;
5648 #endif
5652 /* pass a parameter to a function and do type checking and casting */
5653 static void gfunc_param_typed(Sym *func, Sym *arg)
5655 int func_type;
5656 CType type;
5658 func_type = func->f.func_type;
5659 if (func_type == FUNC_OLD ||
5660 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
5661 /* default casting : only need to convert float to double */
5662 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
5663 gen_cast_s(VT_DOUBLE);
5664 } else if (vtop->type.t & VT_BITFIELD) {
5665 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
5666 type.ref = vtop->type.ref;
5667 gen_cast(&type);
5668 } else if (vtop->r & VT_MUSTCAST) {
5669 force_charshort_cast();
5671 } else if (arg == NULL) {
5672 tcc_error("too many arguments to function");
5673 } else {
5674 type = arg->type;
5675 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
5676 gen_assign_cast(&type);
5680 /* parse an expression and return its type without any side effect. */
5681 static void expr_type(CType *type, void (*expr_fn)(void))
5683 nocode_wanted++;
5684 expr_fn();
5685 *type = vtop->type;
5686 vpop();
5687 nocode_wanted--;
5690 /* parse an expression of the form '(type)' or '(expr)' and return its
5691 type */
5692 static void parse_expr_type(CType *type)
5694 int n;
5695 AttributeDef ad;
5697 skip('(');
5698 if (parse_btype(type, &ad)) {
5699 type_decl(type, &ad, &n, TYPE_ABSTRACT);
5700 } else {
5701 expr_type(type, gexpr);
5703 skip(')');
5706 static void parse_type(CType *type)
5708 AttributeDef ad;
5709 int n;
5711 if (!parse_btype(type, &ad)) {
5712 expect("type");
5714 type_decl(type, &ad, &n, TYPE_ABSTRACT);
5717 static void parse_builtin_params(int nc, const char *args)
5719 char c, sep = '(';
5720 CType type;
5721 if (nc)
5722 nocode_wanted++;
5723 next();
5724 if (*args == 0)
5725 skip(sep);
5726 while ((c = *args++)) {
5727 skip(sep);
5728 sep = ',';
5729 if (c == 't') {
5730 parse_type(&type);
5731 vpush(&type);
5732 continue;
5734 expr_eq();
5735 type.ref = NULL;
5736 type.t = 0;
5737 switch (c) {
5738 case 'e':
5739 continue;
5740 case 'V':
5741 type.t = VT_CONSTANT;
5742 case 'v':
5743 type.t |= VT_VOID;
5744 mk_pointer (&type);
5745 break;
5746 case 'S':
5747 type.t = VT_CONSTANT;
5748 case 's':
5749 type.t |= char_type.t;
5750 mk_pointer (&type);
5751 break;
5752 case 'i':
5753 type.t = VT_INT;
5754 break;
5755 case 'l':
5756 type.t = VT_SIZE_T;
5757 break;
5758 default:
5759 break;
5761 gen_assign_cast(&type);
5763 skip(')');
5764 if (nc)
5765 nocode_wanted--;
5768 static void parse_atomic(int atok)
5770 int size, align, arg;
5771 CType *atom, *atom_ptr, ct = {0};
5772 char buf[40];
5773 static const char *const templates[] = {
5775 * Each entry consists of callback and function template.
5776 * The template represents argument types and return type.
5778 * ? void (return-only)
5779 * b bool
5780 * a atomic
5781 * A read-only atomic
5782 * p pointer to memory
5783 * v value
5784 * m memory model
5787 /* keep in order of appearance in tcctok.h: */
5788 /* __atomic_store */ "avm.?",
5789 /* __atomic_load */ "Am.v",
5790 /* __atomic_exchange */ "avm.v",
5791 /* __atomic_compare_exchange */ "apvbmm.b",
5792 /* __atomic_fetch_add */ "avm.v",
5793 /* __atomic_fetch_sub */ "avm.v",
5794 /* __atomic_fetch_or */ "avm.v",
5795 /* __atomic_fetch_xor */ "avm.v",
5796 /* __atomic_fetch_and */ "avm.v"
5798 const char *template = templates[(atok - TOK___atomic_store)];
5800 atom = atom_ptr = NULL;
5801 size = 0; /* pacify compiler */
5802 next();
5803 skip('(');
5804 for (arg = 0;;) {
5805 expr_eq();
5806 switch (template[arg]) {
5807 case 'a':
5808 case 'A':
5809 atom_ptr = &vtop->type;
5810 if ((atom_ptr->t & VT_BTYPE) != VT_PTR)
5811 expect("pointer");
5812 atom = pointed_type(atom_ptr);
5813 size = type_size(atom, &align);
5814 if (size > 8
5815 || (size & (size - 1))
5816 || (atok > TOK___atomic_compare_exchange
5817 && (0 == btype_size(atom->t & VT_BTYPE)
5818 || (atom->t & VT_BTYPE) == VT_PTR)))
5819 expect("integral or integer-sized pointer target type");
5820 /* GCC does not care either: */
5821 /* if (!(atom->t & VT_ATOMIC))
5822 tcc_warning("pointer target declaration is missing '_Atomic'"); */
5823 break;
5825 case 'p':
5826 if ((vtop->type.t & VT_BTYPE) != VT_PTR
5827 || type_size(pointed_type(&vtop->type), &align) != size)
5828 tcc_error("pointer target type mismatch in argument %d", arg + 1);
5829 gen_assign_cast(atom_ptr);
5830 break;
5831 case 'v':
5832 gen_assign_cast(atom);
5833 break;
5834 case 'm':
5835 gen_assign_cast(&int_type);
5836 break;
5837 case 'b':
5838 ct.t = VT_BOOL;
5839 gen_assign_cast(&ct);
5840 break;
5842 if ('.' == template[++arg])
5843 break;
5844 skip(',');
5846 skip(')');
5848 ct.t = VT_VOID;
5849 switch (template[arg + 1]) {
5850 case 'b':
5851 ct.t = VT_BOOL;
5852 break;
5853 case 'v':
5854 ct = *atom;
5855 break;
5858 sprintf(buf, "%s_%d", get_tok_str(atok, 0), size);
5859 vpush_helper_func(tok_alloc_const(buf));
5860 vrott(arg + 1);
5861 gfunc_call(arg);
5863 vpush(&ct);
5864 PUT_R_RET(vtop, ct.t);
5865 if (ct.t == VT_BOOL) {
5866 #ifdef PROMOTE_RET
5867 vtop->r |= BFVAL(VT_MUSTCAST, 1);
5868 #else
5869 vtop->type.t = VT_INT;
5870 #endif
5874 ST_FUNC void unary(void)
5876 int n, t, align, size, r, sizeof_caller;
5877 CType type;
5878 Sym *s;
5879 AttributeDef ad;
5881 /* generate line number info */
5882 if (debug_modes)
5883 tcc_debug_line(tcc_state), tcc_tcov_check_line (1);
5885 sizeof_caller = in_sizeof;
5886 in_sizeof = 0;
5887 type.ref = NULL;
5888 /* XXX: GCC 2.95.3 does not generate a table although it should be
5889 better here */
5890 tok_next:
5891 switch(tok) {
5892 case TOK_EXTENSION:
5893 next();
5894 goto tok_next;
5895 case TOK_LCHAR:
5896 #ifdef TCC_TARGET_PE
5897 t = VT_SHORT|VT_UNSIGNED;
5898 goto push_tokc;
5899 #endif
5900 case TOK_CINT:
5901 case TOK_CCHAR:
5902 t = VT_INT;
5903 push_tokc:
5904 type.t = t;
5905 vsetc(&type, VT_CONST, &tokc);
5906 next();
5907 break;
5908 case TOK_CUINT:
5909 t = VT_INT | VT_UNSIGNED;
5910 goto push_tokc;
5911 case TOK_CLLONG:
5912 t = VT_LLONG;
5913 goto push_tokc;
5914 case TOK_CULLONG:
5915 t = VT_LLONG | VT_UNSIGNED;
5916 goto push_tokc;
5917 case TOK_CFLOAT:
5918 t = VT_FLOAT;
5919 goto push_tokc;
5920 case TOK_CDOUBLE:
5921 t = VT_DOUBLE;
5922 goto push_tokc;
5923 case TOK_CLDOUBLE:
5924 t = VT_LDOUBLE;
5925 goto push_tokc;
5926 case TOK_CLONG:
5927 t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG;
5928 goto push_tokc;
5929 case TOK_CULONG:
5930 t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG | VT_UNSIGNED;
5931 goto push_tokc;
5932 case TOK___FUNCTION__:
5933 if (!gnu_ext)
5934 goto tok_identifier;
5935 /* fall thru */
5936 case TOK___FUNC__:
5938 Section *sec;
5939 int len;
5940 /* special function name identifier */
5941 len = strlen(funcname) + 1;
5942 /* generate char[len] type */
5943 type.t = char_type.t;
5944 if (tcc_state->warn_write_strings & WARN_ON)
5945 type.t |= VT_CONSTANT;
5946 mk_pointer(&type);
5947 type.t |= VT_ARRAY;
5948 type.ref->c = len;
5949 sec = rodata_section;
5950 vpush_ref(&type, sec, sec->data_offset, len);
5951 if (!NODATA_WANTED)
5952 memcpy(section_ptr_add(sec, len), funcname, len);
5953 next();
5955 break;
5956 case TOK_LSTR:
5957 #ifdef TCC_TARGET_PE
5958 t = VT_SHORT | VT_UNSIGNED;
5959 #else
5960 t = VT_INT;
5961 #endif
5962 goto str_init;
5963 case TOK_STR:
5964 /* string parsing */
5965 t = char_type.t;
5966 str_init:
5967 if (tcc_state->warn_write_strings & WARN_ON)
5968 t |= VT_CONSTANT;
5969 type.t = t;
5970 mk_pointer(&type);
5971 type.t |= VT_ARRAY;
5972 memset(&ad, 0, sizeof(AttributeDef));
5973 ad.section = rodata_section;
5974 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
5975 break;
5976 case '(':
5977 next();
5978 /* cast ? */
5979 if (parse_btype(&type, &ad)) {
5980 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
5981 skip(')');
5982 /* check ISOC99 compound literal */
5983 if (tok == '{') {
5984 /* data is allocated locally by default */
5985 if (global_expr)
5986 r = VT_CONST;
5987 else
5988 r = VT_LOCAL;
5989 /* all except arrays are lvalues */
5990 if (!(type.t & VT_ARRAY))
5991 r |= VT_LVAL;
5992 memset(&ad, 0, sizeof(AttributeDef));
5993 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
5994 } else {
5995 if (sizeof_caller) {
5996 vpush(&type);
5997 return;
5999 unary();
6000 gen_cast(&type);
6002 } else if (tok == '{') {
6003 int saved_nocode_wanted = nocode_wanted;
6004 if (const_wanted && !(nocode_wanted & unevalmask))
6005 expect("constant");
6006 if (0 == local_scope)
6007 tcc_error("statement expression outside of function");
6008 /* save all registers */
6009 save_regs(0);
6010 /* statement expression : we do not accept break/continue
6011 inside as GCC does. We do retain the nocode_wanted state,
6012 as statement expressions can't ever be entered from the
6013 outside, so any reactivation of code emission (from labels
6014 or loop heads) can be disabled again after the end of it. */
6015 block(1);
6016 /* or'ing to keep however possible CODE_OFF() from e.g. "return 0;"
6017 in the statement expression */
6018 nocode_wanted |= saved_nocode_wanted;
6019 skip(')');
6020 } else {
6021 gexpr();
6022 skip(')');
6024 break;
6025 case '*':
6026 next();
6027 unary();
6028 indir();
6029 break;
6030 case '&':
6031 next();
6032 unary();
6033 /* functions names must be treated as function pointers,
6034 except for unary '&' and sizeof. Since we consider that
6035 functions are not lvalues, we only have to handle it
6036 there and in function calls. */
6037 /* arrays can also be used although they are not lvalues */
6038 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
6039 !(vtop->type.t & VT_ARRAY))
6040 test_lvalue();
6041 if (vtop->sym)
6042 vtop->sym->a.addrtaken = 1;
6043 mk_pointer(&vtop->type);
6044 gaddrof();
6045 break;
6046 case '!':
6047 next();
6048 unary();
6049 gen_test_zero(TOK_EQ);
6050 break;
6051 case '~':
6052 next();
6053 unary();
6054 vpushi(-1);
6055 gen_op('^');
6056 break;
6057 case '+':
6058 next();
6059 unary();
6060 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
6061 tcc_error("pointer not accepted for unary plus");
6062 /* In order to force cast, we add zero, except for floating point
6063 where we really need an noop (otherwise -0.0 will be transformed
6064 into +0.0). */
6065 if (!is_float(vtop->type.t)) {
6066 vpushi(0);
6067 gen_op('+');
6069 break;
6070 case TOK_SIZEOF:
6071 case TOK_ALIGNOF1:
6072 case TOK_ALIGNOF2:
6073 case TOK_ALIGNOF3:
6074 t = tok;
6075 next();
6076 in_sizeof++;
6077 expr_type(&type, unary); /* Perform a in_sizeof = 0; */
6078 if (t == TOK_SIZEOF) {
6079 vpush_type_size(&type, &align);
6080 gen_cast_s(VT_SIZE_T);
6081 } else {
6082 type_size(&type, &align);
6083 s = NULL;
6084 if (vtop[1].r & VT_SYM)
6085 s = vtop[1].sym; /* hack: accessing previous vtop */
6086 if (s && s->a.aligned)
6087 align = 1 << (s->a.aligned - 1);
6088 vpushs(align);
6090 break;
6092 case TOK_builtin_expect:
6093 /* __builtin_expect is a no-op for now */
6094 parse_builtin_params(0, "ee");
6095 vpop();
6096 break;
6097 case TOK_builtin_types_compatible_p:
6098 parse_builtin_params(0, "tt");
6099 vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
6100 vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
6101 n = is_compatible_types(&vtop[-1].type, &vtop[0].type);
6102 vtop -= 2;
6103 vpushi(n);
6104 break;
6105 case TOK_builtin_choose_expr:
6107 int64_t c;
6108 next();
6109 skip('(');
6110 c = expr_const64();
6111 skip(',');
6112 if (!c) {
6113 nocode_wanted++;
6115 expr_eq();
6116 if (!c) {
6117 vpop();
6118 nocode_wanted--;
6120 skip(',');
6121 if (c) {
6122 nocode_wanted++;
6124 expr_eq();
6125 if (c) {
6126 vpop();
6127 nocode_wanted--;
6129 skip(')');
6131 break;
6132 case TOK_builtin_constant_p:
6133 parse_builtin_params(1, "e");
6134 n = (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
6135 !((vtop->r & VT_SYM) && vtop->sym->a.addrtaken);
6136 vtop--;
6137 vpushi(n);
6138 break;
6139 case TOK_builtin_frame_address:
6140 case TOK_builtin_return_address:
6142 int tok1 = tok;
6143 int level;
6144 next();
6145 skip('(');
6146 if (tok != TOK_CINT) {
6147 tcc_error("%s only takes positive integers",
6148 tok1 == TOK_builtin_return_address ?
6149 "__builtin_return_address" :
6150 "__builtin_frame_address");
6152 level = (uint32_t)tokc.i;
6153 next();
6154 skip(')');
6155 type.t = VT_VOID;
6156 mk_pointer(&type);
6157 vset(&type, VT_LOCAL, 0); /* local frame */
6158 while (level--) {
6159 #ifdef TCC_TARGET_RISCV64
6160 vpushi(2*PTR_SIZE);
6161 gen_op('-');
6162 #endif
6163 mk_pointer(&vtop->type);
6164 indir(); /* -> parent frame */
6166 if (tok1 == TOK_builtin_return_address) {
6167 // assume return address is just above frame pointer on stack
6168 #ifdef TCC_TARGET_ARM
6169 vpushi(2*PTR_SIZE);
6170 gen_op('+');
6171 #elif defined TCC_TARGET_RISCV64
6172 vpushi(PTR_SIZE);
6173 gen_op('-');
6174 #else
6175 vpushi(PTR_SIZE);
6176 gen_op('+');
6177 #endif
6178 mk_pointer(&vtop->type);
6179 indir();
6182 break;
6183 #ifdef TCC_TARGET_RISCV64
6184 case TOK_builtin_va_start:
6185 parse_builtin_params(0, "ee");
6186 r = vtop->r & VT_VALMASK;
6187 if (r == VT_LLOCAL)
6188 r = VT_LOCAL;
6189 if (r != VT_LOCAL)
6190 tcc_error("__builtin_va_start expects a local variable");
6191 gen_va_start();
6192 vstore();
6193 break;
6194 #endif
6195 #ifdef TCC_TARGET_X86_64
6196 #ifdef TCC_TARGET_PE
6197 case TOK_builtin_va_start:
6198 parse_builtin_params(0, "ee");
6199 r = vtop->r & VT_VALMASK;
6200 if (r == VT_LLOCAL)
6201 r = VT_LOCAL;
6202 if (r != VT_LOCAL)
6203 tcc_error("__builtin_va_start expects a local variable");
6204 vtop->r = r;
6205 vtop->type = char_pointer_type;
6206 vtop->c.i += 8;
6207 vstore();
6208 break;
6209 #else
6210 case TOK_builtin_va_arg_types:
6211 parse_builtin_params(0, "t");
6212 vpushi(classify_x86_64_va_arg(&vtop->type));
6213 vswap();
6214 vpop();
6215 break;
6216 #endif
6217 #endif
6219 #ifdef TCC_TARGET_ARM64
6220 case TOK_builtin_va_start: {
6221 parse_builtin_params(0, "ee");
6222 //xx check types
6223 gen_va_start();
6224 vpushi(0);
6225 vtop->type.t = VT_VOID;
6226 break;
6228 case TOK_builtin_va_arg: {
6229 parse_builtin_params(0, "et");
6230 type = vtop->type;
6231 vpop();
6232 //xx check types
6233 gen_va_arg(&type);
6234 vtop->type = type;
6235 break;
6237 case TOK___arm64_clear_cache: {
6238 parse_builtin_params(0, "ee");
6239 gen_clear_cache();
6240 vpushi(0);
6241 vtop->type.t = VT_VOID;
6242 break;
6244 #endif
6246 /* atomic operations */
6247 case TOK___atomic_store:
6248 case TOK___atomic_load:
6249 case TOK___atomic_exchange:
6250 case TOK___atomic_compare_exchange:
6251 case TOK___atomic_fetch_add:
6252 case TOK___atomic_fetch_sub:
6253 case TOK___atomic_fetch_or:
6254 case TOK___atomic_fetch_xor:
6255 case TOK___atomic_fetch_and:
6256 parse_atomic(tok);
6257 break;
6259 /* pre operations */
6260 case TOK_INC:
6261 case TOK_DEC:
6262 t = tok;
6263 next();
6264 unary();
6265 inc(0, t);
6266 break;
6267 case '-':
6268 next();
6269 unary();
6270 if (is_float(vtop->type.t)) {
6271 gen_opif(TOK_NEG);
6272 } else {
6273 vpushi(0);
6274 vswap();
6275 gen_op('-');
6277 break;
6278 case TOK_LAND:
6279 if (!gnu_ext)
6280 goto tok_identifier;
6281 next();
6282 /* allow to take the address of a label */
6283 if (tok < TOK_UIDENT)
6284 expect("label identifier");
6285 s = label_find(tok);
6286 if (!s) {
6287 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
6288 } else {
6289 if (s->r == LABEL_DECLARED)
6290 s->r = LABEL_FORWARD;
6292 if (!s->type.t) {
6293 s->type.t = VT_VOID;
6294 mk_pointer(&s->type);
6295 s->type.t |= VT_STATIC;
6297 vpushsym(&s->type, s);
6298 next();
6299 break;
6301 case TOK_GENERIC:
6303 CType controlling_type;
6304 int has_default = 0;
6305 int has_match = 0;
6306 int learn = 0;
6307 TokenString *str = NULL;
6308 int saved_const_wanted = const_wanted;
6310 next();
6311 skip('(');
6312 const_wanted = 0;
6313 expr_type(&controlling_type, expr_eq);
6314 controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY);
6315 if ((controlling_type.t & VT_BTYPE) == VT_FUNC)
6316 mk_pointer(&controlling_type);
6317 const_wanted = saved_const_wanted;
6318 for (;;) {
6319 learn = 0;
6320 skip(',');
6321 if (tok == TOK_DEFAULT) {
6322 if (has_default)
6323 tcc_error("too many 'default'");
6324 has_default = 1;
6325 if (!has_match)
6326 learn = 1;
6327 next();
6328 } else {
6329 AttributeDef ad_tmp;
6330 int itmp;
6331 CType cur_type;
6333 in_generic++;
6334 parse_btype(&cur_type, &ad_tmp);
6335 in_generic--;
6337 type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
6338 if (compare_types(&controlling_type, &cur_type, 0)) {
6339 if (has_match) {
6340 tcc_error("type match twice");
6342 has_match = 1;
6343 learn = 1;
6346 skip(':');
6347 if (learn) {
6348 if (str)
6349 tok_str_free(str);
6350 skip_or_save_block(&str);
6351 } else {
6352 skip_or_save_block(NULL);
6354 if (tok == ')')
6355 break;
6357 if (!str) {
6358 char buf[60];
6359 type_to_str(buf, sizeof buf, &controlling_type, NULL);
6360 tcc_error("type '%s' does not match any association", buf);
6362 begin_macro(str, 1);
6363 next();
6364 expr_eq();
6365 if (tok != TOK_EOF)
6366 expect(",");
6367 end_macro();
6368 next();
6369 break;
6371 // special qnan , snan and infinity values
6372 case TOK___NAN__:
6373 n = 0x7fc00000;
6374 special_math_val:
6375 vpushi(n);
6376 vtop->type.t = VT_FLOAT;
6377 next();
6378 break;
6379 case TOK___SNAN__:
6380 n = 0x7f800001;
6381 goto special_math_val;
6382 case TOK___INF__:
6383 n = 0x7f800000;
6384 goto special_math_val;
6386 default:
6387 tok_identifier:
6388 t = tok;
6389 next();
6390 if (t < TOK_UIDENT)
6391 expect("identifier");
6392 s = sym_find(t);
6393 if (!s || IS_ASM_SYM(s)) {
6394 const char *name = get_tok_str(t, NULL);
6395 if (tok != '(')
6396 tcc_error("'%s' undeclared", name);
6397 /* for simple function calls, we tolerate undeclared
6398 external reference to int() function */
6399 tcc_warning_c(warn_implicit_function_declaration)(
6400 "implicit declaration of function '%s'", name);
6401 s = external_global_sym(t, &func_old_type);
6404 r = s->r;
6405 /* A symbol that has a register is a local register variable,
6406 which starts out as VT_LOCAL value. */
6407 if ((r & VT_VALMASK) < VT_CONST)
6408 r = (r & ~VT_VALMASK) | VT_LOCAL;
6410 vset(&s->type, r, s->c);
6411 /* Point to s as backpointer (even without r&VT_SYM).
6412 Will be used by at least the x86 inline asm parser for
6413 regvars. */
6414 vtop->sym = s;
6416 if (r & VT_SYM) {
6417 vtop->c.i = 0;
6418 } else if (r == VT_CONST && IS_ENUM_VAL(s->type.t)) {
6419 vtop->c.i = s->enum_val;
6421 break;
6424 /* post operations */
6425 while (1) {
6426 if (tok == TOK_INC || tok == TOK_DEC) {
6427 inc(1, tok);
6428 next();
6429 } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
6430 int qualifiers, cumofs = 0;
6431 /* field */
6432 if (tok == TOK_ARROW)
6433 indir();
6434 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
6435 test_lvalue();
6436 gaddrof();
6437 /* expect pointer on structure */
6438 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
6439 expect("struct or union");
6440 if (tok == TOK_CDOUBLE)
6441 expect("field name");
6442 next();
6443 if (tok == TOK_CINT || tok == TOK_CUINT)
6444 expect("field name");
6445 s = find_field(&vtop->type, tok, &cumofs);
6446 if (!s)
6447 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc));
6448 /* add field offset to pointer */
6449 vtop->type = char_pointer_type; /* change type to 'char *' */
6450 vpushi(cumofs + s->c);
6451 gen_op('+');
6452 /* change type to field type, and set to lvalue */
6453 vtop->type = s->type;
6454 vtop->type.t |= qualifiers;
6455 /* an array is never an lvalue */
6456 if (!(vtop->type.t & VT_ARRAY)) {
6457 vtop->r |= VT_LVAL;
6458 #ifdef CONFIG_TCC_BCHECK
6459 /* if bound checking, the referenced pointer must be checked */
6460 if (tcc_state->do_bounds_check)
6461 vtop->r |= VT_MUSTBOUND;
6462 #endif
6464 next();
6465 } else if (tok == '[') {
6466 next();
6467 gexpr();
6468 gen_op('+');
6469 indir();
6470 skip(']');
6471 } else if (tok == '(') {
6472 SValue ret;
6473 Sym *sa;
6474 int nb_args, ret_nregs, ret_align, regsize, variadic;
6476 /* function call */
6477 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
6478 /* pointer test (no array accepted) */
6479 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
6480 vtop->type = *pointed_type(&vtop->type);
6481 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
6482 goto error_func;
6483 } else {
6484 error_func:
6485 expect("function pointer");
6487 } else {
6488 vtop->r &= ~VT_LVAL; /* no lvalue */
6490 /* get return type */
6491 s = vtop->type.ref;
6492 next();
6493 sa = s->next; /* first parameter */
6494 nb_args = regsize = 0;
6495 ret.r2 = VT_CONST;
6496 /* compute first implicit argument if a structure is returned */
6497 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
6498 variadic = (s->f.func_type == FUNC_ELLIPSIS);
6499 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
6500 &ret_align, &regsize);
6501 if (ret_nregs <= 0) {
6502 /* get some space for the returned structure */
6503 size = type_size(&s->type, &align);
6504 #ifdef TCC_TARGET_ARM64
6505 /* On arm64, a small struct is return in registers.
6506 It is much easier to write it to memory if we know
6507 that we are allowed to write some extra bytes, so
6508 round the allocated space up to a power of 2: */
6509 if (size < 16)
6510 while (size & (size - 1))
6511 size = (size | (size - 1)) + 1;
6512 #endif
6513 loc = (loc - size) & -align;
6514 ret.type = s->type;
6515 ret.r = VT_LOCAL | VT_LVAL;
6516 /* pass it as 'int' to avoid structure arg passing
6517 problems */
6518 vseti(VT_LOCAL, loc);
6519 #ifdef CONFIG_TCC_BCHECK
6520 if (tcc_state->do_bounds_check)
6521 --loc;
6522 #endif
6523 ret.c = vtop->c;
6524 if (ret_nregs < 0)
6525 vtop--;
6526 else
6527 nb_args++;
6529 } else {
6530 ret_nregs = 1;
6531 ret.type = s->type;
6534 if (ret_nregs > 0) {
6535 /* return in register */
6536 ret.c.i = 0;
6537 PUT_R_RET(&ret, ret.type.t);
6539 if (tok != ')') {
6540 for(;;) {
6541 expr_eq();
6542 gfunc_param_typed(s, sa);
6543 nb_args++;
6544 if (sa)
6545 sa = sa->next;
6546 if (tok == ')')
6547 break;
6548 skip(',');
6551 if (sa)
6552 tcc_error("too few arguments to function");
6553 skip(')');
6554 gfunc_call(nb_args);
6556 if (ret_nregs < 0) {
6557 vsetc(&ret.type, ret.r, &ret.c);
6558 #ifdef TCC_TARGET_RISCV64
6559 arch_transfer_ret_regs(1);
6560 #endif
6561 } else {
6562 /* return value */
6563 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
6564 vsetc(&ret.type, r, &ret.c);
6565 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
6568 /* handle packed struct return */
6569 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
6570 int addr, offset;
6572 size = type_size(&s->type, &align);
6573 /* We're writing whole regs often, make sure there's enough
6574 space. Assume register size is power of 2. */
6575 if (regsize > align)
6576 align = regsize;
6577 loc = (loc - size) & -align;
6578 addr = loc;
6579 offset = 0;
6580 for (;;) {
6581 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
6582 vswap();
6583 vstore();
6584 vtop--;
6585 if (--ret_nregs == 0)
6586 break;
6587 offset += regsize;
6589 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
6592 /* Promote char/short return values. This is matters only
6593 for calling function that were not compiled by TCC and
6594 only on some architectures. For those where it doesn't
6595 matter we expect things to be already promoted to int,
6596 but not larger. */
6597 t = s->type.t & VT_BTYPE;
6598 if (t == VT_BYTE || t == VT_SHORT || t == VT_BOOL) {
6599 #ifdef PROMOTE_RET
6600 vtop->r |= BFVAL(VT_MUSTCAST, 1);
6601 #else
6602 vtop->type.t = VT_INT;
6603 #endif
6606 if (s->f.func_noreturn) {
6607 if (debug_modes)
6608 tcc_tcov_block_end (tcov_data.line);
6609 CODE_OFF();
6611 } else {
6612 break;
6617 #ifndef precedence_parser /* original top-down parser */
6619 static void expr_prod(void)
6621 int t;
6623 unary();
6624 while ((t = tok) == '*' || t == '/' || t == '%') {
6625 next();
6626 unary();
6627 gen_op(t);
6631 static void expr_sum(void)
6633 int t;
6635 expr_prod();
6636 while ((t = tok) == '+' || t == '-') {
6637 next();
6638 expr_prod();
6639 gen_op(t);
6643 static void expr_shift(void)
6645 int t;
6647 expr_sum();
6648 while ((t = tok) == TOK_SHL || t == TOK_SAR) {
6649 next();
6650 expr_sum();
6651 gen_op(t);
6655 static void expr_cmp(void)
6657 int t;
6659 expr_shift();
6660 while (((t = tok) >= TOK_ULE && t <= TOK_GT) ||
6661 t == TOK_ULT || t == TOK_UGE) {
6662 next();
6663 expr_shift();
6664 gen_op(t);
6668 static void expr_cmpeq(void)
6670 int t;
6672 expr_cmp();
6673 while ((t = tok) == TOK_EQ || t == TOK_NE) {
6674 next();
6675 expr_cmp();
6676 gen_op(t);
6680 static void expr_and(void)
6682 expr_cmpeq();
6683 while (tok == '&') {
6684 next();
6685 expr_cmpeq();
6686 gen_op('&');
6690 static void expr_xor(void)
6692 expr_and();
6693 while (tok == '^') {
6694 next();
6695 expr_and();
6696 gen_op('^');
6700 static void expr_or(void)
6702 expr_xor();
6703 while (tok == '|') {
6704 next();
6705 expr_xor();
6706 gen_op('|');
6710 static void expr_landor(int op);
6712 static void expr_land(void)
6714 expr_or();
6715 if (tok == TOK_LAND)
6716 expr_landor(tok);
6719 static void expr_lor(void)
6721 expr_land();
6722 if (tok == TOK_LOR)
6723 expr_landor(tok);
6726 # define expr_landor_next(op) op == TOK_LAND ? expr_or() : expr_land()
6727 #else /* defined precedence_parser */
6728 # define expr_landor_next(op) unary(), expr_infix(precedence(op) + 1)
6729 # define expr_lor() unary(), expr_infix(1)
6731 static int precedence(int tok)
6733 switch (tok) {
6734 case TOK_LOR: return 1;
6735 case TOK_LAND: return 2;
6736 case '|': return 3;
6737 case '^': return 4;
6738 case '&': return 5;
6739 case TOK_EQ: case TOK_NE: return 6;
6740 relat: case TOK_ULT: case TOK_UGE: return 7;
6741 case TOK_SHL: case TOK_SAR: return 8;
6742 case '+': case '-': return 9;
6743 case '*': case '/': case '%': return 10;
6744 default:
6745 if (tok >= TOK_ULE && tok <= TOK_GT)
6746 goto relat;
6747 return 0;
6750 static unsigned char prec[256];
6751 static void init_prec(void)
6753 int i;
6754 for (i = 0; i < 256; i++)
6755 prec[i] = precedence(i);
6757 #define precedence(i) ((unsigned)i < 256 ? prec[i] : 0)
6759 static void expr_landor(int op);
6761 static void expr_infix(int p)
6763 int t = tok, p2;
6764 while ((p2 = precedence(t)) >= p) {
6765 if (t == TOK_LOR || t == TOK_LAND) {
6766 expr_landor(t);
6767 } else {
6768 next();
6769 unary();
6770 if (precedence(tok) > p2)
6771 expr_infix(p2 + 1);
6772 gen_op(t);
6774 t = tok;
6777 #endif
6779 /* Assuming vtop is a value used in a conditional context
6780 (i.e. compared with zero) return 0 if it's false, 1 if
6781 true and -1 if it can't be statically determined. */
6782 static int condition_3way(void)
6784 int c = -1;
6785 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
6786 (!(vtop->r & VT_SYM) || !vtop->sym->a.weak)) {
6787 vdup();
6788 gen_cast_s(VT_BOOL);
6789 c = vtop->c.i;
6790 vpop();
6792 return c;
6795 static void expr_landor(int op)
6797 int t = 0, cc = 1, f = 0, i = op == TOK_LAND, c;
6798 for(;;) {
6799 c = f ? i : condition_3way();
6800 if (c < 0)
6801 save_regs(1), cc = 0;
6802 else if (c != i)
6803 nocode_wanted++, f = 1;
6804 if (tok != op)
6805 break;
6806 if (c < 0)
6807 t = gvtst(i, t);
6808 else
6809 vpop();
6810 next();
6811 expr_landor_next(op);
6813 if (cc || f) {
6814 vpop();
6815 vpushi(i ^ f);
6816 gsym(t);
6817 nocode_wanted -= f;
6818 } else {
6819 gvtst_set(i, t);
6823 static int is_cond_bool(SValue *sv)
6825 if ((sv->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST
6826 && (sv->type.t & VT_BTYPE) == VT_INT)
6827 return (unsigned)sv->c.i < 2;
6828 if (sv->r == VT_CMP)
6829 return 1;
6830 return 0;
6833 static void expr_cond(void)
6835 int tt, u, r1, r2, rc, t1, t2, islv, c, g;
6836 SValue sv;
6837 CType type;
6838 int ncw_prev;
6840 expr_lor();
6841 if (tok == '?') {
6842 next();
6843 c = condition_3way();
6844 g = (tok == ':' && gnu_ext);
6845 tt = 0;
6846 if (!g) {
6847 if (c < 0) {
6848 save_regs(1);
6849 tt = gvtst(1, 0);
6850 } else {
6851 vpop();
6853 } else if (c < 0) {
6854 /* needed to avoid having different registers saved in
6855 each branch */
6856 save_regs(1);
6857 gv_dup();
6858 tt = gvtst(0, 0);
6861 ncw_prev = nocode_wanted;
6862 if (c == 0)
6863 nocode_wanted++;
6864 if (!g)
6865 gexpr();
6867 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
6868 mk_pointer(&vtop->type);
6869 sv = *vtop; /* save value to handle it later */
6870 vtop--; /* no vpop so that FP stack is not flushed */
6872 if (g) {
6873 u = tt;
6874 } else if (c < 0) {
6875 u = gjmp(0);
6876 gsym(tt);
6877 } else
6878 u = 0;
6880 nocode_wanted = ncw_prev;
6881 if (c == 1)
6882 nocode_wanted++;
6883 skip(':');
6884 expr_cond();
6886 if (c < 0 && is_cond_bool(vtop) && is_cond_bool(&sv)) {
6887 /* optimize "if (f ? a > b : c || d) ..." for example, where normally
6888 "a < b" and "c || d" would be forced to "(int)0/1" first, whereas
6889 this code jumps directly to the if's then/else branches. */
6890 t1 = gvtst(0, 0);
6891 t2 = gjmp(0);
6892 gsym(u);
6893 vpushv(&sv);
6894 /* combine jump targets of 2nd op with VT_CMP of 1st op */
6895 gvtst_set(0, t1);
6896 gvtst_set(1, t2);
6897 nocode_wanted = ncw_prev;
6898 // tcc_warning("two conditions expr_cond");
6899 return;
6902 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
6903 mk_pointer(&vtop->type);
6905 /* cast operands to correct type according to ISOC rules */
6906 if (!combine_types(&type, &sv, vtop, '?'))
6907 type_incompatibility_error(&sv.type, &vtop->type,
6908 "type mismatch in conditional expression (have '%s' and '%s')");
6909 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
6910 that `(expr ? a : b).mem` does not error with "lvalue expected" */
6911 islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
6913 /* now we convert second operand */
6914 if (c != 1) {
6915 gen_cast(&type);
6916 if (islv) {
6917 mk_pointer(&vtop->type);
6918 gaddrof();
6919 } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
6920 gaddrof();
6923 rc = RC_TYPE(type.t);
6924 /* for long longs, we use fixed registers to avoid having
6925 to handle a complicated move */
6926 if (USING_TWO_WORDS(type.t))
6927 rc = RC_RET(type.t);
6929 tt = r2 = 0;
6930 if (c < 0) {
6931 r2 = gv(rc);
6932 tt = gjmp(0);
6934 gsym(u);
6935 nocode_wanted = ncw_prev;
6937 /* this is horrible, but we must also convert first
6938 operand */
6939 if (c != 0) {
6940 *vtop = sv;
6941 gen_cast(&type);
6942 if (islv) {
6943 mk_pointer(&vtop->type);
6944 gaddrof();
6945 } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
6946 gaddrof();
6949 if (c < 0) {
6950 r1 = gv(rc);
6951 move_reg(r2, r1, islv ? VT_PTR : type.t);
6952 vtop->r = r2;
6953 gsym(tt);
6956 if (islv)
6957 indir();
6961 static void expr_eq(void)
6963 int t;
6965 expr_cond();
6966 if ((t = tok) == '=' || TOK_ASSIGN(t)) {
6967 test_lvalue();
6968 next();
6969 if (t == '=') {
6970 expr_eq();
6971 } else {
6972 vdup();
6973 expr_eq();
6974 gen_op(TOK_ASSIGN_OP(t));
6976 vstore();
6980 ST_FUNC void gexpr(void)
6982 while (1) {
6983 expr_eq();
6984 if (tok != ',')
6985 break;
6986 vpop();
6987 next();
6991 /* parse a constant expression and return value in vtop. */
6992 static void expr_const1(void)
6994 const_wanted++;
6995 nocode_wanted += unevalmask + 1;
6996 expr_cond();
6997 nocode_wanted -= unevalmask + 1;
6998 const_wanted--;
7001 /* parse an integer constant and return its value. */
7002 static inline int64_t expr_const64(void)
7004 int64_t c;
7005 expr_const1();
7006 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
7007 expect("constant expression");
7008 c = vtop->c.i;
7009 vpop();
7010 return c;
7013 /* parse an integer constant and return its value.
7014 Complain if it doesn't fit 32bit (signed or unsigned). */
7015 ST_FUNC int expr_const(void)
7017 int c;
7018 int64_t wc = expr_const64();
7019 c = wc;
7020 if (c != wc && (unsigned)c != wc)
7021 tcc_error("constant exceeds 32 bit");
7022 return c;
7025 /* ------------------------------------------------------------------------- */
7026 /* return from function */
7028 #ifndef TCC_TARGET_ARM64
7029 static void gfunc_return(CType *func_type)
7031 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
7032 CType type, ret_type;
7033 int ret_align, ret_nregs, regsize;
7034 ret_nregs = gfunc_sret(func_type, func_var, &ret_type,
7035 &ret_align, &regsize);
7036 if (ret_nregs < 0) {
7037 #ifdef TCC_TARGET_RISCV64
7038 arch_transfer_ret_regs(0);
7039 #endif
7040 } else if (0 == ret_nregs) {
7041 /* if returning structure, must copy it to implicit
7042 first pointer arg location */
7043 type = *func_type;
7044 mk_pointer(&type);
7045 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
7046 indir();
7047 vswap();
7048 /* copy structure value to pointer */
7049 vstore();
7050 } else {
7051 /* returning structure packed into registers */
7052 int size, addr, align, rc;
7053 size = type_size(func_type,&align);
7054 if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
7055 (vtop->c.i & (ret_align-1)))
7056 && (align & (ret_align-1))) {
7057 loc = (loc - size) & -ret_align;
7058 addr = loc;
7059 type = *func_type;
7060 vset(&type, VT_LOCAL | VT_LVAL, addr);
7061 vswap();
7062 vstore();
7063 vpop();
7064 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
7066 vtop->type = ret_type;
7067 rc = RC_RET(ret_type.t);
7068 if (ret_nregs == 1)
7069 gv(rc);
7070 else {
7071 for (;;) {
7072 vdup();
7073 gv(rc);
7074 vpop();
7075 if (--ret_nregs == 0)
7076 break;
7077 /* We assume that when a structure is returned in multiple
7078 registers, their classes are consecutive values of the
7079 suite s(n) = 2^n */
7080 rc <<= 1;
7081 vtop->c.i += regsize;
7085 } else {
7086 gv(RC_RET(func_type->t));
7088 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
7090 #endif
7092 static void check_func_return(void)
7094 if ((func_vt.t & VT_BTYPE) == VT_VOID)
7095 return;
7096 if (!strcmp (funcname, "main")
7097 && (func_vt.t & VT_BTYPE) == VT_INT) {
7098 /* main returns 0 by default */
7099 vpushi(0);
7100 gen_assign_cast(&func_vt);
7101 gfunc_return(&func_vt);
7102 } else {
7103 tcc_warning("function might return no value: '%s'", funcname);
7107 /* ------------------------------------------------------------------------- */
7108 /* switch/case */
7110 static int case_cmpi(const void *pa, const void *pb)
7112 int64_t a = (*(struct case_t**) pa)->v1;
7113 int64_t b = (*(struct case_t**) pb)->v1;
7114 return a < b ? -1 : a > b;
7117 static int case_cmpu(const void *pa, const void *pb)
7119 uint64_t a = (uint64_t)(*(struct case_t**) pa)->v1;
7120 uint64_t b = (uint64_t)(*(struct case_t**) pb)->v1;
7121 return a < b ? -1 : a > b;
7124 static void gtst_addr(int t, int a)
7126 gsym_addr(gvtst(0, t), a);
7129 static void gcase(struct case_t **base, int len, int *bsym)
7131 struct case_t *p;
7132 int e;
7133 int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG;
7134 while (len > 8) {
7135 /* binary search */
7136 p = base[len/2];
7137 vdup();
7138 if (ll)
7139 vpushll(p->v2);
7140 else
7141 vpushi(p->v2);
7142 gen_op(TOK_LE);
7143 e = gvtst(1, 0);
7144 vdup();
7145 if (ll)
7146 vpushll(p->v1);
7147 else
7148 vpushi(p->v1);
7149 gen_op(TOK_GE);
7150 gtst_addr(0, p->sym); /* v1 <= x <= v2 */
7151 /* x < v1 */
7152 gcase(base, len/2, bsym);
7153 /* x > v2 */
7154 gsym(e);
7155 e = len/2 + 1;
7156 base += e; len -= e;
7158 /* linear scan */
7159 while (len--) {
7160 p = *base++;
7161 vdup();
7162 if (ll)
7163 vpushll(p->v2);
7164 else
7165 vpushi(p->v2);
7166 if (p->v1 == p->v2) {
7167 gen_op(TOK_EQ);
7168 gtst_addr(0, p->sym);
7169 } else {
7170 gen_op(TOK_LE);
7171 e = gvtst(1, 0);
7172 vdup();
7173 if (ll)
7174 vpushll(p->v1);
7175 else
7176 vpushi(p->v1);
7177 gen_op(TOK_GE);
7178 gtst_addr(0, p->sym);
7179 gsym(e);
7182 *bsym = gjmp(*bsym);
7185 /* ------------------------------------------------------------------------- */
7186 /* __attribute__((cleanup(fn))) */
7188 static void try_call_scope_cleanup(Sym *stop)
7190 Sym *cls = cur_scope->cl.s;
7192 for (; cls != stop; cls = cls->ncl) {
7193 Sym *fs = cls->next;
7194 Sym *vs = cls->prev_tok;
7196 vpushsym(&fs->type, fs);
7197 vset(&vs->type, vs->r, vs->c);
7198 vtop->sym = vs;
7199 mk_pointer(&vtop->type);
7200 gaddrof();
7201 gfunc_call(1);
7205 static void try_call_cleanup_goto(Sym *cleanupstate)
7207 Sym *oc, *cc;
7208 int ocd, ccd;
7210 if (!cur_scope->cl.s)
7211 return;
7213 /* search NCA of both cleanup chains given parents and initial depth */
7214 ocd = cleanupstate ? cleanupstate->v & ~SYM_FIELD : 0;
7215 for (ccd = cur_scope->cl.n, oc = cleanupstate; ocd > ccd; --ocd, oc = oc->ncl)
7217 for (cc = cur_scope->cl.s; ccd > ocd; --ccd, cc = cc->ncl)
7219 for (; cc != oc; cc = cc->ncl, oc = oc->ncl, --ccd)
7222 try_call_scope_cleanup(cc);
7225 /* call 'func' for each __attribute__((cleanup(func))) */
7226 static void block_cleanup(struct scope *o)
7228 int jmp = 0;
7229 Sym *g, **pg;
7230 for (pg = &pending_gotos; (g = *pg) && g->c > o->cl.n;) {
7231 if (g->prev_tok->r & LABEL_FORWARD) {
7232 Sym *pcl = g->next;
7233 if (!jmp)
7234 jmp = gjmp(0);
7235 gsym(pcl->jnext);
7236 try_call_scope_cleanup(o->cl.s);
7237 pcl->jnext = gjmp(0);
7238 if (!o->cl.n)
7239 goto remove_pending;
7240 g->c = o->cl.n;
7241 pg = &g->prev;
7242 } else {
7243 remove_pending:
7244 *pg = g->prev;
7245 sym_free(g);
7248 gsym(jmp);
7249 try_call_scope_cleanup(o->cl.s);
7252 /* ------------------------------------------------------------------------- */
7253 /* VLA */
7255 static void vla_restore(int loc)
7257 if (loc)
7258 gen_vla_sp_restore(loc);
7261 static void vla_leave(struct scope *o)
7263 struct scope *c = cur_scope, *v = NULL;
7264 for (; c != o && c; c = c->prev)
7265 if (c->vla.num)
7266 v = c;
7267 if (v)
7268 vla_restore(v->vla.locorig);
7271 /* ------------------------------------------------------------------------- */
7272 /* local scopes */
7274 static void new_scope(struct scope *o)
7276 /* copy and link previous scope */
7277 *o = *cur_scope;
7278 o->prev = cur_scope;
7279 cur_scope = o;
7280 cur_scope->vla.num = 0;
7282 /* record local declaration stack position */
7283 o->lstk = local_stack;
7284 o->llstk = local_label_stack;
7285 ++local_scope;
7287 if (debug_modes)
7288 tcc_debug_stabn(tcc_state, N_LBRAC, ind - func_ind);
7291 static void prev_scope(struct scope *o, int is_expr)
7293 vla_leave(o->prev);
7295 if (o->cl.s != o->prev->cl.s)
7296 block_cleanup(o->prev);
7298 /* pop locally defined labels */
7299 label_pop(&local_label_stack, o->llstk, is_expr);
7301 /* In the is_expr case (a statement expression is finished here),
7302 vtop might refer to symbols on the local_stack. Either via the
7303 type or via vtop->sym. We can't pop those nor any that in turn
7304 might be referred to. To make it easier we don't roll back
7305 any symbols in that case; some upper level call to block() will
7306 do that. We do have to remove such symbols from the lookup
7307 tables, though. sym_pop will do that. */
7309 /* pop locally defined symbols */
7310 pop_local_syms(o->lstk, is_expr);
7311 cur_scope = o->prev;
7312 --local_scope;
7314 if (debug_modes)
7315 tcc_debug_stabn(tcc_state, N_RBRAC, ind - func_ind);
7318 /* leave a scope via break/continue(/goto) */
7319 static void leave_scope(struct scope *o)
7321 if (!o)
7322 return;
7323 try_call_scope_cleanup(o->cl.s);
7324 vla_leave(o);
7327 /* ------------------------------------------------------------------------- */
7328 /* call block from 'for do while' loops */
7330 static void lblock(int *bsym, int *csym)
7332 struct scope *lo = loop_scope, *co = cur_scope;
7333 int *b = co->bsym, *c = co->csym;
7334 if (csym) {
7335 co->csym = csym;
7336 loop_scope = co;
7338 co->bsym = bsym;
7339 block(0);
7340 co->bsym = b;
7341 if (csym) {
7342 co->csym = c;
7343 loop_scope = lo;
7347 static void block(int is_expr)
7349 int a, b, c, d, e, t;
7350 struct scope o;
7351 Sym *s;
7353 if (is_expr) {
7354 /* default return value is (void) */
7355 vpushi(0);
7356 vtop->type.t = VT_VOID;
7359 again:
7360 t = tok;
7361 /* If the token carries a value, next() might destroy it. Only with
7362 invalid code such as f(){"123"4;} */
7363 if (TOK_HAS_VALUE(t))
7364 goto expr;
7365 next();
7367 if (debug_modes)
7368 tcc_tcov_check_line (0), tcc_tcov_block_begin ();
7370 if (t == TOK_IF) {
7371 skip('(');
7372 gexpr();
7373 skip(')');
7374 a = gvtst(1, 0);
7375 block(0);
7376 if (tok == TOK_ELSE) {
7377 d = gjmp(0);
7378 gsym(a);
7379 next();
7380 block(0);
7381 gsym(d); /* patch else jmp */
7382 } else {
7383 gsym(a);
7386 } else if (t == TOK_WHILE) {
7387 d = gind();
7388 skip('(');
7389 gexpr();
7390 skip(')');
7391 a = gvtst(1, 0);
7392 b = 0;
7393 lblock(&a, &b);
7394 gjmp_addr(d);
7395 gsym_addr(b, d);
7396 gsym(a);
7398 } else if (t == '{') {
7399 new_scope(&o);
7401 /* handle local labels declarations */
7402 while (tok == TOK_LABEL) {
7403 do {
7404 next();
7405 if (tok < TOK_UIDENT)
7406 expect("label identifier");
7407 label_push(&local_label_stack, tok, LABEL_DECLARED);
7408 next();
7409 } while (tok == ',');
7410 skip(';');
7413 while (tok != '}') {
7414 decl(VT_LOCAL);
7415 if (tok != '}') {
7416 if (is_expr)
7417 vpop();
7418 block(is_expr);
7422 prev_scope(&o, is_expr);
7423 if (local_scope)
7424 next();
7425 else if (!nocode_wanted)
7426 check_func_return();
7428 } else if (t == TOK_RETURN) {
7429 b = (func_vt.t & VT_BTYPE) != VT_VOID;
7430 if (tok != ';') {
7431 gexpr();
7432 if (b) {
7433 gen_assign_cast(&func_vt);
7434 } else {
7435 if (vtop->type.t != VT_VOID)
7436 tcc_warning("void function returns a value");
7437 vtop--;
7439 } else if (b) {
7440 tcc_warning("'return' with no value");
7441 b = 0;
7443 leave_scope(root_scope);
7444 if (b)
7445 gfunc_return(&func_vt);
7446 skip(';');
7447 /* jump unless last stmt in top-level block */
7448 if (tok != '}' || local_scope != 1)
7449 rsym = gjmp(rsym);
7450 if (debug_modes)
7451 tcc_tcov_block_end (tcov_data.line);
7452 CODE_OFF();
7454 } else if (t == TOK_BREAK) {
7455 /* compute jump */
7456 if (!cur_scope->bsym)
7457 tcc_error("cannot break");
7458 if (cur_switch && cur_scope->bsym == cur_switch->bsym)
7459 leave_scope(cur_switch->scope);
7460 else
7461 leave_scope(loop_scope);
7462 *cur_scope->bsym = gjmp(*cur_scope->bsym);
7463 skip(';');
7465 } else if (t == TOK_CONTINUE) {
7466 /* compute jump */
7467 if (!cur_scope->csym)
7468 tcc_error("cannot continue");
7469 leave_scope(loop_scope);
7470 *cur_scope->csym = gjmp(*cur_scope->csym);
7471 skip(';');
7473 } else if (t == TOK_FOR) {
7474 new_scope(&o);
7476 skip('(');
7477 if (tok != ';') {
7478 /* c99 for-loop init decl? */
7479 if (!decl0(VT_LOCAL, 1, NULL)) {
7480 /* no, regular for-loop init expr */
7481 gexpr();
7482 vpop();
7485 skip(';');
7486 a = b = 0;
7487 c = d = gind();
7488 if (tok != ';') {
7489 gexpr();
7490 a = gvtst(1, 0);
7492 skip(';');
7493 if (tok != ')') {
7494 e = gjmp(0);
7495 d = gind();
7496 gexpr();
7497 vpop();
7498 gjmp_addr(c);
7499 gsym(e);
7501 skip(')');
7502 lblock(&a, &b);
7503 gjmp_addr(d);
7504 gsym_addr(b, d);
7505 gsym(a);
7506 prev_scope(&o, 0);
7508 } else if (t == TOK_DO) {
7509 a = b = 0;
7510 d = gind();
7511 lblock(&a, &b);
7512 gsym(b);
7513 skip(TOK_WHILE);
7514 skip('(');
7515 gexpr();
7516 skip(')');
7517 skip(';');
7518 c = gvtst(0, 0);
7519 gsym_addr(c, d);
7520 gsym(a);
7522 } else if (t == TOK_SWITCH) {
7523 struct switch_t *sw;
7525 sw = tcc_mallocz(sizeof *sw);
7526 sw->bsym = &a;
7527 sw->scope = cur_scope;
7528 sw->prev = cur_switch;
7529 cur_switch = sw;
7531 skip('(');
7532 gexpr();
7533 skip(')');
7534 sw->sv = *vtop--; /* save switch value */
7536 a = 0;
7537 b = gjmp(0); /* jump to first case */
7538 lblock(&a, NULL);
7539 a = gjmp(a); /* add implicit break */
7540 /* case lookup */
7541 gsym(b);
7543 if (sw->sv.type.t & VT_UNSIGNED)
7544 qsort(sw->p, sw->n, sizeof(void*), case_cmpu);
7545 else
7546 qsort(sw->p, sw->n, sizeof(void*), case_cmpi);
7548 for (b = 1; b < sw->n; b++)
7549 if (sw->sv.type.t & VT_UNSIGNED
7550 ? (uint64_t)sw->p[b - 1]->v2 >= (uint64_t)sw->p[b]->v1
7551 : sw->p[b - 1]->v2 >= sw->p[b]->v1)
7552 tcc_error("duplicate case value");
7554 vpushv(&sw->sv);
7555 gv(RC_INT);
7556 d = 0, gcase(sw->p, sw->n, &d);
7557 vpop();
7558 if (sw->def_sym)
7559 gsym_addr(d, sw->def_sym);
7560 else
7561 gsym(d);
7562 /* break label */
7563 gsym(a);
7565 dynarray_reset(&sw->p, &sw->n);
7566 cur_switch = sw->prev;
7567 tcc_free(sw);
7569 } else if (t == TOK_CASE) {
7570 struct case_t *cr = tcc_malloc(sizeof(struct case_t));
7571 if (!cur_switch)
7572 expect("switch");
7573 cr->v1 = cr->v2 = expr_const64();
7574 if (gnu_ext && tok == TOK_DOTS) {
7575 next();
7576 cr->v2 = expr_const64();
7577 if ((!(cur_switch->sv.type.t & VT_UNSIGNED) && cr->v2 < cr->v1)
7578 || (cur_switch->sv.type.t & VT_UNSIGNED && (uint64_t)cr->v2 < (uint64_t)cr->v1))
7579 tcc_warning("empty case range");
7581 tcov_data.ind = 0;
7582 cr->sym = gind();
7583 dynarray_add(&cur_switch->p, &cur_switch->n, cr);
7584 skip(':');
7585 is_expr = 0;
7586 goto block_after_label;
7588 } else if (t == TOK_DEFAULT) {
7589 if (!cur_switch)
7590 expect("switch");
7591 if (cur_switch->def_sym)
7592 tcc_error("too many 'default'");
7593 tcov_data.ind = 0;
7594 cur_switch->def_sym = gind();
7595 skip(':');
7596 is_expr = 0;
7597 goto block_after_label;
7599 } else if (t == TOK_GOTO) {
7600 if (cur_scope->vla.num)
7601 vla_restore(cur_scope->vla.locorig);
7602 if (tok == '*' && gnu_ext) {
7603 /* computed goto */
7604 next();
7605 gexpr();
7606 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
7607 expect("pointer");
7608 ggoto();
7610 } else if (tok >= TOK_UIDENT) {
7611 s = label_find(tok);
7612 /* put forward definition if needed */
7613 if (!s)
7614 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
7615 else if (s->r == LABEL_DECLARED)
7616 s->r = LABEL_FORWARD;
7618 if (s->r & LABEL_FORWARD) {
7619 /* start new goto chain for cleanups, linked via label->next */
7620 if (cur_scope->cl.s && !nocode_wanted) {
7621 sym_push2(&pending_gotos, SYM_FIELD, 0, cur_scope->cl.n);
7622 pending_gotos->prev_tok = s;
7623 s = sym_push2(&s->next, SYM_FIELD, 0, 0);
7624 pending_gotos->next = s;
7626 s->jnext = gjmp(s->jnext);
7627 } else {
7628 try_call_cleanup_goto(s->cleanupstate);
7629 gjmp_addr(s->jnext);
7631 next();
7633 } else {
7634 expect("label identifier");
7636 skip(';');
7638 } else if (t == TOK_ASM1 || t == TOK_ASM2 || t == TOK_ASM3) {
7639 asm_instr();
7641 } else {
7642 if (tok == ':' && t >= TOK_UIDENT) {
7643 /* label case */
7644 next();
7645 s = label_find(t);
7646 if (s) {
7647 if (s->r == LABEL_DEFINED)
7648 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
7649 s->r = LABEL_DEFINED;
7650 if (s->next) {
7651 Sym *pcl; /* pending cleanup goto */
7652 for (pcl = s->next; pcl; pcl = pcl->prev)
7653 gsym(pcl->jnext);
7654 sym_pop(&s->next, NULL, 0);
7655 } else
7656 gsym(s->jnext);
7657 } else {
7658 s = label_push(&global_label_stack, t, LABEL_DEFINED);
7660 s->jnext = gind();
7661 s->cleanupstate = cur_scope->cl.s;
7663 block_after_label:
7664 vla_restore(cur_scope->vla.loc);
7665 if (tok != '}')
7666 goto again;
7667 /* we accept this, but it is a mistake */
7668 tcc_warning_c(warn_all)("deprecated use of label at end of compound statement");
7670 } else {
7671 /* expression case */
7672 if (t != ';') {
7673 unget_tok(t);
7674 expr:
7675 if (is_expr) {
7676 vpop();
7677 gexpr();
7678 } else {
7679 gexpr();
7680 vpop();
7682 skip(';');
7687 if (debug_modes)
7688 tcc_tcov_check_line (0), tcc_tcov_block_end (0);
7691 /* This skips over a stream of tokens containing balanced {} and ()
7692 pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started
7693 with a '{'). If STR then allocates and stores the skipped tokens
7694 in *STR. This doesn't check if () and {} are nested correctly,
7695 i.e. "({)}" is accepted. */
7696 static void skip_or_save_block(TokenString **str)
7698 int braces = tok == '{';
7699 int level = 0;
7700 if (str)
7701 *str = tok_str_alloc();
7703 while ((level > 0 || (tok != '}' && tok != ',' && tok != ';' && tok != ')'))) {
7704 int t;
7705 if (tok == TOK_EOF) {
7706 if (str || level > 0)
7707 tcc_error("unexpected end of file");
7708 else
7709 break;
7711 if (str)
7712 tok_str_add_tok(*str);
7713 t = tok;
7714 next();
7715 if (t == '{' || t == '(') {
7716 level++;
7717 } else if (t == '}' || t == ')') {
7718 level--;
7719 if (level == 0 && braces && t == '}')
7720 break;
7723 if (str) {
7724 tok_str_add(*str, -1);
7725 tok_str_add(*str, 0);
7729 #define EXPR_CONST 1
7730 #define EXPR_ANY 2
7732 static void parse_init_elem(int expr_type)
7734 int saved_global_expr;
7735 switch(expr_type) {
7736 case EXPR_CONST:
7737 /* compound literals must be allocated globally in this case */
7738 saved_global_expr = global_expr;
7739 global_expr = 1;
7740 expr_const1();
7741 global_expr = saved_global_expr;
7742 /* NOTE: symbols are accepted, as well as lvalue for anon symbols
7743 (compound literals). */
7744 if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST
7745 && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL)
7746 || vtop->sym->v < SYM_FIRST_ANOM))
7747 #ifdef TCC_TARGET_PE
7748 || ((vtop->r & VT_SYM) && vtop->sym->a.dllimport)
7749 #endif
7751 tcc_error("initializer element is not constant");
7752 break;
7753 case EXPR_ANY:
7754 expr_eq();
7755 break;
7759 #if 1
7760 static void init_assert(init_params *p, int offset)
7762 if (p->sec ? !NODATA_WANTED && offset > p->sec->data_offset
7763 : !nocode_wanted && offset > p->local_offset)
7764 tcc_internal_error("initializer overflow");
7766 #else
7767 #define init_assert(sec, offset)
7768 #endif
7770 /* put zeros for variable based init */
7771 static void init_putz(init_params *p, unsigned long c, int size)
7773 init_assert(p, c + size);
7774 if (p->sec) {
7775 /* nothing to do because globals are already set to zero */
7776 } else {
7777 vpush_helper_func(TOK_memset);
7778 vseti(VT_LOCAL, c);
7779 #ifdef TCC_TARGET_ARM
7780 vpushs(size);
7781 vpushi(0);
7782 #else
7783 vpushi(0);
7784 vpushs(size);
7785 #endif
7786 gfunc_call(3);
7790 #define DIF_FIRST 1
7791 #define DIF_SIZE_ONLY 2
7792 #define DIF_HAVE_ELEM 4
7793 #define DIF_CLEAR 8
7795 /* delete relocations for specified range c ... c + size. Unfortunatly
7796 in very special cases, relocations may occur unordered */
7797 static void decl_design_delrels(Section *sec, int c, int size)
7799 ElfW_Rel *rel, *rel2, *rel_end;
7800 if (!sec || !sec->reloc)
7801 return;
7802 rel = rel2 = (ElfW_Rel*)sec->reloc->data;
7803 rel_end = (ElfW_Rel*)(sec->reloc->data + sec->reloc->data_offset);
7804 while (rel < rel_end) {
7805 if (rel->r_offset >= c && rel->r_offset < c + size) {
7806 sec->reloc->data_offset -= sizeof *rel;
7807 } else {
7808 if (rel2 != rel)
7809 memcpy(rel2, rel, sizeof *rel);
7810 ++rel2;
7812 ++rel;
7816 static void decl_design_flex(init_params *p, Sym *ref, int index)
7818 if (ref == p->flex_array_ref) {
7819 if (index >= ref->c)
7820 ref->c = index + 1;
7821 } else if (ref->c < 0)
7822 tcc_error("flexible array has zero size in this context");
7825 /* t is the array or struct type. c is the array or struct
7826 address. cur_field is the pointer to the current
7827 field, for arrays the 'c' member contains the current start
7828 index. 'flags' is as in decl_initializer.
7829 'al' contains the already initialized length of the
7830 current container (starting at c). This returns the new length of that. */
7831 static int decl_designator(init_params *p, CType *type, unsigned long c,
7832 Sym **cur_field, int flags, int al)
7834 Sym *s, *f;
7835 int index, index_last, align, l, nb_elems, elem_size;
7836 unsigned long corig = c;
7838 elem_size = 0;
7839 nb_elems = 1;
7841 if (flags & DIF_HAVE_ELEM)
7842 goto no_designator;
7844 if (gnu_ext && tok >= TOK_UIDENT) {
7845 l = tok, next();
7846 if (tok == ':')
7847 goto struct_field;
7848 unget_tok(l);
7851 /* NOTE: we only support ranges for last designator */
7852 while (nb_elems == 1 && (tok == '[' || tok == '.')) {
7853 if (tok == '[') {
7854 if (!(type->t & VT_ARRAY))
7855 expect("array type");
7856 next();
7857 index = index_last = expr_const();
7858 if (tok == TOK_DOTS && gnu_ext) {
7859 next();
7860 index_last = expr_const();
7862 skip(']');
7863 s = type->ref;
7864 decl_design_flex(p, s, index_last);
7865 if (index < 0 || index_last >= s->c || index_last < index)
7866 tcc_error("index exceeds array bounds or range is empty");
7867 if (cur_field)
7868 (*cur_field)->c = index_last;
7869 type = pointed_type(type);
7870 elem_size = type_size(type, &align);
7871 c += index * elem_size;
7872 nb_elems = index_last - index + 1;
7873 } else {
7874 int cumofs;
7875 next();
7876 l = tok;
7877 struct_field:
7878 next();
7879 if ((type->t & VT_BTYPE) != VT_STRUCT)
7880 expect("struct/union type");
7881 cumofs = 0;
7882 f = find_field(type, l, &cumofs);
7883 if (!f)
7884 expect("field");
7885 if (cur_field)
7886 *cur_field = f;
7887 type = &f->type;
7888 c += cumofs + f->c;
7890 cur_field = NULL;
7892 if (!cur_field) {
7893 if (tok == '=') {
7894 next();
7895 } else if (!gnu_ext) {
7896 expect("=");
7898 } else {
7899 no_designator:
7900 if (type->t & VT_ARRAY) {
7901 index = (*cur_field)->c;
7902 s = type->ref;
7903 decl_design_flex(p, s, index);
7904 if (index >= s->c)
7905 tcc_error("too many initializers");
7906 type = pointed_type(type);
7907 elem_size = type_size(type, &align);
7908 c += index * elem_size;
7909 } else {
7910 f = *cur_field;
7911 while (f && (f->v & SYM_FIRST_ANOM) && (f->type.t & VT_BITFIELD))
7912 *cur_field = f = f->next;
7913 if (!f)
7914 tcc_error("too many initializers");
7915 type = &f->type;
7916 c += f->c;
7920 if (!elem_size) /* for structs */
7921 elem_size = type_size(type, &align);
7923 /* Using designators the same element can be initialized more
7924 than once. In that case we need to delete possibly already
7925 existing relocations. */
7926 if (!(flags & DIF_SIZE_ONLY) && c - corig < al) {
7927 decl_design_delrels(p->sec, c, elem_size * nb_elems);
7928 flags &= ~DIF_CLEAR; /* mark stack dirty too */
7931 decl_initializer(p, type, c, flags & ~DIF_FIRST);
7933 if (!(flags & DIF_SIZE_ONLY) && nb_elems > 1) {
7934 Sym aref = {0};
7935 CType t1;
7936 int i;
7937 if (p->sec || (type->t & VT_ARRAY)) {
7938 /* make init_putv/vstore believe it were a struct */
7939 aref.c = elem_size;
7940 t1.t = VT_STRUCT, t1.ref = &aref;
7941 type = &t1;
7943 if (p->sec)
7944 vpush_ref(type, p->sec, c, elem_size);
7945 else
7946 vset(type, VT_LOCAL|VT_LVAL, c);
7947 for (i = 1; i < nb_elems; i++) {
7948 vdup();
7949 init_putv(p, type, c + elem_size * i);
7951 vpop();
7954 c += nb_elems * elem_size;
7955 if (c - corig > al)
7956 al = c - corig;
7957 return al;
7960 /* store a value or an expression directly in global data or in local array */
7961 static void init_putv(init_params *p, CType *type, unsigned long c)
7963 int bt;
7964 void *ptr;
7965 CType dtype;
7966 int size, align;
7967 Section *sec = p->sec;
7968 uint64_t val;
7970 dtype = *type;
7971 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
7973 size = type_size(type, &align);
7974 if (type->t & VT_BITFIELD)
7975 size = (BIT_POS(type->t) + BIT_SIZE(type->t) + 7) / 8;
7976 init_assert(p, c + size);
7978 if (sec) {
7979 /* XXX: not portable */
7980 /* XXX: generate error if incorrect relocation */
7981 gen_assign_cast(&dtype);
7982 bt = type->t & VT_BTYPE;
7984 if ((vtop->r & VT_SYM)
7985 && bt != VT_PTR
7986 && (bt != (PTR_SIZE == 8 ? VT_LLONG : VT_INT)
7987 || (type->t & VT_BITFIELD))
7988 && !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM)
7990 tcc_error("initializer element is not computable at load time");
7992 if (NODATA_WANTED) {
7993 vtop--;
7994 return;
7997 ptr = sec->data + c;
7998 val = vtop->c.i;
8000 /* XXX: make code faster ? */
8001 if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) &&
8002 vtop->sym->v >= SYM_FIRST_ANOM &&
8003 /* XXX This rejects compound literals like
8004 '(void *){ptr}'. The problem is that '&sym' is
8005 represented the same way, which would be ruled out
8006 by the SYM_FIRST_ANOM check above, but also '"string"'
8007 in 'char *p = "string"' is represented the same
8008 with the type being VT_PTR and the symbol being an
8009 anonymous one. That is, there's no difference in vtop
8010 between '(void *){x}' and '&(void *){x}'. Ignore
8011 pointer typed entities here. Hopefully no real code
8012 will ever use compound literals with scalar type. */
8013 (vtop->type.t & VT_BTYPE) != VT_PTR) {
8014 /* These come from compound literals, memcpy stuff over. */
8015 Section *ssec;
8016 ElfSym *esym;
8017 ElfW_Rel *rel;
8018 esym = elfsym(vtop->sym);
8019 ssec = tcc_state->sections[esym->st_shndx];
8020 memmove (ptr, ssec->data + esym->st_value + (int)vtop->c.i, size);
8021 if (ssec->reloc) {
8022 /* We need to copy over all memory contents, and that
8023 includes relocations. Use the fact that relocs are
8024 created it order, so look from the end of relocs
8025 until we hit one before the copied region. */
8026 unsigned long relofs = ssec->reloc->data_offset;
8027 while (relofs >= sizeof(*rel)) {
8028 relofs -= sizeof(*rel);
8029 rel = (ElfW_Rel*)(ssec->reloc->data + relofs);
8030 if (rel->r_offset >= esym->st_value + size)
8031 continue;
8032 if (rel->r_offset < esym->st_value)
8033 break;
8034 put_elf_reloca(symtab_section, sec,
8035 c + rel->r_offset - esym->st_value,
8036 ELFW(R_TYPE)(rel->r_info),
8037 ELFW(R_SYM)(rel->r_info),
8038 #if PTR_SIZE == 8
8039 rel->r_addend
8040 #else
8042 #endif
8046 } else {
8047 if (type->t & VT_BITFIELD) {
8048 int bit_pos, bit_size, bits, n;
8049 unsigned char *p, v, m;
8050 bit_pos = BIT_POS(vtop->type.t);
8051 bit_size = BIT_SIZE(vtop->type.t);
8052 p = (unsigned char*)ptr + (bit_pos >> 3);
8053 bit_pos &= 7, bits = 0;
8054 while (bit_size) {
8055 n = 8 - bit_pos;
8056 if (n > bit_size)
8057 n = bit_size;
8058 v = val >> bits << bit_pos;
8059 m = ((1 << n) - 1) << bit_pos;
8060 *p = (*p & ~m) | (v & m);
8061 bits += n, bit_size -= n, bit_pos = 0, ++p;
8063 } else
8064 switch(bt) {
8065 case VT_BOOL:
8066 *(char *)ptr = val != 0;
8067 break;
8068 case VT_BYTE:
8069 *(char *)ptr = val;
8070 break;
8071 case VT_SHORT:
8072 write16le(ptr, val);
8073 break;
8074 case VT_FLOAT:
8075 write32le(ptr, val);
8076 break;
8077 case VT_DOUBLE:
8078 write64le(ptr, val);
8079 break;
8080 case VT_LDOUBLE:
8081 #if defined TCC_IS_NATIVE_387
8082 /* Host and target platform may be different but both have x87.
8083 On windows, tcc does not use VT_LDOUBLE, except when it is a
8084 cross compiler. In this case a mingw gcc as host compiler
8085 comes here with 10-byte long doubles, while msvc or tcc won't.
8086 tcc itself can still translate by asm.
8087 In any case we avoid possibly random bytes 11 and 12.
8089 if (sizeof (long double) >= 10)
8090 memcpy(ptr, &vtop->c.ld, 10);
8091 #ifdef __TINYC__
8092 else if (sizeof (long double) == sizeof (double))
8093 __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld));
8094 #endif
8095 else if (vtop->c.ld == 0.0)
8097 else
8098 #endif
8099 /* For other platforms it should work natively, but may not work
8100 for cross compilers */
8101 if (sizeof(long double) == LDOUBLE_SIZE)
8102 memcpy(ptr, &vtop->c.ld, LDOUBLE_SIZE);
8103 else if (sizeof(double) == LDOUBLE_SIZE)
8104 memcpy(ptr, &vtop->c.ld, LDOUBLE_SIZE);
8105 #ifndef TCC_CROSS_TEST
8106 else
8107 tcc_error("can't cross compile long double constants");
8108 #endif
8109 break;
8111 #if PTR_SIZE == 8
8112 /* intptr_t may need a reloc too, see tcctest.c:relocation_test() */
8113 case VT_LLONG:
8114 case VT_PTR:
8115 if (vtop->r & VT_SYM)
8116 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
8117 else
8118 write64le(ptr, val);
8119 break;
8120 case VT_INT:
8121 write32le(ptr, val);
8122 break;
8123 #else
8124 case VT_LLONG:
8125 write64le(ptr, val);
8126 break;
8127 case VT_PTR:
8128 case VT_INT:
8129 if (vtop->r & VT_SYM)
8130 greloc(sec, vtop->sym, c, R_DATA_PTR);
8131 write32le(ptr, val);
8132 break;
8133 #endif
8134 default:
8135 //tcc_internal_error("unexpected type");
8136 break;
8139 vtop--;
8140 } else {
8141 vset(&dtype, VT_LOCAL|VT_LVAL, c);
8142 vswap();
8143 vstore();
8144 vpop();
8148 /* 't' contains the type and storage info. 'c' is the offset of the
8149 object in section 'sec'. If 'sec' is NULL, it means stack based
8150 allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi
8151 dimension implicit array init handling). 'flags & DIF_SIZE_ONLY' is true if
8152 size only evaluation is wanted (only for arrays). */
8153 static void decl_initializer(init_params *p, CType *type, unsigned long c, int flags)
8155 int len, n, no_oblock, i;
8156 int size1, align1;
8157 Sym *s, *f;
8158 Sym indexsym;
8159 CType *t1;
8161 /* generate line number info */
8162 if (debug_modes && !p->sec)
8163 tcc_debug_line(tcc_state), tcc_tcov_check_line (1);
8165 if (!(flags & DIF_HAVE_ELEM) && tok != '{' &&
8166 /* In case of strings we have special handling for arrays, so
8167 don't consume them as initializer value (which would commit them
8168 to some anonymous symbol). */
8169 tok != TOK_LSTR && tok != TOK_STR &&
8170 (!(flags & DIF_SIZE_ONLY)
8171 /* a struct may be initialized from a struct of same type, as in
8172 struct {int x,y;} a = {1,2}, b = {3,4}, c[] = {a,b};
8173 In that case we need to parse the element in order to check
8174 it for compatibility below */
8175 || (type->t & VT_BTYPE) == VT_STRUCT)
8177 int ncw_prev = nocode_wanted;
8178 if ((flags & DIF_SIZE_ONLY) && !p->sec)
8179 ++nocode_wanted;
8180 parse_init_elem(!p->sec ? EXPR_ANY : EXPR_CONST);
8181 nocode_wanted = ncw_prev;
8182 flags |= DIF_HAVE_ELEM;
8185 if (type->t & VT_ARRAY) {
8186 no_oblock = 1;
8187 if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) ||
8188 tok == '{') {
8189 skip('{');
8190 no_oblock = 0;
8193 s = type->ref;
8194 n = s->c;
8195 t1 = pointed_type(type);
8196 size1 = type_size(t1, &align1);
8198 /* only parse strings here if correct type (otherwise: handle
8199 them as ((w)char *) expressions */
8200 if ((tok == TOK_LSTR &&
8201 #ifdef TCC_TARGET_PE
8202 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
8203 #else
8204 (t1->t & VT_BTYPE) == VT_INT
8205 #endif
8206 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
8207 len = 0;
8208 cstr_reset(&initstr);
8209 if (size1 != (tok == TOK_STR ? 1 : sizeof(nwchar_t)))
8210 tcc_error("unhandled string literal merging");
8211 while (tok == TOK_STR || tok == TOK_LSTR) {
8212 if (initstr.size)
8213 initstr.size -= size1;
8214 if (tok == TOK_STR)
8215 len += tokc.str.size;
8216 else
8217 len += tokc.str.size / sizeof(nwchar_t);
8218 len--;
8219 cstr_cat(&initstr, tokc.str.data, tokc.str.size);
8220 next();
8222 if (tok != ')' && tok != '}' && tok != ',' && tok != ';'
8223 && tok != TOK_EOF) {
8224 /* Not a lone literal but part of a bigger expression. */
8225 unget_tok(size1 == 1 ? TOK_STR : TOK_LSTR);
8226 tokc.str.size = initstr.size;
8227 tokc.str.data = initstr.data;
8228 goto do_init_array;
8231 decl_design_flex(p, s, len);
8232 if (!(flags & DIF_SIZE_ONLY)) {
8233 int nb = n;
8234 if (len < nb)
8235 nb = len;
8236 if (len > nb)
8237 tcc_warning("initializer-string for array is too long");
8238 /* in order to go faster for common case (char
8239 string in global variable, we handle it
8240 specifically */
8241 if (p->sec && size1 == 1) {
8242 init_assert(p, c + nb);
8243 if (!NODATA_WANTED)
8244 memcpy(p->sec->data + c, initstr.data, nb);
8245 } else {
8246 for(i=0;i<n;i++) {
8247 if (i >= nb) {
8248 /* only add trailing zero if enough storage (no
8249 warning in this case since it is standard) */
8250 if (flags & DIF_CLEAR)
8251 break;
8252 if (n - i >= 4) {
8253 init_putz(p, c + i * size1, (n - i) * size1);
8254 break;
8256 ch = 0;
8257 } else if (size1 == 1)
8258 ch = ((unsigned char *)initstr.data)[i];
8259 else
8260 ch = ((nwchar_t *)initstr.data)[i];
8261 vpushi(ch);
8262 init_putv(p, t1, c + i * size1);
8266 } else {
8268 do_init_array:
8269 indexsym.c = 0;
8270 f = &indexsym;
8272 do_init_list:
8273 /* zero memory once in advance */
8274 if (!(flags & (DIF_CLEAR | DIF_SIZE_ONLY))) {
8275 init_putz(p, c, n*size1);
8276 flags |= DIF_CLEAR;
8279 len = 0;
8280 while (tok != '}' || (flags & DIF_HAVE_ELEM)) {
8281 len = decl_designator(p, type, c, &f, flags, len);
8282 flags &= ~DIF_HAVE_ELEM;
8283 if (type->t & VT_ARRAY) {
8284 ++indexsym.c;
8285 /* special test for multi dimensional arrays (may not
8286 be strictly correct if designators are used at the
8287 same time) */
8288 if (no_oblock && len >= n*size1)
8289 break;
8290 } else {
8291 if (s->type.t == VT_UNION)
8292 f = NULL;
8293 else
8294 f = f->next;
8295 if (no_oblock && f == NULL)
8296 break;
8299 if (tok == '}')
8300 break;
8301 skip(',');
8304 if (!no_oblock)
8305 skip('}');
8307 } else if ((flags & DIF_HAVE_ELEM)
8308 /* Use i_c_parameter_t, to strip toplevel qualifiers.
8309 The source type might have VT_CONSTANT set, which is
8310 of course assignable to non-const elements. */
8311 && is_compatible_unqualified_types(type, &vtop->type)) {
8312 goto one_elem;
8314 } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
8315 no_oblock = 1;
8316 if ((flags & DIF_FIRST) || tok == '{') {
8317 skip('{');
8318 no_oblock = 0;
8320 s = type->ref;
8321 f = s->next;
8322 n = s->c;
8323 size1 = 1;
8324 goto do_init_list;
8326 } else if (tok == '{') {
8327 if (flags & DIF_HAVE_ELEM)
8328 skip(';');
8329 next();
8330 decl_initializer(p, type, c, flags & ~DIF_HAVE_ELEM);
8331 skip('}');
8333 } else one_elem: if ((flags & DIF_SIZE_ONLY)) {
8334 /* If we supported only ISO C we wouldn't have to accept calling
8335 this on anything than an array if DIF_SIZE_ONLY (and even then
8336 only on the outermost level, so no recursion would be needed),
8337 because initializing a flex array member isn't supported.
8338 But GNU C supports it, so we need to recurse even into
8339 subfields of structs and arrays when DIF_SIZE_ONLY is set. */
8340 /* just skip expression */
8341 if (flags & DIF_HAVE_ELEM)
8342 vpop();
8343 else
8344 skip_or_save_block(NULL);
8346 } else {
8347 if (!(flags & DIF_HAVE_ELEM)) {
8348 /* This should happen only when we haven't parsed
8349 the init element above for fear of committing a
8350 string constant to memory too early. */
8351 if (tok != TOK_STR && tok != TOK_LSTR)
8352 expect("string constant");
8353 parse_init_elem(!p->sec ? EXPR_ANY : EXPR_CONST);
8355 if (!p->sec && (flags & DIF_CLEAR) /* container was already zero'd */
8356 && (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST
8357 && vtop->c.i == 0
8358 && btype_size(type->t & VT_BTYPE) /* not for fp constants */
8360 vpop();
8361 else
8362 init_putv(p, type, c);
8366 /* parse an initializer for type 't' if 'has_init' is non zero, and
8367 allocate space in local or global data space ('r' is either
8368 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
8369 variable 'v' of scope 'scope' is declared before initializers
8370 are parsed. If 'v' is zero, then a reference to the new object
8371 is put in the value stack. If 'has_init' is 2, a special parsing
8372 is done to handle string constants. */
8373 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
8374 int has_init, int v, int scope)
8376 int size, align, addr;
8377 TokenString *init_str = NULL;
8379 Section *sec;
8380 Sym *flexible_array;
8381 Sym *sym;
8382 int saved_nocode_wanted = nocode_wanted;
8383 #ifdef CONFIG_TCC_BCHECK
8384 int bcheck = tcc_state->do_bounds_check && !NODATA_WANTED;
8385 #endif
8386 init_params p = {0};
8388 /* Always allocate static or global variables */
8389 if (v && (r & VT_VALMASK) == VT_CONST)
8390 nocode_wanted |= 0x80000000;
8392 flexible_array = NULL;
8393 size = type_size(type, &align);
8395 /* exactly one flexible array may be initialized, either the
8396 toplevel array or the last member of the toplevel struct */
8398 if (size < 0) {
8399 /* If the base type itself was an array type of unspecified size
8400 (like in 'typedef int arr[]; arr x = {1};') then we will
8401 overwrite the unknown size by the real one for this decl.
8402 We need to unshare the ref symbol holding that size. */
8403 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
8404 p.flex_array_ref = type->ref;
8406 } else if (has_init && (type->t & VT_BTYPE) == VT_STRUCT) {
8407 Sym *field = type->ref->next;
8408 if (field) {
8409 while (field->next)
8410 field = field->next;
8411 if (field->type.t & VT_ARRAY && field->type.ref->c < 0) {
8412 flexible_array = field;
8413 p.flex_array_ref = field->type.ref;
8414 size = -1;
8419 if (size < 0) {
8420 /* If unknown size, do a dry-run 1st pass */
8421 if (!has_init)
8422 tcc_error("unknown type size");
8423 if (has_init == 2) {
8424 /* only get strings */
8425 init_str = tok_str_alloc();
8426 while (tok == TOK_STR || tok == TOK_LSTR) {
8427 tok_str_add_tok(init_str);
8428 next();
8430 tok_str_add(init_str, -1);
8431 tok_str_add(init_str, 0);
8432 } else
8433 skip_or_save_block(&init_str);
8434 unget_tok(0);
8436 /* compute size */
8437 begin_macro(init_str, 1);
8438 next();
8439 decl_initializer(&p, type, 0, DIF_FIRST | DIF_SIZE_ONLY);
8440 /* prepare second initializer parsing */
8441 macro_ptr = init_str->str;
8442 next();
8444 /* if still unknown size, error */
8445 size = type_size(type, &align);
8446 if (size < 0)
8447 tcc_error("unknown type size");
8449 /* If there's a flex member and it was used in the initializer
8450 adjust size. */
8451 if (flexible_array && flexible_array->type.ref->c > 0)
8452 size += flexible_array->type.ref->c
8453 * pointed_size(&flexible_array->type);
8456 /* take into account specified alignment if bigger */
8457 if (ad->a.aligned) {
8458 int speca = 1 << (ad->a.aligned - 1);
8459 if (speca > align)
8460 align = speca;
8461 } else if (ad->a.packed) {
8462 align = 1;
8465 if (!v && NODATA_WANTED)
8466 size = 0, align = 1;
8468 if ((r & VT_VALMASK) == VT_LOCAL) {
8469 sec = NULL;
8470 #ifdef CONFIG_TCC_BCHECK
8471 if (bcheck && v) {
8472 /* add padding between stack variables for bound checking */
8473 loc -= align;
8475 #endif
8476 loc = (loc - size) & -align;
8477 addr = loc;
8478 p.local_offset = addr + size;
8479 #ifdef CONFIG_TCC_BCHECK
8480 if (bcheck && v) {
8481 /* add padding between stack variables for bound checking */
8482 loc -= align;
8484 #endif
8485 if (v) {
8486 /* local variable */
8487 #ifdef CONFIG_TCC_ASM
8488 if (ad->asm_label) {
8489 int reg = asm_parse_regvar(ad->asm_label);
8490 if (reg >= 0)
8491 r = (r & ~VT_VALMASK) | reg;
8493 #endif
8494 sym = sym_push(v, type, r, addr);
8495 if (ad->cleanup_func) {
8496 Sym *cls = sym_push2(&all_cleanups,
8497 SYM_FIELD | ++cur_scope->cl.n, 0, 0);
8498 cls->prev_tok = sym;
8499 cls->next = ad->cleanup_func;
8500 cls->ncl = cur_scope->cl.s;
8501 cur_scope->cl.s = cls;
8504 sym->a = ad->a;
8505 } else {
8506 /* push local reference */
8507 vset(type, r, addr);
8509 } else {
8510 sym = NULL;
8511 if (v && scope == VT_CONST) {
8512 /* see if the symbol was already defined */
8513 sym = sym_find(v);
8514 if (sym) {
8515 if (p.flex_array_ref && (sym->type.t & type->t & VT_ARRAY)
8516 && sym->type.ref->c > type->ref->c) {
8517 /* flex array was already declared with explicit size
8518 extern int arr[10];
8519 int arr[] = { 1,2,3 }; */
8520 type->ref->c = sym->type.ref->c;
8521 size = type_size(type, &align);
8523 patch_storage(sym, ad, type);
8524 /* we accept several definitions of the same global variable. */
8525 if (!has_init && sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)
8526 goto no_alloc;
8530 /* allocate symbol in corresponding section */
8531 sec = ad->section;
8532 if (!sec) {
8533 CType *tp = type;
8534 while ((tp->t & (VT_BTYPE|VT_ARRAY)) == (VT_PTR|VT_ARRAY))
8535 tp = &tp->ref->type;
8536 if (tp->t & VT_CONSTANT) {
8537 sec = rodata_section;
8538 } else if (has_init) {
8539 sec = data_section;
8540 /*if (tcc_state->g_debug & 4)
8541 tcc_warning("rw data: %s", get_tok_str(v, 0));*/
8542 } else if (tcc_state->nocommon)
8543 sec = bss_section;
8546 if (sec) {
8547 addr = section_add(sec, size, align);
8548 #ifdef CONFIG_TCC_BCHECK
8549 /* add padding if bound check */
8550 if (bcheck)
8551 section_add(sec, 1, 1);
8552 #endif
8553 } else {
8554 addr = align; /* SHN_COMMON is special, symbol value is align */
8555 sec = common_section;
8558 if (v) {
8559 if (!sym) {
8560 sym = sym_push(v, type, r | VT_SYM, 0);
8561 patch_storage(sym, ad, NULL);
8563 /* update symbol definition */
8564 put_extern_sym(sym, sec, addr, size);
8565 } else {
8566 /* push global reference */
8567 vpush_ref(type, sec, addr, size);
8568 sym = vtop->sym;
8569 vtop->r |= r;
8572 #ifdef CONFIG_TCC_BCHECK
8573 /* handles bounds now because the symbol must be defined
8574 before for the relocation */
8575 if (bcheck) {
8576 addr_t *bounds_ptr;
8578 greloca(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR, 0);
8579 /* then add global bound info */
8580 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
8581 bounds_ptr[0] = 0; /* relocated */
8582 bounds_ptr[1] = size;
8584 #endif
8587 if (type->t & VT_VLA) {
8588 int a;
8590 if (NODATA_WANTED)
8591 goto no_alloc;
8593 /* save before-VLA stack pointer if needed */
8594 if (cur_scope->vla.num == 0) {
8595 if (cur_scope->prev && cur_scope->prev->vla.num) {
8596 cur_scope->vla.locorig = cur_scope->prev->vla.loc;
8597 } else {
8598 gen_vla_sp_save(loc -= PTR_SIZE);
8599 cur_scope->vla.locorig = loc;
8603 vpush_type_size(type, &a);
8604 gen_vla_alloc(type, a);
8605 #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
8606 /* on _WIN64, because of the function args scratch area, the
8607 result of alloca differs from RSP and is returned in RAX. */
8608 gen_vla_result(addr), addr = (loc -= PTR_SIZE);
8609 #endif
8610 gen_vla_sp_save(addr);
8611 cur_scope->vla.loc = addr;
8612 cur_scope->vla.num++;
8613 } else if (has_init) {
8614 p.sec = sec;
8615 decl_initializer(&p, type, addr, DIF_FIRST);
8616 /* patch flexible array member size back to -1, */
8617 /* for possible subsequent similar declarations */
8618 if (flexible_array)
8619 flexible_array->type.ref->c = -1;
8622 no_alloc:
8623 /* restore parse state if needed */
8624 if (init_str) {
8625 end_macro();
8626 next();
8629 nocode_wanted = saved_nocode_wanted;
8632 /* generate vla code saved in post_type() */
8633 static void func_vla_arg_code(Sym *arg)
8635 int align;
8636 TokenString *vla_array_tok = NULL;
8638 if (arg->type.ref)
8639 func_vla_arg_code(arg->type.ref);
8641 if (arg->type.t & VT_VLA) {
8642 loc -= type_size(&int_type, &align);
8643 loc &= -align;
8644 arg->type.ref->c = loc;
8646 unget_tok(0);
8647 vla_array_tok = tok_str_alloc();
8648 vla_array_tok->str = arg->type.ref->vla_array_str;
8649 begin_macro(vla_array_tok, 1);
8650 next();
8651 gexpr();
8652 end_macro();
8653 next();
8654 vpush_type_size(&arg->type.ref->type, &align);
8655 gen_op('*');
8656 vset(&int_type, VT_LOCAL|VT_LVAL, arg->type.ref->c);
8657 vswap();
8658 vstore();
8659 vpop();
8663 static void func_vla_arg(Sym *sym)
8665 Sym *arg;
8667 for (arg = sym->type.ref->next; arg; arg = arg->next)
8668 if (arg->type.t & VT_VLA)
8669 func_vla_arg_code(arg);
8672 /* parse a function defined by symbol 'sym' and generate its code in
8673 'cur_text_section' */
8674 static void gen_function(Sym *sym)
8676 struct scope f = { 0 };
8677 cur_scope = root_scope = &f;
8678 nocode_wanted = 0;
8679 ind = cur_text_section->data_offset;
8680 if (sym->a.aligned) {
8681 size_t newoff = section_add(cur_text_section, 0,
8682 1 << (sym->a.aligned - 1));
8683 gen_fill_nops(newoff - ind);
8685 /* NOTE: we patch the symbol size later */
8686 put_extern_sym(sym, cur_text_section, ind, 0);
8687 if (sym->type.ref->f.func_ctor)
8688 add_array (tcc_state, ".init_array", sym->c);
8689 if (sym->type.ref->f.func_dtor)
8690 add_array (tcc_state, ".fini_array", sym->c);
8692 funcname = get_tok_str(sym->v, NULL);
8693 func_ind = ind;
8694 func_vt = sym->type.ref->type;
8695 func_var = sym->type.ref->f.func_type == FUNC_ELLIPSIS;
8697 /* put debug symbol */
8698 tcc_debug_funcstart(tcc_state, sym);
8699 /* push a dummy symbol to enable local sym storage */
8700 sym_push2(&local_stack, SYM_FIELD, 0, 0);
8701 local_scope = 1; /* for function parameters */
8702 gfunc_prolog(sym);
8703 local_scope = 0;
8704 rsym = 0;
8705 clear_temp_local_var_list();
8706 func_vla_arg(sym);
8707 block(0);
8708 gsym(rsym);
8709 nocode_wanted = 0;
8710 /* reset local stack */
8711 pop_local_syms(NULL, 0);
8712 gfunc_epilog();
8713 cur_text_section->data_offset = ind;
8714 local_scope = 0;
8715 label_pop(&global_label_stack, NULL, 0);
8716 sym_pop(&all_cleanups, NULL, 0);
8717 /* patch symbol size */
8718 elfsym(sym)->st_size = ind - func_ind;
8719 /* end of function */
8720 tcc_debug_funcend(tcc_state, ind - func_ind);
8721 /* It's better to crash than to generate wrong code */
8722 cur_text_section = NULL;
8723 funcname = ""; /* for safety */
8724 func_vt.t = VT_VOID; /* for safety */
8725 func_var = 0; /* for safety */
8726 ind = 0; /* for safety */
8727 nocode_wanted = 0x80000000;
8728 check_vstack();
8729 /* do this after funcend debug info */
8730 next();
8733 static void gen_inline_functions(TCCState *s)
8735 Sym *sym;
8736 int inline_generated, i;
8737 struct InlineFunc *fn;
8739 tcc_open_bf(s, ":inline:", 0);
8740 /* iterate while inline function are referenced */
8741 do {
8742 inline_generated = 0;
8743 for (i = 0; i < s->nb_inline_fns; ++i) {
8744 fn = s->inline_fns[i];
8745 sym = fn->sym;
8746 if (sym && (sym->c || !(sym->type.t & VT_INLINE))) {
8747 /* the function was used or forced (and then not internal):
8748 generate its code and convert it to a normal function */
8749 fn->sym = NULL;
8750 tcc_debug_putfile(s, fn->filename);
8751 begin_macro(fn->func_str, 1);
8752 next();
8753 cur_text_section = text_section;
8754 gen_function(sym);
8755 end_macro();
8757 inline_generated = 1;
8760 } while (inline_generated);
8761 tcc_close();
8764 static void free_inline_functions(TCCState *s)
8766 int i;
8767 /* free tokens of unused inline functions */
8768 for (i = 0; i < s->nb_inline_fns; ++i) {
8769 struct InlineFunc *fn = s->inline_fns[i];
8770 if (fn->sym)
8771 tok_str_free(fn->func_str);
8773 dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
8776 /* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
8777 if parsing old style parameter decl list (and FUNC_SYM is set then) */
8778 static int decl0(int l, int is_for_loop_init, Sym *func_sym)
8780 int v, has_init, r, oldint;
8781 CType type, btype;
8782 Sym *sym;
8783 AttributeDef ad, adbase;
8785 while (1) {
8786 if (tok == TOK_STATIC_ASSERT) {
8787 CString error_str;
8788 int c;
8790 next();
8791 skip('(');
8792 c = expr_const();
8794 if (tok == ')') {
8795 if (!c)
8796 tcc_error("_Static_assert fail");
8797 next();
8798 goto static_assert_out;
8801 skip(',');
8802 parse_mult_str(&error_str, "string constant");
8803 if (c == 0)
8804 tcc_error("%s", (char *)error_str.data);
8805 cstr_free(&error_str);
8806 skip(')');
8807 static_assert_out:
8808 skip(';');
8809 continue;
8812 oldint = 0;
8813 if (!parse_btype(&btype, &adbase)) {
8814 if (is_for_loop_init)
8815 return 0;
8816 /* skip redundant ';' if not in old parameter decl scope */
8817 if (tok == ';' && l != VT_CMP) {
8818 next();
8819 continue;
8821 if (l != VT_CONST)
8822 break;
8823 if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
8824 /* global asm block */
8825 asm_global_instr();
8826 continue;
8828 if (tok >= TOK_UIDENT) {
8829 /* special test for old K&R protos without explicit int
8830 type. Only accepted when defining global data */
8831 btype.t = VT_INT;
8832 oldint = 1;
8833 } else {
8834 if (tok != TOK_EOF)
8835 expect("declaration");
8836 break;
8840 if (tok == ';') {
8841 if ((btype.t & VT_BTYPE) == VT_STRUCT) {
8842 v = btype.ref->v;
8843 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
8844 tcc_warning("unnamed struct/union that defines no instances");
8845 next();
8846 continue;
8848 if (IS_ENUM(btype.t)) {
8849 next();
8850 continue;
8854 while (1) { /* iterate thru each declaration */
8855 type = btype;
8856 ad = adbase;
8857 type_decl(&type, &ad, &v, TYPE_DIRECT);
8858 #if 0
8860 char buf[500];
8861 type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL));
8862 printf("type = '%s'\n", buf);
8864 #endif
8865 if ((type.t & VT_BTYPE) == VT_FUNC) {
8866 if ((type.t & VT_STATIC) && (l == VT_LOCAL))
8867 tcc_error("function without file scope cannot be static");
8868 /* if old style function prototype, we accept a
8869 declaration list */
8870 sym = type.ref;
8871 if (sym->f.func_type == FUNC_OLD && l == VT_CONST)
8872 decl0(VT_CMP, 0, sym);
8873 #ifdef TCC_TARGET_MACHO
8874 if (sym->f.func_alwinl
8875 && ((type.t & (VT_EXTERN | VT_INLINE))
8876 == (VT_EXTERN | VT_INLINE))) {
8877 /* always_inline functions must be handled as if they
8878 don't generate multiple global defs, even if extern
8879 inline, i.e. GNU inline semantics for those. Rewrite
8880 them into static inline. */
8881 type.t &= ~VT_EXTERN;
8882 type.t |= VT_STATIC;
8884 #endif
8885 /* always compile 'extern inline' */
8886 if (type.t & VT_EXTERN)
8887 type.t &= ~VT_INLINE;
8889 } else if (oldint) {
8890 tcc_warning("type defaults to int");
8893 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
8894 ad.asm_label = asm_label_instr();
8895 /* parse one last attribute list, after asm label */
8896 parse_attribute(&ad);
8897 #if 0
8898 /* gcc does not allow __asm__("label") with function definition,
8899 but why not ... */
8900 if (tok == '{')
8901 expect(";");
8902 #endif
8905 #ifdef TCC_TARGET_PE
8906 if (ad.a.dllimport || ad.a.dllexport) {
8907 if (type.t & VT_STATIC)
8908 tcc_error("cannot have dll linkage with static");
8909 if (type.t & VT_TYPEDEF) {
8910 tcc_warning("'%s' attribute ignored for typedef",
8911 ad.a.dllimport ? (ad.a.dllimport = 0, "dllimport") :
8912 (ad.a.dllexport = 0, "dllexport"));
8913 } else if (ad.a.dllimport) {
8914 if ((type.t & VT_BTYPE) == VT_FUNC)
8915 ad.a.dllimport = 0;
8916 else
8917 type.t |= VT_EXTERN;
8920 #endif
8921 if (tok == '{') {
8922 if (l != VT_CONST)
8923 tcc_error("cannot use local functions");
8924 if ((type.t & VT_BTYPE) != VT_FUNC)
8925 expect("function definition");
8927 /* reject abstract declarators in function definition
8928 make old style params without decl have int type */
8929 sym = type.ref;
8930 while ((sym = sym->next) != NULL) {
8931 if (!(sym->v & ~SYM_FIELD))
8932 expect("identifier");
8933 if (sym->type.t == VT_VOID)
8934 sym->type = int_type;
8937 /* apply post-declaraton attributes */
8938 merge_funcattr(&type.ref->f, &ad.f);
8940 /* put function symbol */
8941 type.t &= ~VT_EXTERN;
8942 sym = external_sym(v, &type, 0, &ad);
8944 /* static inline functions are just recorded as a kind
8945 of macro. Their code will be emitted at the end of
8946 the compilation unit only if they are used */
8947 if (sym->type.t & VT_INLINE) {
8948 struct InlineFunc *fn;
8949 fn = tcc_malloc(sizeof *fn + strlen(file->filename));
8950 strcpy(fn->filename, file->filename);
8951 fn->sym = sym;
8952 skip_or_save_block(&fn->func_str);
8953 dynarray_add(&tcc_state->inline_fns,
8954 &tcc_state->nb_inline_fns, fn);
8955 } else {
8956 /* compute text section */
8957 cur_text_section = ad.section;
8958 if (!cur_text_section)
8959 cur_text_section = text_section;
8960 gen_function(sym);
8962 break;
8963 } else {
8964 if (l == VT_CMP) {
8965 /* find parameter in function parameter list */
8966 for (sym = func_sym->next; sym; sym = sym->next)
8967 if ((sym->v & ~SYM_FIELD) == v)
8968 goto found;
8969 tcc_error("declaration for parameter '%s' but no such parameter",
8970 get_tok_str(v, NULL));
8971 found:
8972 if (type.t & VT_STORAGE) /* 'register' is okay */
8973 tcc_error("storage class specified for '%s'",
8974 get_tok_str(v, NULL));
8975 if (sym->type.t != VT_VOID)
8976 tcc_error("redefinition of parameter '%s'",
8977 get_tok_str(v, NULL));
8978 convert_parameter_type(&type);
8979 sym->type = type;
8980 } else if (type.t & VT_TYPEDEF) {
8981 /* save typedefed type */
8982 /* XXX: test storage specifiers ? */
8983 sym = sym_find(v);
8984 if (sym && sym->sym_scope == local_scope) {
8985 if (!is_compatible_types(&sym->type, &type)
8986 || !(sym->type.t & VT_TYPEDEF))
8987 tcc_error("incompatible redefinition of '%s'",
8988 get_tok_str(v, NULL));
8989 sym->type = type;
8990 } else {
8991 sym = sym_push(v, &type, 0, 0);
8993 sym->a = ad.a;
8994 sym->f = ad.f;
8995 if (debug_modes)
8996 tcc_debug_typedef (tcc_state, sym);
8997 } else if ((type.t & VT_BTYPE) == VT_VOID
8998 && !(type.t & VT_EXTERN)) {
8999 tcc_error("declaration of void object");
9000 } else {
9001 r = 0;
9002 if ((type.t & VT_BTYPE) == VT_FUNC) {
9003 /* external function definition */
9004 /* specific case for func_call attribute */
9005 type.ref->f = ad.f;
9006 } else if (!(type.t & VT_ARRAY)) {
9007 /* not lvalue if array */
9008 r |= VT_LVAL;
9010 has_init = (tok == '=');
9011 if (has_init && (type.t & VT_VLA))
9012 tcc_error("variable length array cannot be initialized");
9013 if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST))
9014 || (type.t & VT_BTYPE) == VT_FUNC
9015 /* as with GCC, uninitialized global arrays with no size
9016 are considered extern: */
9017 || ((type.t & VT_ARRAY) && !has_init
9018 && l == VT_CONST && type.ref->c < 0)
9020 /* external variable or function */
9021 type.t |= VT_EXTERN;
9022 sym = external_sym(v, &type, r, &ad);
9023 if (ad.alias_target) {
9024 /* Aliases need to be emitted when their target
9025 symbol is emitted, even if perhaps unreferenced.
9026 We only support the case where the base is
9027 already defined, otherwise we would need
9028 deferring to emit the aliases until the end of
9029 the compile unit. */
9030 Sym *alias_target = sym_find(ad.alias_target);
9031 ElfSym *esym = elfsym(alias_target);
9032 if (!esym)
9033 tcc_error("unsupported forward __alias__ attribute");
9034 put_extern_sym2(sym, esym->st_shndx,
9035 esym->st_value, esym->st_size, 1);
9037 } else {
9038 if (type.t & VT_STATIC)
9039 r |= VT_CONST;
9040 else
9041 r |= l;
9042 if (has_init)
9043 next();
9044 else if (l == VT_CONST)
9045 /* uninitialized global variables may be overridden */
9046 type.t |= VT_EXTERN;
9047 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
9050 if (tok != ',') {
9051 if (is_for_loop_init)
9052 return 1;
9053 skip(';');
9054 break;
9056 next();
9060 return 0;
9063 static void decl(int l)
9065 decl0(l, 0, NULL);
9068 /* ------------------------------------------------------------------------- */
9069 #undef gjmp_addr
9070 #undef gjmp
9071 /* ------------------------------------------------------------------------- */