source: EcnlProtoTool/trunk/tcc-0.9.26/tccgen.c@ 279

Last change on this file since 279 was 279, checked in by coas-nagasima, 7 years ago

ファイルを追加、更新。

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 172.8 KB
Line 
1/*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001-2004 Fabrice Bellard
5 *
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.
10 *
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.
15 *
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
19 */
20
21#include "tcc.h"
22
23/********************************************************/
24/* global variables */
25
26/* loc : local variable index
27 ind : output code index
28 rsym: return symbol
29 anon_sym: anonymous symbol index
30*/
31ST_DATA int rsym, anon_sym, ind, loc;
32
33ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
34ST_DATA Section *cur_text_section; /* current section where function code is generated */
35#ifdef CONFIG_TCC_ASM
36ST_DATA Section *last_text_section; /* to handle .previous asm directive */
37#endif
38#ifdef CONFIG_TCC_BCHECK
39/* bound check related sections */
40ST_DATA Section *bounds_section; /* contains global data bound description */
41ST_DATA Section *lbounds_section; /* contains local data bound description */
42#endif
43/* symbol sections */
44ST_DATA Section *symtab_section, *strtab_section;
45/* debug sections */
46ST_DATA Section *stab_section, *stabstr_section;
47ST_DATA Sym *sym_free_first;
48ST_DATA void **sym_pools;
49ST_DATA int nb_sym_pools;
50
51ST_DATA Sym *global_stack;
52ST_DATA Sym *local_stack;
53ST_DATA Sym *scope_stack_bottom;
54ST_DATA Sym *define_stack;
55ST_DATA Sym *global_label_stack;
56ST_DATA Sym *local_label_stack;
57
58ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop;
59
60ST_DATA int const_wanted; /* true if constant wanted */
61ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
62ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
63ST_DATA CType func_vt; /* current function return type (used by return instruction) */
64ST_DATA int func_vc;
65ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
66ST_DATA char *funcname;
67
68ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
69
70/* ------------------------------------------------------------------------- */
71static void gen_cast(CType *type);
72static inline CType *pointed_type(CType *type);
73static int is_compatible_types(CType *type1, CType *type2);
74static int parse_btype(CType *type, AttributeDef *ad);
75static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
76static void parse_expr_type(CType *type);
77static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
78static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
79static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
80static int decl0(int l, int is_for_loop_init);
81static void expr_eq(void);
82static void unary_type(CType *type);
83static void vla_runtime_type_size(CType *type, int *a);
84static int is_compatible_parameter_types(CType *type1, CType *type2);
85static void expr_type(CType *type);
86
87ST_INLN int is_float(int t)
88{
89 int bt;
90 bt = t & VT_BTYPE;
91 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
92}
93
94/* we use our own 'finite' function to avoid potential problems with
95 non standard math libs */
96/* XXX: endianness dependent */
97ST_FUNC int ieee_finite(double d)
98{
99 int *p = (int *)&d;
100 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
101}
102
103ST_FUNC void test_lvalue(void)
104{
105 if (!(vtop->r & VT_LVAL))
106 expect("lvalue");
107}
108
109/* ------------------------------------------------------------------------- */
110/* symbol allocator */
111static Sym *__sym_malloc(void)
112{
113 Sym *sym_pool, *sym, *last_sym;
114 int i;
115
116 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
117 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
118
119 last_sym = sym_free_first;
120 sym = sym_pool;
121 for(i = 0; i < SYM_POOL_NB; i++) {
122 sym->next = last_sym;
123 last_sym = sym;
124 sym++;
125 }
126 sym_free_first = last_sym;
127 return last_sym;
128}
129
130static inline Sym *sym_malloc(void)
131{
132 Sym *sym;
133 sym = sym_free_first;
134 if (!sym)
135 sym = __sym_malloc();
136 sym_free_first = sym->next;
137 return sym;
138}
139
140ST_INLN void sym_free(Sym *sym)
141{
142 sym->next = sym_free_first;
143 tcc_free(sym->asm_label);
144 sym_free_first = sym;
145}
146
147/* push, without hashing */
148ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
149{
150 Sym *s;
151 if (ps == &local_stack) {
152 for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
153 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
154 tcc_error("incompatible types for redefinition of '%s'",
155 get_tok_str(v, NULL));
156 }
157 s = *ps;
158 s = sym_malloc();
159 s->asm_label = NULL;
160 s->v = v;
161 s->type.t = t;
162 s->type.ref = NULL;
163#ifdef _WIN64
164 s->d = NULL;
165#endif
166 s->c = c;
167 s->next = NULL;
168 /* add in stack */
169 s->prev = *ps;
170 *ps = s;
171 return s;
172}
173
174/* find a symbol and return its associated structure. 's' is the top
175 of the symbol stack */
176ST_FUNC Sym *sym_find2(Sym *s, int v)
177{
178 while (s) {
179 if (s->v == v)
180 return s;
181 s = s->prev;
182 }
183 return NULL;
184}
185
186/* structure lookup */
187ST_INLN Sym *struct_find(int v)
188{
189 v -= TOK_IDENT;
190 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
191 return NULL;
192 return table_ident[v]->sym_struct;
193}
194
195/* find an identifier */
196ST_INLN Sym *sym_find(int v)
197{
198 v -= TOK_IDENT;
199 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
200 return NULL;
201 return table_ident[v]->sym_identifier;
202}
203
204/* push a given symbol on the symbol stack */
205ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
206{
207 Sym *s, **ps;
208 TokenSym *ts;
209
210 if (local_stack)
211 ps = &local_stack;
212 else
213 ps = &global_stack;
214 s = sym_push2(ps, v, type->t, c);
215 s->type.ref = type->ref;
216 s->r = r;
217 /* don't record fields or anonymous symbols */
218 /* XXX: simplify */
219 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
220 /* record symbol in token array */
221 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
222 if (v & SYM_STRUCT)
223 ps = &ts->sym_struct;
224 else
225 ps = &ts->sym_identifier;
226 s->prev_tok = *ps;
227 *ps = s;
228 }
229 return s;
230}
231
232/* push a global identifier */
233ST_FUNC Sym *global_identifier_push(int v, int t, int c)
234{
235 Sym *s, **ps;
236 s = sym_push2(&global_stack, v, t, c);
237 /* don't record anonymous symbol */
238 if (v < SYM_FIRST_ANOM) {
239 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
240 /* modify the top most local identifier, so that
241 sym_identifier will point to 's' when popped */
242 while (*ps != NULL)
243 ps = &(*ps)->prev_tok;
244 s->prev_tok = NULL;
245 *ps = s;
246 }
247 return s;
248}
249
250/* pop symbols until top reaches 'b' */
251ST_FUNC void sym_pop(Sym **ptop, Sym *b)
252{
253 Sym *s, *ss, **ps;
254 TokenSym *ts;
255 int v;
256
257 s = *ptop;
258 while(s != b) {
259 ss = s->prev;
260 v = s->v;
261 /* remove symbol in token array */
262 /* XXX: simplify */
263 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
264 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
265 if (v & SYM_STRUCT)
266 ps = &ts->sym_struct;
267 else
268 ps = &ts->sym_identifier;
269 *ps = s->prev_tok;
270 }
271 sym_free(s);
272 s = ss;
273 }
274 *ptop = b;
275}
276
277static void weaken_symbol(Sym *sym)
278{
279 sym->type.t |= VT_WEAK;
280 if (sym->c > 0) {
281 int esym_type;
282 ElfW(Sym) *esym;
283
284 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
285 esym_type = ELFW(ST_TYPE)(esym->st_info);
286 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
287 }
288}
289
290/* ------------------------------------------------------------------------- */
291
292ST_FUNC void swap(int *p, int *q)
293{
294 int t;
295 t = *p;
296 *p = *q;
297 *q = t;
298}
299
300static void vsetc(CType *type, int r, CValue *vc)
301{
302 int v;
303
304 if (vtop >= vstack + (VSTACK_SIZE - 1))
305 tcc_error("memory full");
306 /* cannot let cpu flags if other instruction are generated. Also
307 avoid leaving VT_JMP anywhere except on the top of the stack
308 because it would complicate the code generator. */
309 if (vtop >= vstack) {
310 v = vtop->r & VT_VALMASK;
311 if (v == VT_CMP || (v & ~1) == VT_JMP)
312 gv(RC_INT);
313 }
314 vtop++;
315 vtop->type = *type;
316 vtop->r = r;
317 vtop->r2 = VT_CONST;
318 vtop->c = *vc;
319}
320
321/* push constant of type "type" with useless value */
322void vpush(CType *type)
323{
324 CValue cval;
325 vsetc(type, VT_CONST, &cval);
326}
327
328/* push integer constant */
329ST_FUNC void vpushi(int v)
330{
331 CValue cval;
332 cval.i = v;
333 vsetc(&int_type, VT_CONST, &cval);
334}
335
336/* push a pointer sized constant */
337static void vpushs(long long v)
338{
339 CValue cval;
340 if (PTR_SIZE == 4)
341 cval.i = (int)v;
342 else
343 cval.ull = v;
344 vsetc(&size_type, VT_CONST, &cval);
345}
346
347/* push arbitrary 64bit constant */
348void vpush64(int ty, unsigned long long v)
349{
350 CValue cval;
351 CType ctype;
352 ctype.t = ty;
353 ctype.ref = NULL;
354 cval.ull = v;
355 vsetc(&ctype, VT_CONST, &cval);
356}
357
358/* push long long constant */
359static inline void vpushll(long long v)
360{
361 vpush64(VT_LLONG, v);
362}
363
364/* Return a static symbol pointing to a section */
365ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
366{
367 int v;
368 Sym *sym;
369
370 v = anon_sym++;
371 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
372 sym->type.ref = type->ref;
373 sym->r = VT_CONST | VT_SYM;
374 put_extern_sym(sym, sec, offset, size);
375 return sym;
376}
377
378/* push a reference to a section offset by adding a dummy symbol */
379static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
380{
381 CValue cval;
382
383 cval.ul = 0;
384 vsetc(type, VT_CONST | VT_SYM, &cval);
385 vtop->sym = get_sym_ref(type, sec, offset, size);
386}
387
388/* define a new external reference to a symbol 'v' of type 'u' */
389ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
390{
391 Sym *s;
392
393 s = sym_find(v);
394 if (!s) {
395 /* push forward reference */
396 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
397 s->type.ref = type->ref;
398 s->r = r | VT_CONST | VT_SYM;
399 }
400 return s;
401}
402
403/* define a new external reference to a symbol 'v' with alternate asm
404 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
405 is no alternate name (most cases) */
406static Sym *external_sym(int v, CType *type, int r, char *asm_label)
407{
408 Sym *s;
409
410 s = sym_find(v);
411 if (!s) {
412 /* push forward reference */
413 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
414 s->asm_label = asm_label;
415 s->type.t |= VT_EXTERN;
416 } else if (s->type.ref == func_old_type.ref) {
417 s->type.ref = type->ref;
418 s->r = r | VT_CONST | VT_SYM;
419 s->type.t |= VT_EXTERN;
420 } else if (!is_compatible_types(&s->type, type)) {
421 tcc_error("incompatible types for redefinition of '%s'",
422 get_tok_str(v, NULL));
423 }
424 return s;
425}
426
427/* push a reference to global symbol v */
428ST_FUNC void vpush_global_sym(CType *type, int v)
429{
430 Sym *sym;
431 CValue cval;
432
433 sym = external_global_sym(v, type, 0);
434 cval.ul = 0;
435 vsetc(type, VT_CONST | VT_SYM, &cval);
436 vtop->sym = sym;
437}
438
439ST_FUNC void vset(CType *type, int r, int v)
440{
441 CValue cval;
442
443 cval.i = v;
444 vsetc(type, r, &cval);
445}
446
447static void vseti(int r, int v)
448{
449 CType type;
450 type.t = VT_INT;
451 type.ref = 0;
452 vset(&type, r, v);
453}
454
455ST_FUNC void vswap(void)
456{
457 SValue tmp;
458 /* cannot let cpu flags if other instruction are generated. Also
459 avoid leaving VT_JMP anywhere except on the top of the stack
460 because it would complicate the code generator. */
461 if (vtop >= vstack) {
462 int v = vtop->r & VT_VALMASK;
463 if (v == VT_CMP || (v & ~1) == VT_JMP)
464 gv(RC_INT);
465 }
466 tmp = vtop[0];
467 vtop[0] = vtop[-1];
468 vtop[-1] = tmp;
469
470/* XXX: +2% overall speed possible with optimized memswap
471 *
472 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
473 */
474}
475
476ST_FUNC void vpushv(SValue *v)
477{
478 if (vtop >= vstack + (VSTACK_SIZE - 1))
479 tcc_error("memory full");
480 vtop++;
481 *vtop = *v;
482}
483
484static void vdup(void)
485{
486 vpushv(vtop);
487}
488
489/* save r to the memory stack, and mark it as being free */
490ST_FUNC void save_reg(int r)
491{
492 int l, saved, size, align;
493 SValue *p, sv;
494 CType *type;
495
496 /* modify all stack values */
497 saved = 0;
498 l = 0;
499 for(p=vstack;p<=vtop;p++) {
500 if ((p->r & VT_VALMASK) == r ||
501 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
502 /* must save value on stack if not already done */
503 if (!saved) {
504 /* NOTE: must reload 'r' because r might be equal to r2 */
505 r = p->r & VT_VALMASK;
506 /* store register in the stack */
507 type = &p->type;
508 if ((p->r & VT_LVAL) ||
509 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
510#ifdef TCC_TARGET_X86_64
511 type = &char_pointer_type;
512#else
513 type = &int_type;
514#endif
515 size = type_size(type, &align);
516 loc = (loc - size) & -align;
517 sv.type.t = type->t;
518 sv.r = VT_LOCAL | VT_LVAL;
519 sv.c.ul = loc;
520 store(r, &sv);
521#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
522 /* x86 specific: need to pop fp register ST0 if saved */
523 if (r == TREG_ST0) {
524 o(0xd8dd); /* fstp %st(0) */
525 }
526#endif
527#ifndef TCC_TARGET_X86_64
528 /* special long long case */
529 if ((type->t & VT_BTYPE) == VT_LLONG) {
530 sv.c.ul += 4;
531 store(p->r2, &sv);
532 }
533#endif
534 l = loc;
535 saved = 1;
536 }
537 /* mark that stack entry as being saved on the stack */
538 if (p->r & VT_LVAL) {
539 /* also clear the bounded flag because the
540 relocation address of the function was stored in
541 p->c.ul */
542 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
543 } else {
544 p->r = lvalue_type(p->type.t) | VT_LOCAL;
545 }
546 p->r2 = VT_CONST;
547 p->c.ul = l;
548 }
549 }
550}
551
552#ifdef TCC_TARGET_ARM
553/* find a register of class 'rc2' with at most one reference on stack.
554 * If none, call get_reg(rc) */
555ST_FUNC int get_reg_ex(int rc, int rc2)
556{
557 int r;
558 SValue *p;
559
560 for(r=0;r<NB_REGS;r++) {
561 if (reg_classes[r] & rc2) {
562 int n;
563 n=0;
564 for(p = vstack; p <= vtop; p++) {
565 if ((p->r & VT_VALMASK) == r ||
566 (p->r2 & VT_VALMASK) == r)
567 n++;
568 }
569 if (n <= 1)
570 return r;
571 }
572 }
573 return get_reg(rc);
574}
575#endif
576
577/* find a free register of class 'rc'. If none, save one register */
578ST_FUNC int get_reg(int rc)
579{
580 int r;
581 SValue *p;
582
583 /* find a free register */
584 for(r=0;r<NB_REGS;r++) {
585 if (reg_classes[r] & rc) {
586 for(p=vstack;p<=vtop;p++) {
587 if ((p->r & VT_VALMASK) == r ||
588 (p->r2 & VT_VALMASK) == r)
589 goto notfound;
590 }
591 return r;
592 }
593 notfound: ;
594 }
595
596 /* no register left : free the first one on the stack (VERY
597 IMPORTANT to start from the bottom to ensure that we don't
598 spill registers used in gen_opi()) */
599 for(p=vstack;p<=vtop;p++) {
600 /* look at second register (if long long) */
601 r = p->r2 & VT_VALMASK;
602 if (r < VT_CONST && (reg_classes[r] & rc))
603 goto save_found;
604 r = p->r & VT_VALMASK;
605 if (r < VT_CONST && (reg_classes[r] & rc)) {
606 save_found:
607 save_reg(r);
608 return r;
609 }
610 }
611 /* Should never comes here */
612 return -1;
613}
614
615/* save registers up to (vtop - n) stack entry */
616ST_FUNC void save_regs(int n)
617{
618 int r;
619 SValue *p, *p1;
620 p1 = vtop - n;
621 for(p = vstack;p <= p1; p++) {
622 r = p->r & VT_VALMASK;
623 if (r < VT_CONST) {
624 save_reg(r);
625 }
626 }
627}
628
629/* move register 's' to 'r', and flush previous value of r to memory
630 if needed */
631static void move_reg(int r, int s)
632{
633 SValue sv;
634
635 if (r != s) {
636 save_reg(r);
637 sv.type.t = VT_INT;
638 sv.r = s;
639 sv.c.ul = 0;
640 load(r, &sv);
641 }
642}
643
644/* get address of vtop (vtop MUST BE an lvalue) */
645static void gaddrof(void)
646{
647 if (vtop->r & VT_REF)
648 gv(RC_INT);
649 vtop->r &= ~VT_LVAL;
650 /* tricky: if saved lvalue, then we can go back to lvalue */
651 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
652 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
653
654
655}
656
657#ifdef CONFIG_TCC_BCHECK
658/* generate lvalue bound code */
659static void gbound(void)
660{
661 int lval_type;
662 CType type1;
663
664 vtop->r &= ~VT_MUSTBOUND;
665 /* if lvalue, then use checking code before dereferencing */
666 if (vtop->r & VT_LVAL) {
667 /* if not VT_BOUNDED value, then make one */
668 if (!(vtop->r & VT_BOUNDED)) {
669 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
670 /* must save type because we must set it to int to get pointer */
671 type1 = vtop->type;
672 vtop->type.t = VT_INT;
673 gaddrof();
674 vpushi(0);
675 gen_bounded_ptr_add();
676 vtop->r |= lval_type;
677 vtop->type = type1;
678 }
679 /* then check for dereferencing */
680 gen_bounded_ptr_deref();
681 }
682}
683#endif
684
685/* store vtop a register belonging to class 'rc'. lvalues are
686 converted to values. Cannot be used if cannot be converted to
687 register value (such as structures). */
688ST_FUNC int gv(int rc)
689{
690 int r, bit_pos, bit_size, size, align, i;
691#ifndef TCC_TARGET_X86_64
692 int rc2;
693#endif
694
695 /* NOTE: get_reg can modify vstack[] */
696 if (vtop->type.t & VT_BITFIELD) {
697 CType type;
698 int bits = 32;
699 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
700 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
701 /* remove bit field info to avoid loops */
702 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
703 /* cast to int to propagate signedness in following ops */
704 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
705 type.t = VT_LLONG;
706 bits = 64;
707 } else
708 type.t = VT_INT;
709 if((vtop->type.t & VT_UNSIGNED) ||
710 (vtop->type.t & VT_BTYPE) == VT_BOOL)
711 type.t |= VT_UNSIGNED;
712 gen_cast(&type);
713 /* generate shifts */
714 vpushi(bits - (bit_pos + bit_size));
715 gen_op(TOK_SHL);
716 vpushi(bits - bit_size);
717 /* NOTE: transformed to SHR if unsigned */
718 gen_op(TOK_SAR);
719 r = gv(rc);
720 } else {
721 if (is_float(vtop->type.t) &&
722 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
723 Sym *sym;
724 int *ptr;
725 unsigned long offset;
726#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
727 CValue check;
728#endif
729
730 /* XXX: unify with initializers handling ? */
731 /* CPUs usually cannot use float constants, so we store them
732 generically in data segment */
733 size = type_size(&vtop->type, &align);
734 offset = (data_section->data_offset + align - 1) & -align;
735 data_section->data_offset = offset;
736 /* XXX: not portable yet */
737#if defined(__i386__) || defined(__x86_64__)
738 /* Zero pad x87 tenbyte long doubles */
739 if (size == LDOUBLE_SIZE) {
740 vtop->c.tab[2] &= 0xffff;
741#if LDOUBLE_SIZE == 16
742 vtop->c.tab[3] = 0;
743#endif
744 }
745#endif
746 ptr = section_ptr_add(data_section, size);
747 size = size >> 2;
748#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
749 check.d = 1;
750 if(check.tab[0])
751 for(i=0;i<size;i++)
752 ptr[i] = vtop->c.tab[size-1-i];
753 else
754#endif
755 for(i=0;i<size;i++)
756 ptr[i] = vtop->c.tab[i];
757 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
758 vtop->r |= VT_LVAL | VT_SYM;
759 vtop->sym = sym;
760 vtop->c.ul = 0;
761 }
762#ifdef CONFIG_TCC_BCHECK
763 if (vtop->r & VT_MUSTBOUND)
764 gbound();
765#endif
766
767 r = vtop->r & VT_VALMASK;
768#ifndef TCC_TARGET_X86_64
769 rc2 = RC_INT;
770 if (rc == RC_IRET)
771 rc2 = RC_LRET;
772#endif
773 /* need to reload if:
774 - constant
775 - lvalue (need to dereference pointer)
776 - already a register, but not in the right class */
777 if (r >= VT_CONST
778 || (vtop->r & VT_LVAL)
779 || !(reg_classes[r] & rc)
780#ifndef TCC_TARGET_X86_64
781 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
782#endif
783 )
784 {
785 r = get_reg(rc);
786#ifndef TCC_TARGET_X86_64
787 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
788 int r2;
789 unsigned long long ll;
790 /* two register type load : expand to two words
791 temporarily */
792 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
793 /* load constant */
794 ll = vtop->c.ull;
795 vtop->c.ui = ll; /* first word */
796 load(r, vtop);
797 vtop->r = r; /* save register value */
798 vpushi(ll >> 32); /* second word */
799 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
800 (vtop->r & VT_LVAL)) {
801 /* We do not want to modifier the long long
802 pointer here, so the safest (and less
803 efficient) is to save all the other registers
804 in the stack. XXX: totally inefficient. */
805 save_regs(1);
806 /* load from memory */
807 load(r, vtop);
808 vdup();
809 vtop[-1].r = r; /* save register value */
810 /* increment pointer to get second word */
811 vtop->type.t = VT_INT;
812 gaddrof();
813 vpushi(4);
814 gen_op('+');
815 vtop->r |= VT_LVAL;
816 } else {
817 /* move registers */
818 load(r, vtop);
819 vdup();
820 vtop[-1].r = r; /* save register value */
821 vtop->r = vtop[-1].r2;
822 }
823 /* Allocate second register. Here we rely on the fact that
824 get_reg() tries first to free r2 of an SValue. */
825 r2 = get_reg(rc2);
826 load(r2, vtop);
827 vpop();
828 /* write second register */
829 vtop->r2 = r2;
830 } else
831#endif
832 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
833 int t1, t;
834 /* lvalue of scalar type : need to use lvalue type
835 because of possible cast */
836 t = vtop->type.t;
837 t1 = t;
838 /* compute memory access type */
839 if (vtop->r & VT_LVAL_BYTE)
840 t = VT_BYTE;
841 else if (vtop->r & VT_LVAL_SHORT)
842 t = VT_SHORT;
843 if (vtop->r & VT_LVAL_UNSIGNED)
844 t |= VT_UNSIGNED;
845 vtop->type.t = t;
846 load(r, vtop);
847 /* restore wanted type */
848 vtop->type.t = t1;
849 } else {
850 /* one register type load */
851 load(r, vtop);
852 }
853 }
854 vtop->r = r;
855#ifdef TCC_TARGET_C67
856 /* uses register pairs for doubles */
857 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
858 vtop->r2 = r+1;
859#endif
860 }
861 return r;
862}
863
864/* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
865ST_FUNC void gv2(int rc1, int rc2)
866{
867 int v;
868
869 /* generate more generic register first. But VT_JMP or VT_CMP
870 values must be generated first in all cases to avoid possible
871 reload errors */
872 v = vtop[0].r & VT_VALMASK;
873 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
874 vswap();
875 gv(rc1);
876 vswap();
877 gv(rc2);
878 /* test if reload is needed for first register */
879 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
880 vswap();
881 gv(rc1);
882 vswap();
883 }
884 } else {
885 gv(rc2);
886 vswap();
887 gv(rc1);
888 vswap();
889 /* test if reload is needed for first register */
890 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
891 gv(rc2);
892 }
893 }
894}
895
896/* wrapper around RC_FRET to return a register by type */
897static int rc_fret(int t)
898{
899#ifdef TCC_TARGET_X86_64
900 if (t == VT_LDOUBLE) {
901 return RC_ST0;
902 }
903#endif
904 return RC_FRET;
905}
906
907/* wrapper around REG_FRET to return a register by type */
908static int reg_fret(int t)
909{
910#ifdef TCC_TARGET_X86_64
911 if (t == VT_LDOUBLE) {
912 return TREG_ST0;
913 }
914#endif
915 return REG_FRET;
916}
917
918/* expand long long on stack in two int registers */
919static void lexpand(void)
920{
921 int u;
922
923 u = vtop->type.t & VT_UNSIGNED;
924 gv(RC_INT);
925 vdup();
926 vtop[0].r = vtop[-1].r2;
927 vtop[0].r2 = VT_CONST;
928 vtop[-1].r2 = VT_CONST;
929 vtop[0].type.t = VT_INT | u;
930 vtop[-1].type.t = VT_INT | u;
931}
932
933#ifdef TCC_TARGET_ARM
934/* expand long long on stack */
935ST_FUNC void lexpand_nr(void)
936{
937 int u,v;
938
939 u = vtop->type.t & VT_UNSIGNED;
940 vdup();
941 vtop->r2 = VT_CONST;
942 vtop->type.t = VT_INT | u;
943 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
944 if (v == VT_CONST) {
945 vtop[-1].c.ui = vtop->c.ull;
946 vtop->c.ui = vtop->c.ull >> 32;
947 vtop->r = VT_CONST;
948 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
949 vtop->c.ui += 4;
950 vtop->r = vtop[-1].r;
951 } else if (v > VT_CONST) {
952 vtop--;
953 lexpand();
954 } else
955 vtop->r = vtop[-1].r2;
956 vtop[-1].r2 = VT_CONST;
957 vtop[-1].type.t = VT_INT | u;
958}
959#endif
960
961/* build a long long from two ints */
962static void lbuild(int t)
963{
964 gv2(RC_INT, RC_INT);
965 vtop[-1].r2 = vtop[0].r;
966 vtop[-1].type.t = t;
967 vpop();
968}
969
970/* rotate n first stack elements to the bottom
971 I1 ... In -> I2 ... In I1 [top is right]
972*/
973ST_FUNC void vrotb(int n)
974{
975 int i;
976 SValue tmp;
977
978 tmp = vtop[-n + 1];
979 for(i=-n+1;i!=0;i++)
980 vtop[i] = vtop[i+1];
981 vtop[0] = tmp;
982}
983
984/* rotate the n elements before entry e towards the top
985 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
986 */
987ST_FUNC void vrote(SValue *e, int n)
988{
989 int i;
990 SValue tmp;
991
992 tmp = *e;
993 for(i = 0;i < n - 1; i++)
994 e[-i] = e[-i - 1];
995 e[-n + 1] = tmp;
996}
997
998/* rotate n first stack elements to the top
999 I1 ... In -> In I1 ... I(n-1) [top is right]
1000 */
1001ST_FUNC void vrott(int n)
1002{
1003 vrote(vtop, n);
1004}
1005
1006/* pop stack value */
1007ST_FUNC void vpop(void)
1008{
1009 int v;
1010 v = vtop->r & VT_VALMASK;
1011#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1012 /* for x86, we need to pop the FP stack */
1013 if (v == TREG_ST0 && !nocode_wanted) {
1014 o(0xd8dd); /* fstp %st(0) */
1015 } else
1016#endif
1017 if (v == VT_JMP || v == VT_JMPI) {
1018 /* need to put correct jump if && or || without test */
1019 gsym(vtop->c.ul);
1020 }
1021 vtop--;
1022}
1023
1024/* convert stack entry to register and duplicate its value in another
1025 register */
1026static void gv_dup(void)
1027{
1028 int rc, t, r, r1;
1029 SValue sv;
1030
1031 t = vtop->type.t;
1032 if ((t & VT_BTYPE) == VT_LLONG) {
1033 lexpand();
1034 gv_dup();
1035 vswap();
1036 vrotb(3);
1037 gv_dup();
1038 vrotb(4);
1039 /* stack: H L L1 H1 */
1040 lbuild(t);
1041 vrotb(3);
1042 vrotb(3);
1043 vswap();
1044 lbuild(t);
1045 vswap();
1046 } else {
1047 /* duplicate value */
1048 rc = RC_INT;
1049 sv.type.t = VT_INT;
1050 if (is_float(t)) {
1051 rc = RC_FLOAT;
1052#ifdef TCC_TARGET_X86_64
1053 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1054 rc = RC_ST0;
1055 }
1056#endif
1057 sv.type.t = t;
1058 }
1059 r = gv(rc);
1060 r1 = get_reg(rc);
1061 sv.r = r;
1062 sv.c.ul = 0;
1063 load(r1, &sv); /* move r to r1 */
1064 vdup();
1065 /* duplicates value */
1066 if (r != r1)
1067 vtop->r = r1;
1068 }
1069}
1070
1071#ifndef TCC_TARGET_X86_64
1072/* generate CPU independent (unsigned) long long operations */
1073static void gen_opl(int op)
1074{
1075 int t, a, b, op1, c, i;
1076 int func;
1077 unsigned short reg_iret = REG_IRET;
1078 unsigned short reg_lret = REG_LRET;
1079 SValue tmp;
1080
1081 switch(op) {
1082 case '/':
1083 case TOK_PDIV:
1084 func = TOK___divdi3;
1085 goto gen_func;
1086 case TOK_UDIV:
1087 func = TOK___udivdi3;
1088 goto gen_func;
1089 case '%':
1090 func = TOK___moddi3;
1091 goto gen_mod_func;
1092 case TOK_UMOD:
1093 func = TOK___umoddi3;
1094 gen_mod_func:
1095#ifdef TCC_ARM_EABI
1096 reg_iret = TREG_R2;
1097 reg_lret = TREG_R3;
1098#endif
1099 gen_func:
1100 /* call generic long long function */
1101 vpush_global_sym(&func_old_type, func);
1102 vrott(3);
1103 gfunc_call(2);
1104 vpushi(0);
1105 vtop->r = reg_iret;
1106 vtop->r2 = reg_lret;
1107 break;
1108 case '^':
1109 case '&':
1110 case '|':
1111 case '*':
1112 case '+':
1113 case '-':
1114 t = vtop->type.t;
1115 vswap();
1116 lexpand();
1117 vrotb(3);
1118 lexpand();
1119 /* stack: L1 H1 L2 H2 */
1120 tmp = vtop[0];
1121 vtop[0] = vtop[-3];
1122 vtop[-3] = tmp;
1123 tmp = vtop[-2];
1124 vtop[-2] = vtop[-3];
1125 vtop[-3] = tmp;
1126 vswap();
1127 /* stack: H1 H2 L1 L2 */
1128 if (op == '*') {
1129 vpushv(vtop - 1);
1130 vpushv(vtop - 1);
1131 gen_op(TOK_UMULL);
1132 lexpand();
1133 /* stack: H1 H2 L1 L2 ML MH */
1134 for(i=0;i<4;i++)
1135 vrotb(6);
1136 /* stack: ML MH H1 H2 L1 L2 */
1137 tmp = vtop[0];
1138 vtop[0] = vtop[-2];
1139 vtop[-2] = tmp;
1140 /* stack: ML MH H1 L2 H2 L1 */
1141 gen_op('*');
1142 vrotb(3);
1143 vrotb(3);
1144 gen_op('*');
1145 /* stack: ML MH M1 M2 */
1146 gen_op('+');
1147 gen_op('+');
1148 } else if (op == '+' || op == '-') {
1149 /* XXX: add non carry method too (for MIPS or alpha) */
1150 if (op == '+')
1151 op1 = TOK_ADDC1;
1152 else
1153 op1 = TOK_SUBC1;
1154 gen_op(op1);
1155 /* stack: H1 H2 (L1 op L2) */
1156 vrotb(3);
1157 vrotb(3);
1158 gen_op(op1 + 1); /* TOK_xxxC2 */
1159 } else {
1160 gen_op(op);
1161 /* stack: H1 H2 (L1 op L2) */
1162 vrotb(3);
1163 vrotb(3);
1164 /* stack: (L1 op L2) H1 H2 */
1165 gen_op(op);
1166 /* stack: (L1 op L2) (H1 op H2) */
1167 }
1168 /* stack: L H */
1169 lbuild(t);
1170 break;
1171 case TOK_SAR:
1172 case TOK_SHR:
1173 case TOK_SHL:
1174 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1175 t = vtop[-1].type.t;
1176 vswap();
1177 lexpand();
1178 vrotb(3);
1179 /* stack: L H shift */
1180 c = (int)vtop->c.i;
1181 /* constant: simpler */
1182 /* NOTE: all comments are for SHL. the other cases are
1183 done by swaping words */
1184 vpop();
1185 if (op != TOK_SHL)
1186 vswap();
1187 if (c >= 32) {
1188 /* stack: L H */
1189 vpop();
1190 if (c > 32) {
1191 vpushi(c - 32);
1192 gen_op(op);
1193 }
1194 if (op != TOK_SAR) {
1195 vpushi(0);
1196 } else {
1197 gv_dup();
1198 vpushi(31);
1199 gen_op(TOK_SAR);
1200 }
1201 vswap();
1202 } else {
1203 vswap();
1204 gv_dup();
1205 /* stack: H L L */
1206 vpushi(c);
1207 gen_op(op);
1208 vswap();
1209 vpushi(32 - c);
1210 if (op == TOK_SHL)
1211 gen_op(TOK_SHR);
1212 else
1213 gen_op(TOK_SHL);
1214 vrotb(3);
1215 /* stack: L L H */
1216 vpushi(c);
1217 if (op == TOK_SHL)
1218 gen_op(TOK_SHL);
1219 else
1220 gen_op(TOK_SHR);
1221 gen_op('|');
1222 }
1223 if (op != TOK_SHL)
1224 vswap();
1225 lbuild(t);
1226 } else {
1227 /* XXX: should provide a faster fallback on x86 ? */
1228 switch(op) {
1229 case TOK_SAR:
1230 func = TOK___ashrdi3;
1231 goto gen_func;
1232 case TOK_SHR:
1233 func = TOK___lshrdi3;
1234 goto gen_func;
1235 case TOK_SHL:
1236 func = TOK___ashldi3;
1237 goto gen_func;
1238 }
1239 }
1240 break;
1241 default:
1242 /* compare operations */
1243 t = vtop->type.t;
1244 vswap();
1245 lexpand();
1246 vrotb(3);
1247 lexpand();
1248 /* stack: L1 H1 L2 H2 */
1249 tmp = vtop[-1];
1250 vtop[-1] = vtop[-2];
1251 vtop[-2] = tmp;
1252 /* stack: L1 L2 H1 H2 */
1253 /* compare high */
1254 op1 = op;
1255 /* when values are equal, we need to compare low words. since
1256 the jump is inverted, we invert the test too. */
1257 if (op1 == TOK_LT)
1258 op1 = TOK_LE;
1259 else if (op1 == TOK_GT)
1260 op1 = TOK_GE;
1261 else if (op1 == TOK_ULT)
1262 op1 = TOK_ULE;
1263 else if (op1 == TOK_UGT)
1264 op1 = TOK_UGE;
1265 a = 0;
1266 b = 0;
1267 gen_op(op1);
1268 if (op1 != TOK_NE) {
1269 a = gtst(1, 0);
1270 }
1271 if (op != TOK_EQ) {
1272 /* generate non equal test */
1273 /* XXX: NOT PORTABLE yet */
1274 if (a == 0) {
1275 b = gtst(0, 0);
1276 } else {
1277#if defined(TCC_TARGET_I386)
1278 b = psym(0x850f, 0);
1279#elif defined(TCC_TARGET_ARM)
1280 b = ind;
1281 o(0x1A000000 | encbranch(ind, 0, 1));
1282#elif defined(TCC_TARGET_C67)
1283 tcc_error("not implemented");
1284#elif defined(TCC_TARGET_IL)
1285 tcc_error("not implemented");
1286#else
1287#error not supported
1288#endif
1289 }
1290 }
1291 /* compare low. Always unsigned */
1292 op1 = op;
1293 if (op1 == TOK_LT)
1294 op1 = TOK_ULT;
1295 else if (op1 == TOK_LE)
1296 op1 = TOK_ULE;
1297 else if (op1 == TOK_GT)
1298 op1 = TOK_UGT;
1299 else if (op1 == TOK_GE)
1300 op1 = TOK_UGE;
1301 gen_op(op1);
1302 a = gtst(1, a);
1303 gsym(b);
1304 vseti(VT_JMPI, a);
1305 break;
1306 }
1307}
1308#endif
1309
1310/* handle integer constant optimizations and various machine
1311 independent opt */
1312static void gen_opic(int op)
1313{
1314 int c1, c2, t1, t2, n;
1315 SValue *v1, *v2;
1316 long long l1, l2;
1317 typedef unsigned long long U;
1318
1319 v1 = vtop - 1;
1320 v2 = vtop;
1321 t1 = v1->type.t & VT_BTYPE;
1322 t2 = v2->type.t & VT_BTYPE;
1323
1324 if (t1 == VT_LLONG)
1325 l1 = v1->c.ll;
1326 else if (v1->type.t & VT_UNSIGNED)
1327 l1 = v1->c.ui;
1328 else
1329 l1 = v1->c.i;
1330
1331 if (t2 == VT_LLONG)
1332 l2 = v2->c.ll;
1333 else if (v2->type.t & VT_UNSIGNED)
1334 l2 = v2->c.ui;
1335 else
1336 l2 = v2->c.i;
1337
1338 /* currently, we cannot do computations with forward symbols */
1339 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1340 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1341 if (c1 && c2) {
1342 switch(op) {
1343 case '+': l1 += l2; break;
1344 case '-': l1 -= l2; break;
1345 case '&': l1 &= l2; break;
1346 case '^': l1 ^= l2; break;
1347 case '|': l1 |= l2; break;
1348 case '*': l1 *= l2; break;
1349
1350 case TOK_PDIV:
1351 case '/':
1352 case '%':
1353 case TOK_UDIV:
1354 case TOK_UMOD:
1355 /* if division by zero, generate explicit division */
1356 if (l2 == 0) {
1357 if (const_wanted)
1358 tcc_error("division by zero in constant");
1359 goto general_case;
1360 }
1361 switch(op) {
1362 default: l1 /= l2; break;
1363 case '%': l1 %= l2; break;
1364 case TOK_UDIV: l1 = (U)l1 / l2; break;
1365 case TOK_UMOD: l1 = (U)l1 % l2; break;
1366 }
1367 break;
1368 case TOK_SHL: l1 <<= l2; break;
1369 case TOK_SHR: l1 = (U)l1 >> l2; break;
1370 case TOK_SAR: l1 >>= l2; break;
1371 /* tests */
1372 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1373 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1374 case TOK_EQ: l1 = l1 == l2; break;
1375 case TOK_NE: l1 = l1 != l2; break;
1376 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1377 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1378 case TOK_LT: l1 = l1 < l2; break;
1379 case TOK_GE: l1 = l1 >= l2; break;
1380 case TOK_LE: l1 = l1 <= l2; break;
1381 case TOK_GT: l1 = l1 > l2; break;
1382 /* logical */
1383 case TOK_LAND: l1 = l1 && l2; break;
1384 case TOK_LOR: l1 = l1 || l2; break;
1385 default:
1386 goto general_case;
1387 }
1388 v1->c.ll = l1;
1389 vtop--;
1390 } else {
1391 /* if commutative ops, put c2 as constant */
1392 if (c1 && (op == '+' || op == '&' || op == '^' ||
1393 op == '|' || op == '*')) {
1394 vswap();
1395 c2 = c1; //c = c1, c1 = c2, c2 = c;
1396 l2 = l1; //l = l1, l1 = l2, l2 = l;
1397 }
1398 /* Filter out NOP operations like x*1, x-0, x&-1... */
1399 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1400 op == TOK_PDIV) &&
1401 l2 == 1) ||
1402 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1403 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1404 l2 == 0) ||
1405 (op == '&' &&
1406 l2 == -1))) {
1407 /* nothing to do */
1408 vtop--;
1409 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1410 /* try to use shifts instead of muls or divs */
1411 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1412 n = -1;
1413 while (l2) {
1414 l2 >>= 1;
1415 n++;
1416 }
1417 vtop->c.ll = n;
1418 if (op == '*')
1419 op = TOK_SHL;
1420 else if (op == TOK_PDIV)
1421 op = TOK_SAR;
1422 else
1423 op = TOK_SHR;
1424 }
1425 goto general_case;
1426 } else if (c2 && (op == '+' || op == '-') &&
1427 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1428 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1429 /* symbol + constant case */
1430 if (op == '-')
1431 l2 = -l2;
1432 vtop--;
1433 vtop->c.ll += l2;
1434 } else {
1435 general_case:
1436 if (!nocode_wanted) {
1437 /* call low level op generator */
1438 if (t1 == VT_LLONG || t2 == VT_LLONG)
1439 gen_opl(op);
1440 else
1441 gen_opi(op);
1442 } else {
1443 vtop--;
1444 }
1445 }
1446 }
1447}
1448
1449/* generate a floating point operation with constant propagation */
1450static void gen_opif(int op)
1451{
1452 int c1, c2;
1453 SValue *v1, *v2;
1454 long double f1, f2;
1455
1456 v1 = vtop - 1;
1457 v2 = vtop;
1458 /* currently, we cannot do computations with forward symbols */
1459 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1460 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1461 if (c1 && c2) {
1462 if (v1->type.t == VT_FLOAT) {
1463 f1 = v1->c.f;
1464 f2 = v2->c.f;
1465 } else if (v1->type.t == VT_DOUBLE) {
1466 f1 = v1->c.d;
1467 f2 = v2->c.d;
1468 } else {
1469 f1 = v1->c.ld;
1470 f2 = v2->c.ld;
1471 }
1472
1473 /* NOTE: we only do constant propagation if finite number (not
1474 NaN or infinity) (ANSI spec) */
1475 if (!ieee_finite(f1) || !ieee_finite(f2))
1476 goto general_case;
1477
1478 switch(op) {
1479 case '+': f1 += f2; break;
1480 case '-': f1 -= f2; break;
1481 case '*': f1 *= f2; break;
1482 case '/':
1483 if (f2 == 0.0) {
1484 if (const_wanted)
1485 tcc_error("division by zero in constant");
1486 goto general_case;
1487 }
1488 f1 /= f2;
1489 break;
1490 /* XXX: also handles tests ? */
1491 default:
1492 goto general_case;
1493 }
1494 /* XXX: overflow test ? */
1495 if (v1->type.t == VT_FLOAT) {
1496 v1->c.f = f1;
1497 } else if (v1->type.t == VT_DOUBLE) {
1498 v1->c.d = f1;
1499 } else {
1500 v1->c.ld = f1;
1501 }
1502 vtop--;
1503 } else {
1504 general_case:
1505 if (!nocode_wanted) {
1506 gen_opf(op);
1507 } else {
1508 vtop--;
1509 }
1510 }
1511}
1512
1513static int pointed_size(CType *type)
1514{
1515 int align;
1516 return type_size(pointed_type(type), &align);
1517}
1518
1519static void vla_runtime_pointed_size(CType *type)
1520{
1521 int align;
1522 vla_runtime_type_size(pointed_type(type), &align);
1523}
1524
1525static inline int is_null_pointer(SValue *p)
1526{
1527 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1528 return 0;
1529 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1530 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
1531 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0);
1532}
1533
1534static inline int is_integer_btype(int bt)
1535{
1536 return (bt == VT_BYTE || bt == VT_SHORT ||
1537 bt == VT_INT || bt == VT_LLONG);
1538}
1539
1540/* check types for comparison or substraction of pointers */
1541static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1542{
1543 CType *type1, *type2, tmp_type1, tmp_type2;
1544 int bt1, bt2;
1545
1546 /* null pointers are accepted for all comparisons as gcc */
1547 if (is_null_pointer(p1) || is_null_pointer(p2))
1548 return;
1549 type1 = &p1->type;
1550 type2 = &p2->type;
1551 bt1 = type1->t & VT_BTYPE;
1552 bt2 = type2->t & VT_BTYPE;
1553 /* accept comparison between pointer and integer with a warning */
1554 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1555 if (op != TOK_LOR && op != TOK_LAND )
1556 tcc_warning("comparison between pointer and integer");
1557 return;
1558 }
1559
1560 /* both must be pointers or implicit function pointers */
1561 if (bt1 == VT_PTR) {
1562 type1 = pointed_type(type1);
1563 } else if (bt1 != VT_FUNC)
1564 goto invalid_operands;
1565
1566 if (bt2 == VT_PTR) {
1567 type2 = pointed_type(type2);
1568 } else if (bt2 != VT_FUNC) {
1569 invalid_operands:
1570 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1571 }
1572 if ((type1->t & VT_BTYPE) == VT_VOID ||
1573 (type2->t & VT_BTYPE) == VT_VOID)
1574 return;
1575 tmp_type1 = *type1;
1576 tmp_type2 = *type2;
1577 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1578 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1579 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1580 /* gcc-like error if '-' is used */
1581 if (op == '-')
1582 goto invalid_operands;
1583 else
1584 tcc_warning("comparison of distinct pointer types lacks a cast");
1585 }
1586}
1587
1588/* generic gen_op: handles types problems */
1589ST_FUNC void gen_op(int op)
1590{
1591 int u, t1, t2, bt1, bt2, t;
1592 CType type1;
1593
1594 t1 = vtop[-1].type.t;
1595 t2 = vtop[0].type.t;
1596 bt1 = t1 & VT_BTYPE;
1597 bt2 = t2 & VT_BTYPE;
1598
1599 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1600 /* at least one operand is a pointer */
1601 /* relationnal op: must be both pointers */
1602 if (op >= TOK_ULT && op <= TOK_LOR) {
1603 check_comparison_pointer_types(vtop - 1, vtop, op);
1604 /* pointers are handled are unsigned */
1605#ifdef TCC_TARGET_X86_64
1606 t = VT_LLONG | VT_UNSIGNED;
1607#else
1608 t = VT_INT | VT_UNSIGNED;
1609#endif
1610 goto std_op;
1611 }
1612 /* if both pointers, then it must be the '-' op */
1613 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1614 if (op != '-')
1615 tcc_error("cannot use pointers here");
1616 check_comparison_pointer_types(vtop - 1, vtop, op);
1617 /* XXX: check that types are compatible */
1618 if (vtop[-1].type.t & VT_VLA) {
1619 vla_runtime_pointed_size(&vtop[-1].type);
1620 } else {
1621 vpushi(pointed_size(&vtop[-1].type));
1622 }
1623 vrott(3);
1624 gen_opic(op);
1625 /* set to integer type */
1626#ifdef TCC_TARGET_X86_64
1627 vtop->type.t = VT_LLONG;
1628#else
1629 vtop->type.t = VT_INT;
1630#endif
1631 vswap();
1632 gen_op(TOK_PDIV);
1633 } else {
1634 /* exactly one pointer : must be '+' or '-'. */
1635 if (op != '-' && op != '+')
1636 tcc_error("cannot use pointers here");
1637 /* Put pointer as first operand */
1638 if (bt2 == VT_PTR) {
1639 vswap();
1640 swap(&t1, &t2);
1641 }
1642 type1 = vtop[-1].type;
1643 type1.t &= ~VT_ARRAY;
1644 if (vtop[-1].type.t & VT_VLA)
1645 vla_runtime_pointed_size(&vtop[-1].type);
1646 else {
1647 u = pointed_size(&vtop[-1].type);
1648 if (u < 0)
1649 tcc_error("unknown array element size");
1650#ifdef TCC_TARGET_X86_64
1651 vpushll(u);
1652#else
1653 /* XXX: cast to int ? (long long case) */
1654 vpushi(u);
1655#endif
1656 }
1657 gen_op('*');
1658#ifdef CONFIG_TCC_BCHECK
1659 /* if evaluating constant expression, no code should be
1660 generated, so no bound check */
1661 if (tcc_state->do_bounds_check && !const_wanted) {
1662 /* if bounded pointers, we generate a special code to
1663 test bounds */
1664 if (op == '-') {
1665 vpushi(0);
1666 vswap();
1667 gen_op('-');
1668 }
1669 gen_bounded_ptr_add();
1670 } else
1671#endif
1672 {
1673 gen_opic(op);
1674 }
1675 /* put again type if gen_opic() swaped operands */
1676 vtop->type = type1;
1677 }
1678 } else if (is_float(bt1) || is_float(bt2)) {
1679 /* compute bigger type and do implicit casts */
1680 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1681 t = VT_LDOUBLE;
1682 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1683 t = VT_DOUBLE;
1684 } else {
1685 t = VT_FLOAT;
1686 }
1687 /* floats can only be used for a few operations */
1688 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1689 (op < TOK_ULT || op > TOK_GT))
1690 tcc_error("invalid operands for binary operation");
1691 goto std_op;
1692 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
1693 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
1694 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
1695 t |= VT_UNSIGNED;
1696 goto std_op;
1697 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1698 /* cast to biggest op */
1699 t = VT_LLONG;
1700 /* convert to unsigned if it does not fit in a long long */
1701 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1702 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1703 t |= VT_UNSIGNED;
1704 goto std_op;
1705 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1706 tcc_error("comparison of struct");
1707 } else {
1708 /* integer operations */
1709 t = VT_INT;
1710 /* convert to unsigned if it does not fit in an integer */
1711 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1712 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1713 t |= VT_UNSIGNED;
1714 std_op:
1715 /* XXX: currently, some unsigned operations are explicit, so
1716 we modify them here */
1717 if (t & VT_UNSIGNED) {
1718 if (op == TOK_SAR)
1719 op = TOK_SHR;
1720 else if (op == '/')
1721 op = TOK_UDIV;
1722 else if (op == '%')
1723 op = TOK_UMOD;
1724 else if (op == TOK_LT)
1725 op = TOK_ULT;
1726 else if (op == TOK_GT)
1727 op = TOK_UGT;
1728 else if (op == TOK_LE)
1729 op = TOK_ULE;
1730 else if (op == TOK_GE)
1731 op = TOK_UGE;
1732 }
1733 vswap();
1734 type1.t = t;
1735 gen_cast(&type1);
1736 vswap();
1737 /* special case for shifts and long long: we keep the shift as
1738 an integer */
1739 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1740 type1.t = VT_INT;
1741 gen_cast(&type1);
1742 if (is_float(t))
1743 gen_opif(op);
1744 else
1745 gen_opic(op);
1746 if (op >= TOK_ULT && op <= TOK_GT) {
1747 /* relationnal op: the result is an int */
1748 vtop->type.t = VT_INT;
1749 } else {
1750 vtop->type.t = t;
1751 }
1752 }
1753}
1754
1755#ifndef TCC_TARGET_ARM
1756/* generic itof for unsigned long long case */
1757static void gen_cvt_itof1(int t)
1758{
1759 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1760 (VT_LLONG | VT_UNSIGNED)) {
1761
1762 if (t == VT_FLOAT)
1763 vpush_global_sym(&func_old_type, TOK___floatundisf);
1764#if LDOUBLE_SIZE != 8
1765 else if (t == VT_LDOUBLE)
1766 vpush_global_sym(&func_old_type, TOK___floatundixf);
1767#endif
1768 else
1769 vpush_global_sym(&func_old_type, TOK___floatundidf);
1770 vrott(2);
1771 gfunc_call(1);
1772 vpushi(0);
1773 vtop->r = reg_fret(t);
1774 } else {
1775 gen_cvt_itof(t);
1776 }
1777}
1778#endif
1779
1780/* generic ftoi for unsigned long long case */
1781static void gen_cvt_ftoi1(int t)
1782{
1783 int st;
1784
1785 if (t == (VT_LLONG | VT_UNSIGNED)) {
1786 /* not handled natively */
1787 st = vtop->type.t & VT_BTYPE;
1788 if (st == VT_FLOAT)
1789 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1790#if LDOUBLE_SIZE != 8
1791 else if (st == VT_LDOUBLE)
1792 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1793#endif
1794 else
1795 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1796 vrott(2);
1797 gfunc_call(1);
1798 vpushi(0);
1799 vtop->r = REG_IRET;
1800 vtop->r2 = REG_LRET;
1801 } else {
1802 gen_cvt_ftoi(t);
1803 }
1804}
1805
1806/* force char or short cast */
1807static void force_charshort_cast(int t)
1808{
1809 int bits, dbt;
1810 dbt = t & VT_BTYPE;
1811 /* XXX: add optimization if lvalue : just change type and offset */
1812 if (dbt == VT_BYTE)
1813 bits = 8;
1814 else
1815 bits = 16;
1816 if (t & VT_UNSIGNED) {
1817 vpushi((1 << bits) - 1);
1818 gen_op('&');
1819 } else {
1820 bits = 32 - bits;
1821 vpushi(bits);
1822 gen_op(TOK_SHL);
1823 /* result must be signed or the SAR is converted to an SHL
1824 This was not the case when "t" was a signed short
1825 and the last value on the stack was an unsigned int */
1826 vtop->type.t &= ~VT_UNSIGNED;
1827 vpushi(bits);
1828 gen_op(TOK_SAR);
1829 }
1830}
1831
1832/* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1833static void gen_cast(CType *type)
1834{
1835 int sbt, dbt, sf, df, c, p;
1836
1837 /* special delayed cast for char/short */
1838 /* XXX: in some cases (multiple cascaded casts), it may still
1839 be incorrect */
1840 if (vtop->r & VT_MUSTCAST) {
1841 vtop->r &= ~VT_MUSTCAST;
1842 force_charshort_cast(vtop->type.t);
1843 }
1844
1845 /* bitfields first get cast to ints */
1846 if (vtop->type.t & VT_BITFIELD) {
1847 gv(RC_INT);
1848 }
1849
1850 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1851 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1852
1853 if (sbt != dbt) {
1854 sf = is_float(sbt);
1855 df = is_float(dbt);
1856 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1857 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1858 if (c) {
1859 /* constant case: we can do it now */
1860 /* XXX: in ISOC, cannot do it if error in convert */
1861 if (sbt == VT_FLOAT)
1862 vtop->c.ld = vtop->c.f;
1863 else if (sbt == VT_DOUBLE)
1864 vtop->c.ld = vtop->c.d;
1865
1866 if (df) {
1867 if ((sbt & VT_BTYPE) == VT_LLONG) {
1868 if (sbt & VT_UNSIGNED)
1869 vtop->c.ld = vtop->c.ull;
1870 else
1871 vtop->c.ld = vtop->c.ll;
1872 } else if(!sf) {
1873 if (sbt & VT_UNSIGNED)
1874 vtop->c.ld = vtop->c.ui;
1875 else
1876 vtop->c.ld = vtop->c.i;
1877 }
1878
1879 if (dbt == VT_FLOAT)
1880 vtop->c.f = (float)vtop->c.ld;
1881 else if (dbt == VT_DOUBLE)
1882 vtop->c.d = (double)vtop->c.ld;
1883 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1884 vtop->c.ull = (unsigned long long)vtop->c.ld;
1885 } else if (sf && dbt == VT_BOOL) {
1886 vtop->c.i = (vtop->c.ld != 0);
1887 } else {
1888 if(sf)
1889 vtop->c.ll = (long long)vtop->c.ld;
1890 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1891 vtop->c.ll = vtop->c.ull;
1892 else if (sbt & VT_UNSIGNED)
1893 vtop->c.ll = vtop->c.ui;
1894#ifdef TCC_TARGET_X86_64
1895 else if (sbt == VT_PTR)
1896 ;
1897#endif
1898 else if (sbt != VT_LLONG)
1899 vtop->c.ll = vtop->c.i;
1900
1901 if (dbt == (VT_LLONG|VT_UNSIGNED))
1902 vtop->c.ull = vtop->c.ll;
1903 else if (dbt == VT_BOOL)
1904 vtop->c.i = (vtop->c.ll != 0);
1905 else if (dbt != VT_LLONG) {
1906 int s = 0;
1907 if ((dbt & VT_BTYPE) == VT_BYTE)
1908 s = 24;
1909 else if ((dbt & VT_BTYPE) == VT_SHORT)
1910 s = 16;
1911
1912 if(dbt & VT_UNSIGNED)
1913 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1914 else
1915 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1916 }
1917 }
1918 } else if (p && dbt == VT_BOOL) {
1919 vtop->r = VT_CONST;
1920 vtop->c.i = 1;
1921 } else if (!nocode_wanted) {
1922 /* non constant case: generate code */
1923 if (sf && df) {
1924 /* convert from fp to fp */
1925 gen_cvt_ftof(dbt);
1926 } else if (df) {
1927 /* convert int to fp */
1928 gen_cvt_itof1(dbt);
1929 } else if (sf) {
1930 /* convert fp to int */
1931 if (dbt == VT_BOOL) {
1932 vpushi(0);
1933 gen_op(TOK_NE);
1934 } else {
1935 /* we handle char/short/etc... with generic code */
1936 if (dbt != (VT_INT | VT_UNSIGNED) &&
1937 dbt != (VT_LLONG | VT_UNSIGNED) &&
1938 dbt != VT_LLONG)
1939 dbt = VT_INT;
1940 gen_cvt_ftoi1(dbt);
1941 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1942 /* additional cast for char/short... */
1943 vtop->type.t = dbt;
1944 gen_cast(type);
1945 }
1946 }
1947#ifndef TCC_TARGET_X86_64
1948 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1949 if ((sbt & VT_BTYPE) != VT_LLONG) {
1950 /* scalar to long long */
1951 /* machine independent conversion */
1952 gv(RC_INT);
1953 /* generate high word */
1954 if (sbt == (VT_INT | VT_UNSIGNED)) {
1955 vpushi(0);
1956 gv(RC_INT);
1957 } else {
1958 if (sbt == VT_PTR) {
1959 /* cast from pointer to int before we apply
1960 shift operation, which pointers don't support*/
1961 gen_cast(&int_type);
1962 }
1963 gv_dup();
1964 vpushi(31);
1965 gen_op(TOK_SAR);
1966 }
1967 /* patch second register */
1968 vtop[-1].r2 = vtop->r;
1969 vpop();
1970 }
1971#else
1972 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1973 (dbt & VT_BTYPE) == VT_PTR ||
1974 (dbt & VT_BTYPE) == VT_FUNC) {
1975 if ((sbt & VT_BTYPE) != VT_LLONG &&
1976 (sbt & VT_BTYPE) != VT_PTR &&
1977 (sbt & VT_BTYPE) != VT_FUNC) {
1978 /* need to convert from 32bit to 64bit */
1979 int r = gv(RC_INT);
1980 if (sbt != (VT_INT | VT_UNSIGNED)) {
1981 /* x86_64 specific: movslq */
1982 o(0x6348);
1983 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
1984 }
1985 }
1986#endif
1987 } else if (dbt == VT_BOOL) {
1988 /* scalar to bool */
1989 vpushi(0);
1990 gen_op(TOK_NE);
1991 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
1992 (dbt & VT_BTYPE) == VT_SHORT) {
1993 if (sbt == VT_PTR) {
1994 vtop->type.t = VT_INT;
1995 tcc_warning("nonportable conversion from pointer to char/short");
1996 }
1997 force_charshort_cast(dbt);
1998 } else if ((dbt & VT_BTYPE) == VT_INT) {
1999 /* scalar to int */
2000 if (sbt == VT_LLONG) {
2001 /* from long long: just take low order word */
2002 lexpand();
2003 vpop();
2004 }
2005 /* if lvalue and single word type, nothing to do because
2006 the lvalue already contains the real type size (see
2007 VT_LVAL_xxx constants) */
2008 }
2009 }
2010 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2011 /* if we are casting between pointer types,
2012 we must update the VT_LVAL_xxx size */
2013 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2014 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2015 }
2016 vtop->type = *type;
2017}
2018
2019/* return type size as known at compile time. Put alignment at 'a' */
2020ST_FUNC int type_size(CType *type, int *a)
2021{
2022 Sym *s;
2023 int bt;
2024
2025 bt = type->t & VT_BTYPE;
2026 if (bt == VT_STRUCT) {
2027 /* struct/union */
2028 s = type->ref;
2029 *a = s->r;
2030 return s->c;
2031 } else if (bt == VT_PTR) {
2032 if (type->t & VT_ARRAY) {
2033 int ts;
2034
2035 s = type->ref;
2036 ts = type_size(&s->type, a);
2037
2038 if (ts < 0 && s->c < 0)
2039 ts = -ts;
2040
2041 return ts * s->c;
2042 } else {
2043 *a = PTR_SIZE;
2044 return PTR_SIZE;
2045 }
2046 } else if (bt == VT_LDOUBLE) {
2047 *a = LDOUBLE_ALIGN;
2048 return LDOUBLE_SIZE;
2049 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2050#ifdef TCC_TARGET_I386
2051#ifdef TCC_TARGET_PE
2052 *a = 8;
2053#else
2054 *a = 4;
2055#endif
2056#elif defined(TCC_TARGET_ARM)
2057#ifdef TCC_ARM_EABI
2058 *a = 8;
2059#else
2060 *a = 4;
2061#endif
2062#else
2063 *a = 8;
2064#endif
2065 return 8;
2066 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2067 *a = 4;
2068 return 4;
2069 } else if (bt == VT_SHORT) {
2070 *a = 2;
2071 return 2;
2072 } else {
2073 /* char, void, function, _Bool */
2074 *a = 1;
2075 return 1;
2076 }
2077}
2078
2079/* push type size as known at runtime time on top of value stack. Put
2080 alignment at 'a' */
2081ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2082{
2083 if (type->t & VT_VLA) {
2084 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2085 } else {
2086 vpushi(type_size(type, a));
2087 }
2088}
2089
2090/* return the pointed type of t */
2091static inline CType *pointed_type(CType *type)
2092{
2093 return &type->ref->type;
2094}
2095
2096/* modify type so that its it is a pointer to type. */
2097ST_FUNC void mk_pointer(CType *type)
2098{
2099 Sym *s;
2100 s = sym_push(SYM_FIELD, type, 0, -1);
2101 type->t = VT_PTR | (type->t & ~VT_TYPE);
2102 type->ref = s;
2103}
2104
2105/* compare function types. OLD functions match any new functions */
2106static int is_compatible_func(CType *type1, CType *type2)
2107{
2108 Sym *s1, *s2;
2109
2110 s1 = type1->ref;
2111 s2 = type2->ref;
2112 if (!is_compatible_types(&s1->type, &s2->type))
2113 return 0;
2114 /* check func_call */
2115 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2116 return 0;
2117 /* XXX: not complete */
2118 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2119 return 1;
2120 if (s1->c != s2->c)
2121 return 0;
2122 while (s1 != NULL) {
2123 if (s2 == NULL)
2124 return 0;
2125 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2126 return 0;
2127 s1 = s1->next;
2128 s2 = s2->next;
2129 }
2130 if (s2)
2131 return 0;
2132 return 1;
2133}
2134
2135/* return true if type1 and type2 are the same. If unqualified is
2136 true, qualifiers on the types are ignored.
2137
2138 - enums are not checked as gcc __builtin_types_compatible_p ()
2139 */
2140static int compare_types(CType *type1, CType *type2, int unqualified)
2141{
2142 int bt1, t1, t2;
2143
2144 t1 = type1->t & VT_TYPE;
2145 t2 = type2->t & VT_TYPE;
2146 if (unqualified) {
2147 /* strip qualifiers before comparing */
2148 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2149 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2150 }
2151 /* XXX: bitfields ? */
2152 if (t1 != t2)
2153 return 0;
2154 /* test more complicated cases */
2155 bt1 = t1 & VT_BTYPE;
2156 if (bt1 == VT_PTR) {
2157 type1 = pointed_type(type1);
2158 type2 = pointed_type(type2);
2159 return is_compatible_types(type1, type2);
2160 } else if (bt1 == VT_STRUCT) {
2161 return (type1->ref == type2->ref);
2162 } else if (bt1 == VT_FUNC) {
2163 return is_compatible_func(type1, type2);
2164 } else {
2165 return 1;
2166 }
2167}
2168
2169/* return true if type1 and type2 are exactly the same (including
2170 qualifiers).
2171*/
2172static int is_compatible_types(CType *type1, CType *type2)
2173{
2174 return compare_types(type1,type2,0);
2175}
2176
2177/* return true if type1 and type2 are the same (ignoring qualifiers).
2178*/
2179static int is_compatible_parameter_types(CType *type1, CType *type2)
2180{
2181 return compare_types(type1,type2,1);
2182}
2183
2184/* print a type. If 'varstr' is not NULL, then the variable is also
2185 printed in the type */
2186/* XXX: union */
2187/* XXX: add array and function pointers */
2188static void type_to_str(char *buf, int buf_size,
2189 CType *type, const char *varstr)
2190{
2191 int bt, v, t;
2192 Sym *s, *sa;
2193 char buf1[256];
2194 const char *tstr;
2195
2196 t = type->t & VT_TYPE;
2197 bt = t & VT_BTYPE;
2198 buf[0] = '\0';
2199 if (t & VT_CONSTANT)
2200 pstrcat(buf, buf_size, "const ");
2201 if (t & VT_VOLATILE)
2202 pstrcat(buf, buf_size, "volatile ");
2203 if (t & VT_UNSIGNED)
2204 pstrcat(buf, buf_size, "unsigned ");
2205 switch(bt) {
2206 case VT_VOID:
2207 tstr = "void";
2208 goto add_tstr;
2209 case VT_BOOL:
2210 tstr = "_Bool";
2211 goto add_tstr;
2212 case VT_BYTE:
2213 tstr = "char";
2214 goto add_tstr;
2215 case VT_SHORT:
2216 tstr = "short";
2217 goto add_tstr;
2218 case VT_INT:
2219 tstr = "int";
2220 goto add_tstr;
2221 case VT_LONG:
2222 tstr = "long";
2223 goto add_tstr;
2224 case VT_LLONG:
2225 tstr = "long long";
2226 goto add_tstr;
2227 case VT_FLOAT:
2228 tstr = "float";
2229 goto add_tstr;
2230 case VT_DOUBLE:
2231 tstr = "double";
2232 goto add_tstr;
2233 case VT_LDOUBLE:
2234 tstr = "long double";
2235 add_tstr:
2236 pstrcat(buf, buf_size, tstr);
2237 break;
2238 case VT_ENUM:
2239 case VT_STRUCT:
2240 if (bt == VT_STRUCT)
2241 tstr = "struct ";
2242 else
2243 tstr = "enum ";
2244 pstrcat(buf, buf_size, tstr);
2245 v = type->ref->v & ~SYM_STRUCT;
2246 if (v >= SYM_FIRST_ANOM)
2247 pstrcat(buf, buf_size, "<anonymous>");
2248 else
2249 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2250 break;
2251 case VT_FUNC:
2252 s = type->ref;
2253 type_to_str(buf, buf_size, &s->type, varstr);
2254 pstrcat(buf, buf_size, "(");
2255 sa = s->next;
2256 while (sa != NULL) {
2257 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2258 pstrcat(buf, buf_size, buf1);
2259 sa = sa->next;
2260 if (sa)
2261 pstrcat(buf, buf_size, ", ");
2262 }
2263 pstrcat(buf, buf_size, ")");
2264 goto no_var;
2265 case VT_PTR:
2266 s = type->ref;
2267 pstrcpy(buf1, sizeof(buf1), "*");
2268 if (varstr)
2269 pstrcat(buf1, sizeof(buf1), varstr);
2270 type_to_str(buf, buf_size, &s->type, buf1);
2271 goto no_var;
2272 }
2273 if (varstr) {
2274 pstrcat(buf, buf_size, " ");
2275 pstrcat(buf, buf_size, varstr);
2276 }
2277 no_var: ;
2278}
2279
2280/* verify type compatibility to store vtop in 'dt' type, and generate
2281 casts if needed. */
2282static void gen_assign_cast(CType *dt)
2283{
2284 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2285 char buf1[256], buf2[256];
2286 int dbt, sbt;
2287
2288 st = &vtop->type; /* source type */
2289 dbt = dt->t & VT_BTYPE;
2290 sbt = st->t & VT_BTYPE;
2291 if (sbt == VT_VOID)
2292 tcc_error("Cannot assign void value");
2293 if (dt->t & VT_CONSTANT)
2294 tcc_warning("assignment of read-only location");
2295 switch(dbt) {
2296 case VT_PTR:
2297 /* special cases for pointers */
2298 /* '0' can also be a pointer */
2299 if (is_null_pointer(vtop))
2300 goto type_ok;
2301 /* accept implicit pointer to integer cast with warning */
2302 if (is_integer_btype(sbt)) {
2303 tcc_warning("assignment makes pointer from integer without a cast");
2304 goto type_ok;
2305 }
2306 type1 = pointed_type(dt);
2307 /* a function is implicitely a function pointer */
2308 if (sbt == VT_FUNC) {
2309 if ((type1->t & VT_BTYPE) != VT_VOID &&
2310 !is_compatible_types(pointed_type(dt), st))
2311 tcc_warning("assignment from incompatible pointer type");
2312 goto type_ok;
2313 }
2314 if (sbt != VT_PTR)
2315 goto error;
2316 type2 = pointed_type(st);
2317 if ((type1->t & VT_BTYPE) == VT_VOID ||
2318 (type2->t & VT_BTYPE) == VT_VOID) {
2319 /* void * can match anything */
2320 } else {
2321 /* exact type match, except for unsigned */
2322 tmp_type1 = *type1;
2323 tmp_type2 = *type2;
2324 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2325 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2326 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2327 tcc_warning("assignment from incompatible pointer type");
2328 }
2329 /* check const and volatile */
2330 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2331 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2332 tcc_warning("assignment discards qualifiers from pointer target type");
2333 break;
2334 case VT_BYTE:
2335 case VT_SHORT:
2336 case VT_INT:
2337 case VT_LLONG:
2338 if (sbt == VT_PTR || sbt == VT_FUNC) {
2339 tcc_warning("assignment makes integer from pointer without a cast");
2340 }
2341 /* XXX: more tests */
2342 break;
2343 case VT_STRUCT:
2344 tmp_type1 = *dt;
2345 tmp_type2 = *st;
2346 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2347 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2348 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2349 error:
2350 type_to_str(buf1, sizeof(buf1), st, NULL);
2351 type_to_str(buf2, sizeof(buf2), dt, NULL);
2352 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2353 }
2354 break;
2355 }
2356 type_ok:
2357 gen_cast(dt);
2358}
2359
2360/* store vtop in lvalue pushed on stack */
2361ST_FUNC void vstore(void)
2362{
2363 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2364
2365 ft = vtop[-1].type.t;
2366 sbt = vtop->type.t & VT_BTYPE;
2367 dbt = ft & VT_BTYPE;
2368 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2369 (sbt == VT_INT && dbt == VT_SHORT))
2370 && !(vtop->type.t & VT_BITFIELD)) {
2371 /* optimize char/short casts */
2372 delayed_cast = VT_MUSTCAST;
2373 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2374 /* XXX: factorize */
2375 if (ft & VT_CONSTANT)
2376 tcc_warning("assignment of read-only location");
2377 } else {
2378 delayed_cast = 0;
2379 if (!(ft & VT_BITFIELD))
2380 gen_assign_cast(&vtop[-1].type);
2381 }
2382
2383 if (sbt == VT_STRUCT) {
2384 /* if structure, only generate pointer */
2385 /* structure assignment : generate memcpy */
2386 /* XXX: optimize if small size */
2387 if (!nocode_wanted) {
2388 size = type_size(&vtop->type, &align);
2389
2390 /* destination */
2391 vswap();
2392 vtop->type.t = VT_PTR;
2393 gaddrof();
2394
2395 /* address of memcpy() */
2396#ifdef TCC_ARM_EABI
2397 if(!(align & 7))
2398 vpush_global_sym(&func_old_type, TOK_memcpy8);
2399 else if(!(align & 3))
2400 vpush_global_sym(&func_old_type, TOK_memcpy4);
2401 else
2402#endif
2403 vpush_global_sym(&func_old_type, TOK_memcpy);
2404
2405 vswap();
2406 /* source */
2407 vpushv(vtop - 2);
2408 vtop->type.t = VT_PTR;
2409 gaddrof();
2410 /* type size */
2411 vpushi(size);
2412 gfunc_call(3);
2413 } else {
2414 vswap();
2415 vpop();
2416 }
2417 /* leave source on stack */
2418 } else if (ft & VT_BITFIELD) {
2419 /* bitfield store handling */
2420 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2421 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2422 /* remove bit field info to avoid loops */
2423 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2424
2425 /* duplicate source into other register */
2426 gv_dup();
2427 vswap();
2428 vrott(3);
2429
2430 if((ft & VT_BTYPE) == VT_BOOL) {
2431 gen_cast(&vtop[-1].type);
2432 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2433 }
2434
2435 /* duplicate destination */
2436 vdup();
2437 vtop[-1] = vtop[-2];
2438
2439 /* mask and shift source */
2440 if((ft & VT_BTYPE) != VT_BOOL) {
2441 if((ft & VT_BTYPE) == VT_LLONG) {
2442 vpushll((1ULL << bit_size) - 1ULL);
2443 } else {
2444 vpushi((1 << bit_size) - 1);
2445 }
2446 gen_op('&');
2447 }
2448 vpushi(bit_pos);
2449 gen_op(TOK_SHL);
2450 /* load destination, mask and or with source */
2451 vswap();
2452 if((ft & VT_BTYPE) == VT_LLONG) {
2453 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2454 } else {
2455 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2456 }
2457 gen_op('&');
2458 gen_op('|');
2459 /* store result */
2460 vstore();
2461
2462 /* pop off shifted source from "duplicate source..." above */
2463 vpop();
2464
2465 } else {
2466#ifdef CONFIG_TCC_BCHECK
2467 /* bound check case */
2468 if (vtop[-1].r & VT_MUSTBOUND) {
2469 vswap();
2470 gbound();
2471 vswap();
2472 }
2473#endif
2474 if (!nocode_wanted) {
2475 rc = RC_INT;
2476 if (is_float(ft)) {
2477 rc = RC_FLOAT;
2478#ifdef TCC_TARGET_X86_64
2479 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2480 rc = RC_ST0;
2481 }
2482#endif
2483 }
2484 r = gv(rc); /* generate value */
2485 /* if lvalue was saved on stack, must read it */
2486 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2487 SValue sv;
2488 t = get_reg(RC_INT);
2489#ifdef TCC_TARGET_X86_64
2490 sv.type.t = VT_PTR;
2491#else
2492 sv.type.t = VT_INT;
2493#endif
2494 sv.r = VT_LOCAL | VT_LVAL;
2495 sv.c.ul = vtop[-1].c.ul;
2496 load(t, &sv);
2497 vtop[-1].r = t | VT_LVAL;
2498 }
2499 store(r, vtop - 1);
2500#ifndef TCC_TARGET_X86_64
2501 /* two word case handling : store second register at word + 4 */
2502 if ((ft & VT_BTYPE) == VT_LLONG) {
2503 vswap();
2504 /* convert to int to increment easily */
2505 vtop->type.t = VT_INT;
2506 gaddrof();
2507 vpushi(4);
2508 gen_op('+');
2509 vtop->r |= VT_LVAL;
2510 vswap();
2511 /* XXX: it works because r2 is spilled last ! */
2512 store(vtop->r2, vtop - 1);
2513 }
2514#endif
2515 }
2516 vswap();
2517 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2518 vtop->r |= delayed_cast;
2519 }
2520}
2521
2522/* post defines POST/PRE add. c is the token ++ or -- */
2523ST_FUNC void inc(int post, int c)
2524{
2525 test_lvalue();
2526 vdup(); /* save lvalue */
2527 if (post) {
2528 gv_dup(); /* duplicate value */
2529 vrotb(3);
2530 vrotb(3);
2531 }
2532 /* add constant */
2533 vpushi(c - TOK_MID);
2534 gen_op('+');
2535 vstore(); /* store value */
2536 if (post)
2537 vpop(); /* if post op, return saved value */
2538}
2539
2540/* Parse GNUC __attribute__ extension. Currently, the following
2541 extensions are recognized:
2542 - aligned(n) : set data/function alignment.
2543 - packed : force data alignment to 1
2544 - section(x) : generate data/code in this section.
2545 - unused : currently ignored, but may be used someday.
2546 - regparm(n) : pass function parameters in registers (i386 only)
2547 */
2548static void parse_attribute(AttributeDef *ad)
2549{
2550 int t, n;
2551
2552 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2553 next();
2554 skip('(');
2555 skip('(');
2556 while (tok != ')') {
2557 if (tok < TOK_IDENT)
2558 expect("attribute name");
2559 t = tok;
2560 next();
2561 switch(t) {
2562 case TOK_SECTION1:
2563 case TOK_SECTION2:
2564 skip('(');
2565 if (tok != TOK_STR)
2566 expect("section name");
2567 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2568 next();
2569 skip(')');
2570 break;
2571 case TOK_ALIAS1:
2572 case TOK_ALIAS2:
2573 skip('(');
2574 if (tok != TOK_STR)
2575 expect("alias(\"target\")");
2576 ad->alias_target = /* save string as token, for later */
2577 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2578 next();
2579 skip(')');
2580 break;
2581 case TOK_ALIGNED1:
2582 case TOK_ALIGNED2:
2583 if (tok == '(') {
2584 next();
2585 n = expr_const();
2586 if (n <= 0 || (n & (n - 1)) != 0)
2587 tcc_error("alignment must be a positive power of two");
2588 skip(')');
2589 } else {
2590 n = MAX_ALIGN;
2591 }
2592 ad->aligned = n;
2593 break;
2594 case TOK_PACKED1:
2595 case TOK_PACKED2:
2596 ad->packed = 1;
2597 break;
2598 case TOK_WEAK1:
2599 case TOK_WEAK2:
2600 ad->weak = 1;
2601 break;
2602 case TOK_UNUSED1:
2603 case TOK_UNUSED2:
2604 /* currently, no need to handle it because tcc does not
2605 track unused objects */
2606 break;
2607 case TOK_NORETURN1:
2608 case TOK_NORETURN2:
2609 /* currently, no need to handle it because tcc does not
2610 track unused objects */
2611 break;
2612 case TOK_CDECL1:
2613 case TOK_CDECL2:
2614 case TOK_CDECL3:
2615 ad->func_call = FUNC_CDECL;
2616 break;
2617 case TOK_STDCALL1:
2618 case TOK_STDCALL2:
2619 case TOK_STDCALL3:
2620 ad->func_call = FUNC_STDCALL;
2621 break;
2622#ifdef TCC_TARGET_I386
2623 case TOK_REGPARM1:
2624 case TOK_REGPARM2:
2625 skip('(');
2626 n = expr_const();
2627 if (n > 3)
2628 n = 3;
2629 else if (n < 0)
2630 n = 0;
2631 if (n > 0)
2632 ad->func_call = FUNC_FASTCALL1 + n - 1;
2633 skip(')');
2634 break;
2635 case TOK_FASTCALL1:
2636 case TOK_FASTCALL2:
2637 case TOK_FASTCALL3:
2638 ad->func_call = FUNC_FASTCALLW;
2639 break;
2640#endif
2641 case TOK_MODE:
2642 skip('(');
2643 switch(tok) {
2644 case TOK_MODE_DI:
2645 ad->mode = VT_LLONG + 1;
2646 break;
2647 case TOK_MODE_HI:
2648 ad->mode = VT_SHORT + 1;
2649 break;
2650 case TOK_MODE_SI:
2651 ad->mode = VT_INT + 1;
2652 break;
2653 default:
2654 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2655 break;
2656 }
2657 next();
2658 skip(')');
2659 break;
2660 case TOK_DLLEXPORT:
2661 ad->func_export = 1;
2662 break;
2663 case TOK_DLLIMPORT:
2664 ad->func_import = 1;
2665 break;
2666 default:
2667 if (tcc_state->warn_unsupported)
2668 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2669 /* skip parameters */
2670 if (tok == '(') {
2671 int parenthesis = 0;
2672 do {
2673 if (tok == '(')
2674 parenthesis++;
2675 else if (tok == ')')
2676 parenthesis--;
2677 next();
2678 } while (parenthesis && tok != -1);
2679 }
2680 break;
2681 }
2682 if (tok != ',')
2683 break;
2684 next();
2685 }
2686 skip(')');
2687 skip(')');
2688 }
2689}
2690
2691/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2692static void struct_decl(CType *type, int u)
2693{
2694 int a, v, size, align, maxalign, c, offset;
2695 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2696 Sym *s, *ss, *ass, **ps;
2697 AttributeDef ad;
2698 CType type1, btype;
2699
2700 a = tok; /* save decl type */
2701 next();
2702 if (tok != '{') {
2703 v = tok;
2704 next();
2705 /* struct already defined ? return it */
2706 if (v < TOK_IDENT)
2707 expect("struct/union/enum name");
2708 s = struct_find(v);
2709 if (s) {
2710 if (s->type.t != a)
2711 tcc_error("invalid type");
2712 goto do_decl;
2713 }
2714 } else {
2715 v = anon_sym++;
2716 }
2717 type1.t = a;
2718 /* we put an undefined size for struct/union */
2719 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2720 s->r = 0; /* default alignment is zero as gcc */
2721 /* put struct/union/enum name in type */
2722 do_decl:
2723 type->t = u;
2724 type->ref = s;
2725
2726 if (tok == '{') {
2727 next();
2728 if (s->c != -1)
2729 tcc_error("struct/union/enum already defined");
2730 /* cannot be empty */
2731 c = 0;
2732 /* non empty enums are not allowed */
2733 if (a == TOK_ENUM) {
2734 for(;;) {
2735 v = tok;
2736 if (v < TOK_UIDENT)
2737 expect("identifier");
2738 next();
2739 if (tok == '=') {
2740 next();
2741 c = expr_const();
2742 }
2743 /* enum symbols have static storage */
2744 ss = sym_push(v, &int_type, VT_CONST, c);
2745 ss->type.t |= VT_STATIC;
2746 if (tok != ',')
2747 break;
2748 next();
2749 c++;
2750 /* NOTE: we accept a trailing comma */
2751 if (tok == '}')
2752 break;
2753 }
2754 skip('}');
2755 } else {
2756 maxalign = 1;
2757 ps = &s->next;
2758 prevbt = VT_INT;
2759 bit_pos = 0;
2760 offset = 0;
2761 while (tok != '}') {
2762 parse_btype(&btype, &ad);
2763 while (1) {
2764 bit_size = -1;
2765 v = 0;
2766 type1 = btype;
2767 if (tok != ':') {
2768 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2769 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2770 expect("identifier");
2771 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2772 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2773 tcc_error("invalid type for '%s'",
2774 get_tok_str(v, NULL));
2775 }
2776 if (tok == ':') {
2777 next();
2778 bit_size = expr_const();
2779 /* XXX: handle v = 0 case for messages */
2780 if (bit_size < 0)
2781 tcc_error("negative width in bit-field '%s'",
2782 get_tok_str(v, NULL));
2783 if (v && bit_size == 0)
2784 tcc_error("zero width for bit-field '%s'",
2785 get_tok_str(v, NULL));
2786 }
2787 size = type_size(&type1, &align);
2788 if (ad.aligned) {
2789 if (align < ad.aligned)
2790 align = ad.aligned;
2791 } else if (ad.packed) {
2792 align = 1;
2793 } else if (*tcc_state->pack_stack_ptr) {
2794 if (align > *tcc_state->pack_stack_ptr)
2795 align = *tcc_state->pack_stack_ptr;
2796 }
2797 lbit_pos = 0;
2798 if (bit_size >= 0) {
2799 bt = type1.t & VT_BTYPE;
2800 if (bt != VT_INT &&
2801 bt != VT_BYTE &&
2802 bt != VT_SHORT &&
2803 bt != VT_BOOL &&
2804 bt != VT_ENUM &&
2805 bt != VT_LLONG)
2806 tcc_error("bitfields must have scalar type");
2807 bsize = size * 8;
2808 if (bit_size > bsize) {
2809 tcc_error("width of '%s' exceeds its type",
2810 get_tok_str(v, NULL));
2811 } else if (bit_size == bsize) {
2812 /* no need for bit fields */
2813 bit_pos = 0;
2814 } else if (bit_size == 0) {
2815 /* XXX: what to do if only padding in a
2816 structure ? */
2817 /* zero size: means to pad */
2818 bit_pos = 0;
2819 } else {
2820 /* we do not have enough room ?
2821 did the type change?
2822 is it a union? */
2823 if ((bit_pos + bit_size) > bsize ||
2824 bt != prevbt || a == TOK_UNION)
2825 bit_pos = 0;
2826 lbit_pos = bit_pos;
2827 /* XXX: handle LSB first */
2828 type1.t |= VT_BITFIELD |
2829 (bit_pos << VT_STRUCT_SHIFT) |
2830 (bit_size << (VT_STRUCT_SHIFT + 6));
2831 bit_pos += bit_size;
2832 }
2833 prevbt = bt;
2834 } else {
2835 bit_pos = 0;
2836 }
2837 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2838 /* add new memory data only if starting
2839 bit field */
2840 if (lbit_pos == 0) {
2841 if (a == TOK_STRUCT) {
2842 c = (c + align - 1) & -align;
2843 offset = c;
2844 if (size > 0)
2845 c += size;
2846 } else {
2847 offset = 0;
2848 if (size > c)
2849 c = size;
2850 }
2851 if (align > maxalign)
2852 maxalign = align;
2853 }
2854#if 0
2855 printf("add field %s offset=%d",
2856 get_tok_str(v, NULL), offset);
2857 if (type1.t & VT_BITFIELD) {
2858 printf(" pos=%d size=%d",
2859 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2860 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2861 }
2862 printf("\n");
2863#endif
2864 }
2865 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2866 ass = type1.ref;
2867 while ((ass = ass->next) != NULL) {
2868 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2869 *ps = ss;
2870 ps = &ss->next;
2871 }
2872 } else if (v) {
2873 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2874 *ps = ss;
2875 ps = &ss->next;
2876 }
2877 if (tok == ';' || tok == TOK_EOF)
2878 break;
2879 skip(',');
2880 }
2881 skip(';');
2882 }
2883 skip('}');
2884 /* store size and alignment */
2885 s->c = (c + maxalign - 1) & -maxalign;
2886 s->r = maxalign;
2887 }
2888 }
2889}
2890
2891/* return 0 if no type declaration. otherwise, return the basic type
2892 and skip it.
2893 */
2894static int parse_btype(CType *type, AttributeDef *ad)
2895{
2896 int t, u, type_found, typespec_found, typedef_found;
2897 Sym *s;
2898 CType type1;
2899
2900 memset(ad, 0, sizeof(AttributeDef));
2901 type_found = 0;
2902 typespec_found = 0;
2903 typedef_found = 0;
2904 t = 0;
2905 while(1) {
2906 switch(tok) {
2907 case TOK_EXTENSION:
2908 /* currently, we really ignore extension */
2909 next();
2910 continue;
2911
2912 /* basic types */
2913 case TOK_CHAR:
2914 u = VT_BYTE;
2915 basic_type:
2916 next();
2917 basic_type1:
2918 if ((t & VT_BTYPE) != 0)
2919 tcc_error("too many basic types");
2920 t |= u;
2921 typespec_found = 1;
2922 break;
2923 case TOK_VOID:
2924 u = VT_VOID;
2925 goto basic_type;
2926 case TOK_SHORT:
2927 u = VT_SHORT;
2928 goto basic_type;
2929 case TOK_INT:
2930 next();
2931 typespec_found = 1;
2932 break;
2933 case TOK_LONG:
2934 next();
2935 if ((t & VT_BTYPE) == VT_DOUBLE) {
2936#ifndef TCC_TARGET_PE
2937 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2938#endif
2939 } else if ((t & VT_BTYPE) == VT_LONG) {
2940 t = (t & ~VT_BTYPE) | VT_LLONG;
2941 } else {
2942 u = VT_LONG;
2943 goto basic_type1;
2944 }
2945 break;
2946 case TOK_BOOL:
2947 u = VT_BOOL;
2948 goto basic_type;
2949 case TOK_FLOAT:
2950 u = VT_FLOAT;
2951 goto basic_type;
2952 case TOK_DOUBLE:
2953 next();
2954 if ((t & VT_BTYPE) == VT_LONG) {
2955#ifdef TCC_TARGET_PE
2956 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2957#else
2958 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2959#endif
2960 } else {
2961 u = VT_DOUBLE;
2962 goto basic_type1;
2963 }
2964 break;
2965 case TOK_ENUM:
2966 struct_decl(&type1, VT_ENUM);
2967 basic_type2:
2968 u = type1.t;
2969 type->ref = type1.ref;
2970 goto basic_type1;
2971 case TOK_STRUCT:
2972 case TOK_UNION:
2973 struct_decl(&type1, VT_STRUCT);
2974 goto basic_type2;
2975
2976 /* type modifiers */
2977 case TOK_CONST1:
2978 case TOK_CONST2:
2979 case TOK_CONST3:
2980 t |= VT_CONSTANT;
2981 next();
2982 break;
2983 case TOK_VOLATILE1:
2984 case TOK_VOLATILE2:
2985 case TOK_VOLATILE3:
2986 t |= VT_VOLATILE;
2987 next();
2988 break;
2989 case TOK_SIGNED1:
2990 case TOK_SIGNED2:
2991 case TOK_SIGNED3:
2992 typespec_found = 1;
2993 t |= VT_SIGNED;
2994 next();
2995 break;
2996 case TOK_REGISTER:
2997 case TOK_AUTO:
2998 case TOK_RESTRICT1:
2999 case TOK_RESTRICT2:
3000 case TOK_RESTRICT3:
3001 next();
3002 break;
3003 case TOK_UNSIGNED:
3004 t |= VT_UNSIGNED;
3005 next();
3006 typespec_found = 1;
3007 break;
3008
3009 /* storage */
3010 case TOK_EXTERN:
3011 t |= VT_EXTERN;
3012 next();
3013 break;
3014 case TOK_STATIC:
3015 t |= VT_STATIC;
3016 next();
3017 break;
3018 case TOK_TYPEDEF:
3019 t |= VT_TYPEDEF;
3020 next();
3021 break;
3022 case TOK_INLINE1:
3023 case TOK_INLINE2:
3024 case TOK_INLINE3:
3025 t |= VT_INLINE;
3026 next();
3027 break;
3028
3029 /* GNUC attribute */
3030 case TOK_ATTRIBUTE1:
3031 case TOK_ATTRIBUTE2:
3032 parse_attribute(ad);
3033 if (ad->mode) {
3034 u = ad->mode -1;
3035 t = (t & ~VT_BTYPE) | u;
3036 }
3037 break;
3038 /* GNUC typeof */
3039 case TOK_TYPEOF1:
3040 case TOK_TYPEOF2:
3041 case TOK_TYPEOF3:
3042 next();
3043 parse_expr_type(&type1);
3044 /* remove all storage modifiers except typedef */
3045 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3046 goto basic_type2;
3047 default:
3048 if (typespec_found || typedef_found)
3049 goto the_end;
3050 s = sym_find(tok);
3051 if (!s || !(s->type.t & VT_TYPEDEF))
3052 goto the_end;
3053 typedef_found = 1;
3054 t |= (s->type.t & ~VT_TYPEDEF);
3055 type->ref = s->type.ref;
3056 if (s->r) {
3057 /* get attributes from typedef */
3058 if (0 == ad->aligned)
3059 ad->aligned = FUNC_ALIGN(s->r);
3060 if (0 == ad->func_call)
3061 ad->func_call = FUNC_CALL(s->r);
3062 ad->packed |= FUNC_PACKED(s->r);
3063 }
3064 next();
3065 typespec_found = 1;
3066 break;
3067 }
3068 type_found = 1;
3069 }
3070the_end:
3071 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
3072 tcc_error("signed and unsigned modifier");
3073 if (tcc_state->char_is_unsigned) {
3074 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
3075 t |= VT_UNSIGNED;
3076 }
3077 t &= ~VT_SIGNED;
3078
3079 /* long is never used as type */
3080 if ((t & VT_BTYPE) == VT_LONG)
3081#if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3082 t = (t & ~VT_BTYPE) | VT_INT;
3083#else
3084 t = (t & ~VT_BTYPE) | VT_LLONG;
3085#endif
3086 type->t = t;
3087 return type_found;
3088}
3089
3090/* convert a function parameter type (array to pointer and function to
3091 function pointer) */
3092static inline void convert_parameter_type(CType *pt)
3093{
3094 /* remove const and volatile qualifiers (XXX: const could be used
3095 to indicate a const function parameter */
3096 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3097 /* array must be transformed to pointer according to ANSI C */
3098 pt->t &= ~VT_ARRAY;
3099 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3100 mk_pointer(pt);
3101 }
3102}
3103
3104ST_FUNC void parse_asm_str(CString *astr)
3105{
3106 skip('(');
3107 /* read the string */
3108 if (tok != TOK_STR)
3109 expect("string constant");
3110 cstr_new(astr);
3111 while (tok == TOK_STR) {
3112 /* XXX: add \0 handling too ? */
3113 cstr_cat(astr, tokc.cstr->data);
3114 next();
3115 }
3116 cstr_ccat(astr, '\0');
3117}
3118
3119/* Parse an asm label and return the label
3120 * Don't forget to free the CString in the caller! */
3121static void asm_label_instr(CString *astr)
3122{
3123 next();
3124 parse_asm_str(astr);
3125 skip(')');
3126#ifdef ASM_DEBUG
3127 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3128#endif
3129}
3130
3131static void post_type(CType *type, AttributeDef *ad)
3132{
3133 int n, l, t1, arg_size, align;
3134 Sym **plast, *s, *first;
3135 AttributeDef ad1;
3136 CType pt;
3137
3138 if (tok == '(') {
3139 /* function declaration */
3140 next();
3141 l = 0;
3142 first = NULL;
3143 plast = &first;
3144 arg_size = 0;
3145 if (tok != ')') {
3146 for(;;) {
3147 /* read param name and compute offset */
3148 if (l != FUNC_OLD) {
3149 if (!parse_btype(&pt, &ad1)) {
3150 if (l) {
3151 tcc_error("invalid type");
3152 } else {
3153 l = FUNC_OLD;
3154 goto old_proto;
3155 }
3156 }
3157 l = FUNC_NEW;
3158 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3159 break;
3160 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3161 if ((pt.t & VT_BTYPE) == VT_VOID)
3162 tcc_error("parameter declared as void");
3163 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3164 } else {
3165 old_proto:
3166 n = tok;
3167 if (n < TOK_UIDENT)
3168 expect("identifier");
3169 pt.t = VT_INT;
3170 next();
3171 }
3172 convert_parameter_type(&pt);
3173 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3174 *plast = s;
3175 plast = &s->next;
3176 if (tok == ')')
3177 break;
3178 skip(',');
3179 if (l == FUNC_NEW && tok == TOK_DOTS) {
3180 l = FUNC_ELLIPSIS;
3181 next();
3182 break;
3183 }
3184 }
3185 }
3186 /* if no parameters, then old type prototype */
3187 if (l == 0)
3188 l = FUNC_OLD;
3189 skip(')');
3190 /* NOTE: const is ignored in returned type as it has a special
3191 meaning in gcc / C++ */
3192 type->t &= ~VT_CONSTANT;
3193 /* some ancient pre-K&R C allows a function to return an array
3194 and the array brackets to be put after the arguments, such
3195 that "int c()[]" means something like "int[] c()" */
3196 if (tok == '[') {
3197 next();
3198 skip(']'); /* only handle simple "[]" */
3199 type->t |= VT_PTR;
3200 }
3201 /* we push a anonymous symbol which will contain the function prototype */
3202 ad->func_args = arg_size;
3203 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3204 s->next = first;
3205 type->t = VT_FUNC;
3206 type->ref = s;
3207 } else if (tok == '[') {
3208 /* array definition */
3209 next();
3210 if (tok == TOK_RESTRICT1)
3211 next();
3212 n = -1;
3213 t1 = 0;
3214 if (tok != ']') {
3215 if (!local_stack || nocode_wanted)
3216 vpushi(expr_const());
3217 else gexpr();
3218 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3219 n = vtop->c.i;
3220 if (n < 0)
3221 tcc_error("invalid array size");
3222 } else {
3223 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3224 tcc_error("size of variable length array should be an integer");
3225 t1 = VT_VLA;
3226 }
3227 }
3228 skip(']');
3229 /* parse next post type */
3230 post_type(type, ad);
3231 t1 |= type->t & VT_VLA;
3232
3233 if (t1 & VT_VLA) {
3234 loc -= type_size(&int_type, &align);
3235 loc &= -align;
3236 n = loc;
3237
3238 vla_runtime_type_size(type, &align);
3239 gen_op('*');
3240 vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3241 vswap();
3242 vstore();
3243 }
3244 if (n != -1)
3245 vpop();
3246
3247 /* we push an anonymous symbol which will contain the array
3248 element type */
3249 s = sym_push(SYM_FIELD, type, 0, n);
3250 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3251 type->ref = s;
3252 }
3253}
3254
3255/* Parse a type declaration (except basic type), and return the type
3256 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3257 expected. 'type' should contain the basic type. 'ad' is the
3258 attribute definition of the basic type. It can be modified by
3259 type_decl().
3260 */
3261static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3262{
3263 Sym *s;
3264 CType type1, *type2;
3265 int qualifiers, storage;
3266
3267 while (tok == '*') {
3268 qualifiers = 0;
3269 redo:
3270 next();
3271 switch(tok) {
3272 case TOK_CONST1:
3273 case TOK_CONST2:
3274 case TOK_CONST3:
3275 qualifiers |= VT_CONSTANT;
3276 goto redo;
3277 case TOK_VOLATILE1:
3278 case TOK_VOLATILE2:
3279 case TOK_VOLATILE3:
3280 qualifiers |= VT_VOLATILE;
3281 goto redo;
3282 case TOK_RESTRICT1:
3283 case TOK_RESTRICT2:
3284 case TOK_RESTRICT3:
3285 goto redo;
3286 }
3287 mk_pointer(type);
3288 type->t |= qualifiers;
3289 }
3290
3291 /* XXX: clarify attribute handling */
3292 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3293 parse_attribute(ad);
3294
3295 /* recursive type */
3296 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3297 type1.t = 0; /* XXX: same as int */
3298 if (tok == '(') {
3299 next();
3300 /* XXX: this is not correct to modify 'ad' at this point, but
3301 the syntax is not clear */
3302 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3303 parse_attribute(ad);
3304 type_decl(&type1, ad, v, td);
3305 skip(')');
3306 } else {
3307 /* type identifier */
3308 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3309 *v = tok;
3310 next();
3311 } else {
3312 if (!(td & TYPE_ABSTRACT))
3313 expect("identifier");
3314 *v = 0;
3315 }
3316 }
3317 storage = type->t & VT_STORAGE;
3318 type->t &= ~VT_STORAGE;
3319 if (storage & VT_STATIC) {
3320 int saved_nocode_wanted = nocode_wanted;
3321 nocode_wanted = 1;
3322 post_type(type, ad);
3323 nocode_wanted = saved_nocode_wanted;
3324 } else
3325 post_type(type, ad);
3326 type->t |= storage;
3327 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3328 parse_attribute(ad);
3329
3330 if (!type1.t)
3331 return;
3332 /* append type at the end of type1 */
3333 type2 = &type1;
3334 for(;;) {
3335 s = type2->ref;
3336 type2 = &s->type;
3337 if (!type2->t) {
3338 *type2 = *type;
3339 break;
3340 }
3341 }
3342 *type = type1;
3343}
3344
3345/* compute the lvalue VT_LVAL_xxx needed to match type t. */
3346ST_FUNC int lvalue_type(int t)
3347{
3348 int bt, r;
3349 r = VT_LVAL;
3350 bt = t & VT_BTYPE;
3351 if (bt == VT_BYTE || bt == VT_BOOL)
3352 r |= VT_LVAL_BYTE;
3353 else if (bt == VT_SHORT)
3354 r |= VT_LVAL_SHORT;
3355 else
3356 return r;
3357 if (t & VT_UNSIGNED)
3358 r |= VT_LVAL_UNSIGNED;
3359 return r;
3360}
3361
3362/* indirection with full error checking and bound check */
3363ST_FUNC void indir(void)
3364{
3365 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3366 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3367 return;
3368 expect("pointer");
3369 }
3370 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3371 gv(RC_INT);
3372 vtop->type = *pointed_type(&vtop->type);
3373 /* Arrays and functions are never lvalues */
3374 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3375 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3376 vtop->r |= lvalue_type(vtop->type.t);
3377 /* if bound checking, the referenced pointer must be checked */
3378#ifdef CONFIG_TCC_BCHECK
3379 if (tcc_state->do_bounds_check)
3380 vtop->r |= VT_MUSTBOUND;
3381#endif
3382 }
3383}
3384
3385/* pass a parameter to a function and do type checking and casting */
3386static void gfunc_param_typed(Sym *func, Sym *arg)
3387{
3388 int func_type;
3389 CType type;
3390
3391 func_type = func->c;
3392 if (func_type == FUNC_OLD ||
3393 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3394 /* default casting : only need to convert float to double */
3395 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3396 type.t = VT_DOUBLE;
3397 gen_cast(&type);
3398 }
3399 } else if (arg == NULL) {
3400 tcc_error("too many arguments to function");
3401 } else {
3402 type = arg->type;
3403 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3404 gen_assign_cast(&type);
3405 }
3406}
3407
3408/* parse an expression of the form '(type)' or '(expr)' and return its
3409 type */
3410static void parse_expr_type(CType *type)
3411{
3412 int n;
3413 AttributeDef ad;
3414
3415 skip('(');
3416 if (parse_btype(type, &ad)) {
3417 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3418 } else {
3419 expr_type(type);
3420 }
3421 skip(')');
3422}
3423
3424static void parse_type(CType *type)
3425{
3426 AttributeDef ad;
3427 int n;
3428
3429 if (!parse_btype(type, &ad)) {
3430 expect("type");
3431 }
3432 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3433}
3434
3435static void vpush_tokc(int t)
3436{
3437 CType type;
3438 type.t = t;
3439 type.ref = 0;
3440 vsetc(&type, VT_CONST, &tokc);
3441}
3442
3443ST_FUNC void unary(void)
3444{
3445 int n, t, align, size, r, sizeof_caller;
3446 CType type;
3447 Sym *s;
3448 AttributeDef ad;
3449 static int in_sizeof = 0;
3450
3451 sizeof_caller = in_sizeof;
3452 in_sizeof = 0;
3453 /* XXX: GCC 2.95.3 does not generate a table although it should be
3454 better here */
3455 tok_next:
3456 switch(tok) {
3457 case TOK_EXTENSION:
3458 next();
3459 goto tok_next;
3460 case TOK_CINT:
3461 case TOK_CCHAR:
3462 case TOK_LCHAR:
3463 vpushi(tokc.i);
3464 next();
3465 break;
3466 case TOK_CUINT:
3467 vpush_tokc(VT_INT | VT_UNSIGNED);
3468 next();
3469 break;
3470 case TOK_CLLONG:
3471 vpush_tokc(VT_LLONG);
3472 next();
3473 break;
3474 case TOK_CULLONG:
3475 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3476 next();
3477 break;
3478 case TOK_CFLOAT:
3479 vpush_tokc(VT_FLOAT);
3480 next();
3481 break;
3482 case TOK_CDOUBLE:
3483 vpush_tokc(VT_DOUBLE);
3484 next();
3485 break;
3486 case TOK_CLDOUBLE:
3487 vpush_tokc(VT_LDOUBLE);
3488 next();
3489 break;
3490 case TOK___FUNCTION__:
3491 if (!gnu_ext)
3492 goto tok_identifier;
3493 /* fall thru */
3494 case TOK___FUNC__:
3495 {
3496 void *ptr;
3497 int len;
3498 /* special function name identifier */
3499 len = strlen(funcname) + 1;
3500 /* generate char[len] type */
3501 type.t = VT_BYTE;
3502 mk_pointer(&type);
3503 type.t |= VT_ARRAY;
3504 type.ref->c = len;
3505 vpush_ref(&type, data_section, data_section->data_offset, len);
3506 ptr = section_ptr_add(data_section, len);
3507 memcpy(ptr, funcname, len);
3508 next();
3509 }
3510 break;
3511 case TOK_LSTR:
3512#ifdef TCC_TARGET_PE
3513 t = VT_SHORT | VT_UNSIGNED;
3514#else
3515 t = VT_INT;
3516#endif
3517 goto str_init;
3518 case TOK_STR:
3519 /* string parsing */
3520 t = VT_BYTE;
3521 str_init:
3522 if (tcc_state->warn_write_strings)
3523 t |= VT_CONSTANT;
3524 type.t = t;
3525 mk_pointer(&type);
3526 type.t |= VT_ARRAY;
3527 memset(&ad, 0, sizeof(AttributeDef));
3528 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3529 break;
3530 case '(':
3531 next();
3532 /* cast ? */
3533 if (parse_btype(&type, &ad)) {
3534 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3535 skip(')');
3536 /* check ISOC99 compound literal */
3537 if (tok == '{') {
3538 /* data is allocated locally by default */
3539 if (global_expr)
3540 r = VT_CONST;
3541 else
3542 r = VT_LOCAL;
3543 /* all except arrays are lvalues */
3544 if (!(type.t & VT_ARRAY))
3545 r |= lvalue_type(type.t);
3546 memset(&ad, 0, sizeof(AttributeDef));
3547 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3548 } else {
3549 if (sizeof_caller) {
3550 vpush(&type);
3551 return;
3552 }
3553 unary();
3554 gen_cast(&type);
3555 }
3556 } else if (tok == '{') {
3557 /* save all registers */
3558 save_regs(0);
3559 /* statement expression : we do not accept break/continue
3560 inside as GCC does */
3561 block(NULL, NULL, NULL, NULL, 0, 1);
3562 skip(')');
3563 } else {
3564 gexpr();
3565 skip(')');
3566 }
3567 break;
3568 case '*':
3569 next();
3570 unary();
3571 indir();
3572 break;
3573 case '&':
3574 next();
3575 unary();
3576 /* functions names must be treated as function pointers,
3577 except for unary '&' and sizeof. Since we consider that
3578 functions are not lvalues, we only have to handle it
3579 there and in function calls. */
3580 /* arrays can also be used although they are not lvalues */
3581 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3582 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3583 test_lvalue();
3584 mk_pointer(&vtop->type);
3585 gaddrof();
3586 break;
3587 case '!':
3588 next();
3589 unary();
3590 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3591 CType boolean;
3592 boolean.t = VT_BOOL;
3593 gen_cast(&boolean);
3594 vtop->c.i = !vtop->c.i;
3595 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3596 vtop->c.i = vtop->c.i ^ 1;
3597 else {
3598 save_regs(1);
3599 vseti(VT_JMP, gtst(1, 0));
3600 }
3601 break;
3602 case '~':
3603 next();
3604 unary();
3605 vpushi(-1);
3606 gen_op('^');
3607 break;
3608 case '+':
3609 next();
3610 /* in order to force cast, we add zero */
3611 unary();
3612 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3613 tcc_error("pointer not accepted for unary plus");
3614 vpushi(0);
3615 gen_op('+');
3616 break;
3617 case TOK_SIZEOF:
3618 case TOK_ALIGNOF1:
3619 case TOK_ALIGNOF2:
3620 t = tok;
3621 next();
3622 in_sizeof++;
3623 unary_type(&type); // Perform a in_sizeof = 0;
3624 size = type_size(&type, &align);
3625 if (t == TOK_SIZEOF) {
3626 if (!(type.t & VT_VLA)) {
3627 if (size < 0)
3628 tcc_error("sizeof applied to an incomplete type");
3629 vpushs(size);
3630 } else {
3631 vla_runtime_type_size(&type, &align);
3632 }
3633 } else {
3634 vpushs(align);
3635 }
3636 vtop->type.t |= VT_UNSIGNED;
3637 break;
3638
3639 case TOK_builtin_types_compatible_p:
3640 {
3641 CType type1, type2;
3642 next();
3643 skip('(');
3644 parse_type(&type1);
3645 skip(',');
3646 parse_type(&type2);
3647 skip(')');
3648 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3649 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3650 vpushi(is_compatible_types(&type1, &type2));
3651 }
3652 break;
3653 case TOK_builtin_constant_p:
3654 {
3655 int saved_nocode_wanted, res;
3656 next();
3657 skip('(');
3658 saved_nocode_wanted = nocode_wanted;
3659 nocode_wanted = 1;
3660 gexpr();
3661 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3662 vpop();
3663 nocode_wanted = saved_nocode_wanted;
3664 skip(')');
3665 vpushi(res);
3666 }
3667 break;
3668 case TOK_builtin_frame_address:
3669 {
3670 int level;
3671 CType type;
3672 next();
3673 skip('(');
3674 if (tok != TOK_CINT || tokc.i < 0) {
3675 tcc_error("__builtin_frame_address only takes positive integers");
3676 }
3677 level = tokc.i;
3678 next();
3679 skip(')');
3680 type.t = VT_VOID;
3681 mk_pointer(&type);
3682 vset(&type, VT_LOCAL, 0); /* local frame */
3683 while (level--) {
3684 mk_pointer(&vtop->type);
3685 indir(); /* -> parent frame */
3686 }
3687 }
3688 break;
3689#ifdef TCC_TARGET_X86_64
3690 case TOK_builtin_va_arg_types:
3691 {
3692 /* This definition must be synced with stdarg.h */
3693 enum __va_arg_type {
3694 __va_gen_reg, __va_float_reg, __va_stack
3695 };
3696 CType type;
3697 int bt;
3698 next();
3699 skip('(');
3700 parse_type(&type);
3701 skip(')');
3702 bt = type.t & VT_BTYPE;
3703 if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
3704 vpushi(__va_stack);
3705 } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
3706 vpushi(__va_float_reg);
3707 } else {
3708 vpushi(__va_gen_reg);
3709 }
3710 }
3711 break;
3712#endif
3713 case TOK_INC:
3714 case TOK_DEC:
3715 t = tok;
3716 next();
3717 unary();
3718 inc(0, t);
3719 break;
3720 case '-':
3721 next();
3722 vpushi(0);
3723 unary();
3724 gen_op('-');
3725 break;
3726 case TOK_LAND:
3727 if (!gnu_ext)
3728 goto tok_identifier;
3729 next();
3730 /* allow to take the address of a label */
3731 if (tok < TOK_UIDENT)
3732 expect("label identifier");
3733 s = label_find(tok);
3734 if (!s) {
3735 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3736 } else {
3737 if (s->r == LABEL_DECLARED)
3738 s->r = LABEL_FORWARD;
3739 }
3740 if (!s->type.t) {
3741 s->type.t = VT_VOID;
3742 mk_pointer(&s->type);
3743 s->type.t |= VT_STATIC;
3744 }
3745 vset(&s->type, VT_CONST | VT_SYM, 0);
3746 vtop->sym = s;
3747 next();
3748 break;
3749
3750 // special qnan , snan and infinity values
3751 case TOK___NAN__:
3752 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3753 next();
3754 break;
3755 case TOK___SNAN__:
3756 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3757 next();
3758 break;
3759 case TOK___INF__:
3760 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3761 next();
3762 break;
3763
3764 default:
3765 tok_identifier:
3766 t = tok;
3767 next();
3768 if (t < TOK_UIDENT)
3769 expect("identifier");
3770 s = sym_find(t);
3771 if (!s) {
3772 if (tok != '(')
3773 tcc_error("'%s' undeclared", get_tok_str(t, NULL));
3774 /* for simple function calls, we tolerate undeclared
3775 external reference to int() function */
3776 if (tcc_state->warn_implicit_function_declaration)
3777 tcc_warning("implicit declaration of function '%s'",
3778 get_tok_str(t, NULL));
3779 s = external_global_sym(t, &func_old_type, 0);
3780 }
3781 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3782 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3783 /* if referencing an inline function, then we generate a
3784 symbol to it if not already done. It will have the
3785 effect to generate code for it at the end of the
3786 compilation unit. Inline function as always
3787 generated in the text section. */
3788 if (!s->c)
3789 put_extern_sym(s, text_section, 0, 0);
3790 r = VT_SYM | VT_CONST;
3791 } else {
3792 r = s->r;
3793 }
3794 vset(&s->type, r, s->c);
3795 /* if forward reference, we must point to s */
3796 if (vtop->r & VT_SYM) {
3797 vtop->sym = s;
3798 vtop->c.ul = 0;
3799 }
3800 break;
3801 }
3802
3803 /* post operations */
3804 while (1) {
3805 if (tok == TOK_INC || tok == TOK_DEC) {
3806 inc(1, tok);
3807 next();
3808 } else if (tok == '.' || tok == TOK_ARROW) {
3809 int qualifiers;
3810 /* field */
3811 if (tok == TOK_ARROW)
3812 indir();
3813 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3814 test_lvalue();
3815 gaddrof();
3816 next();
3817 /* expect pointer on structure */
3818 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3819 expect("struct or union");
3820 s = vtop->type.ref;
3821 /* find field */
3822 tok |= SYM_FIELD;
3823 while ((s = s->next) != NULL) {
3824 if (s->v == tok)
3825 break;
3826 }
3827 if (!s)
3828 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3829 /* add field offset to pointer */
3830 vtop->type = char_pointer_type; /* change type to 'char *' */
3831 vpushi(s->c);
3832 gen_op('+');
3833 /* change type to field type, and set to lvalue */
3834 vtop->type = s->type;
3835 vtop->type.t |= qualifiers;
3836 /* an array is never an lvalue */
3837 if (!(vtop->type.t & VT_ARRAY)) {
3838 vtop->r |= lvalue_type(vtop->type.t);
3839#ifdef CONFIG_TCC_BCHECK
3840 /* if bound checking, the referenced pointer must be checked */
3841 if (tcc_state->do_bounds_check)
3842 vtop->r |= VT_MUSTBOUND;
3843#endif
3844 }
3845 next();
3846 } else if (tok == '[') {
3847 next();
3848 gexpr();
3849 gen_op('+');
3850 indir();
3851 skip(']');
3852 } else if (tok == '(') {
3853 SValue ret;
3854 Sym *sa;
3855 int nb_args;
3856
3857 /* function call */
3858 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3859 /* pointer test (no array accepted) */
3860 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3861 vtop->type = *pointed_type(&vtop->type);
3862 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3863 goto error_func;
3864 } else {
3865 error_func:
3866 expect("function pointer");
3867 }
3868 } else {
3869 vtop->r &= ~VT_LVAL; /* no lvalue */
3870 }
3871 /* get return type */
3872 s = vtop->type.ref;
3873 next();
3874 sa = s->next; /* first parameter */
3875 nb_args = 0;
3876 ret.r2 = VT_CONST;
3877 /* compute first implicit argument if a structure is returned */
3878 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3879 /* get some space for the returned structure */
3880 size = type_size(&s->type, &align);
3881 loc = (loc - size) & -align;
3882 ret.type = s->type;
3883 ret.r = VT_LOCAL | VT_LVAL;
3884 /* pass it as 'int' to avoid structure arg passing
3885 problems */
3886 vseti(VT_LOCAL, loc);
3887 ret.c = vtop->c;
3888 nb_args++;
3889 } else {
3890 ret.type = s->type;
3891 /* return in register */
3892 if (is_float(ret.type.t)) {
3893 ret.r = reg_fret(ret.type.t);
3894 } else {
3895 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3896 ret.r2 = REG_LRET;
3897 ret.r = REG_IRET;
3898 }
3899 ret.c.i = 0;
3900 }
3901 if (tok != ')') {
3902 for(;;) {
3903 expr_eq();
3904 gfunc_param_typed(s, sa);
3905 nb_args++;
3906 if (sa)
3907 sa = sa->next;
3908 if (tok == ')')
3909 break;
3910 skip(',');
3911 }
3912 }
3913 if (sa)
3914 tcc_error("too few arguments to function");
3915 skip(')');
3916 if (!nocode_wanted) {
3917 gfunc_call(nb_args);
3918 } else {
3919 vtop -= (nb_args + 1);
3920 }
3921 /* return value */
3922 vsetc(&ret.type, ret.r, &ret.c);
3923 vtop->r2 = ret.r2;
3924 } else {
3925 break;
3926 }
3927 }
3928}
3929
3930ST_FUNC void expr_prod(void)
3931{
3932 int t;
3933
3934 unary();
3935 while (tok == '*' || tok == '/' || tok == '%') {
3936 t = tok;
3937 next();
3938 unary();
3939 gen_op(t);
3940 }
3941}
3942
3943ST_FUNC void expr_sum(void)
3944{
3945 int t;
3946
3947 expr_prod();
3948 while (tok == '+' || tok == '-') {
3949 t = tok;
3950 next();
3951 expr_prod();
3952 gen_op(t);
3953 }
3954}
3955
3956static void expr_shift(void)
3957{
3958 int t;
3959
3960 expr_sum();
3961 while (tok == TOK_SHL || tok == TOK_SAR) {
3962 t = tok;
3963 next();
3964 expr_sum();
3965 gen_op(t);
3966 }
3967}
3968
3969static void expr_cmp(void)
3970{
3971 int t;
3972
3973 expr_shift();
3974 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3975 tok == TOK_ULT || tok == TOK_UGE) {
3976 t = tok;
3977 next();
3978 expr_shift();
3979 gen_op(t);
3980 }
3981}
3982
3983static void expr_cmpeq(void)
3984{
3985 int t;
3986
3987 expr_cmp();
3988 while (tok == TOK_EQ || tok == TOK_NE) {
3989 t = tok;
3990 next();
3991 expr_cmp();
3992 gen_op(t);
3993 }
3994}
3995
3996static void expr_and(void)
3997{
3998 expr_cmpeq();
3999 while (tok == '&') {
4000 next();
4001 expr_cmpeq();
4002 gen_op('&');
4003 }
4004}
4005
4006static void expr_xor(void)
4007{
4008 expr_and();
4009 while (tok == '^') {
4010 next();
4011 expr_and();
4012 gen_op('^');
4013 }
4014}
4015
4016static void expr_or(void)
4017{
4018 expr_xor();
4019 while (tok == '|') {
4020 next();
4021 expr_xor();
4022 gen_op('|');
4023 }
4024}
4025
4026/* XXX: fix this mess */
4027static void expr_land_const(void)
4028{
4029 expr_or();
4030 while (tok == TOK_LAND) {
4031 next();
4032 expr_or();
4033 gen_op(TOK_LAND);
4034 }
4035}
4036
4037/* XXX: fix this mess */
4038static void expr_lor_const(void)
4039{
4040 expr_land_const();
4041 while (tok == TOK_LOR) {
4042 next();
4043 expr_land_const();
4044 gen_op(TOK_LOR);
4045 }
4046}
4047
4048/* only used if non constant */
4049static void expr_land(void)
4050{
4051 int t;
4052
4053 expr_or();
4054 if (tok == TOK_LAND) {
4055 t = 0;
4056 save_regs(1);
4057 for(;;) {
4058 t = gtst(1, t);
4059 if (tok != TOK_LAND) {
4060 vseti(VT_JMPI, t);
4061 break;
4062 }
4063 next();
4064 expr_or();
4065 }
4066 }
4067}
4068
4069static void expr_lor(void)
4070{
4071 int t;
4072
4073 expr_land();
4074 if (tok == TOK_LOR) {
4075 t = 0;
4076 save_regs(1);
4077 for(;;) {
4078 t = gtst(0, t);
4079 if (tok != TOK_LOR) {
4080 vseti(VT_JMP, t);
4081 break;
4082 }
4083 next();
4084 expr_land();
4085 }
4086 }
4087}
4088
4089/* XXX: better constant handling */
4090static void expr_cond(void)
4091{
4092 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4093 SValue sv;
4094 CType type, type1, type2;
4095
4096 if (const_wanted) {
4097 expr_lor_const();
4098 if (tok == '?') {
4099 CType boolean;
4100 int c;
4101 boolean.t = VT_BOOL;
4102 vdup();
4103 gen_cast(&boolean);
4104 c = vtop->c.i;
4105 vpop();
4106 next();
4107 if (tok != ':' || !gnu_ext) {
4108 vpop();
4109 gexpr();
4110 }
4111 if (!c)
4112 vpop();
4113 skip(':');
4114 expr_cond();
4115 if (c)
4116 vpop();
4117 }
4118 } else {
4119 expr_lor();
4120 if (tok == '?') {
4121 next();
4122 if (vtop != vstack) {
4123 /* needed to avoid having different registers saved in
4124 each branch */
4125 if (is_float(vtop->type.t)) {
4126 rc = RC_FLOAT;
4127#ifdef TCC_TARGET_X86_64
4128 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4129 rc = RC_ST0;
4130 }
4131#endif
4132 }
4133 else
4134 rc = RC_INT;
4135 gv(rc);
4136 save_regs(1);
4137 }
4138 if (tok == ':' && gnu_ext) {
4139 gv_dup();
4140 tt = gtst(1, 0);
4141 } else {
4142 tt = gtst(1, 0);
4143 gexpr();
4144 }
4145 type1 = vtop->type;
4146 sv = *vtop; /* save value to handle it later */
4147 vtop--; /* no vpop so that FP stack is not flushed */
4148 skip(':');
4149 u = gjmp(0);
4150 gsym(tt);
4151 expr_cond();
4152 type2 = vtop->type;
4153
4154 t1 = type1.t;
4155 bt1 = t1 & VT_BTYPE;
4156 t2 = type2.t;
4157 bt2 = t2 & VT_BTYPE;
4158 /* cast operands to correct type according to ISOC rules */
4159 if (is_float(bt1) || is_float(bt2)) {
4160 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4161 type.t = VT_LDOUBLE;
4162 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4163 type.t = VT_DOUBLE;
4164 } else {
4165 type.t = VT_FLOAT;
4166 }
4167 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4168 /* cast to biggest op */
4169 type.t = VT_LLONG;
4170 /* convert to unsigned if it does not fit in a long long */
4171 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4172 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4173 type.t |= VT_UNSIGNED;
4174 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4175 /* If one is a null ptr constant the result type
4176 is the other. */
4177 if (is_null_pointer (vtop))
4178 type = type1;
4179 else if (is_null_pointer (&sv))
4180 type = type2;
4181 /* XXX: test pointer compatibility, C99 has more elaborate
4182 rules here. */
4183 else
4184 type = type1;
4185 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4186 /* XXX: test function pointer compatibility */
4187 type = bt1 == VT_FUNC ? type1 : type2;
4188 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4189 /* XXX: test structure compatibility */
4190 type = bt1 == VT_STRUCT ? type1 : type2;
4191 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4192 /* NOTE: as an extension, we accept void on only one side */
4193 type.t = VT_VOID;
4194 } else {
4195 /* integer operations */
4196 type.t = VT_INT;
4197 /* convert to unsigned if it does not fit in an integer */
4198 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4199 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4200 type.t |= VT_UNSIGNED;
4201 }
4202
4203 /* now we convert second operand */
4204 gen_cast(&type);
4205 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4206 gaddrof();
4207 rc = RC_INT;
4208 if (is_float(type.t)) {
4209 rc = RC_FLOAT;
4210#ifdef TCC_TARGET_X86_64
4211 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4212 rc = RC_ST0;
4213 }
4214#endif
4215 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4216 /* for long longs, we use fixed registers to avoid having
4217 to handle a complicated move */
4218 rc = RC_IRET;
4219 }
4220
4221 r2 = gv(rc);
4222 /* this is horrible, but we must also convert first
4223 operand */
4224 tt = gjmp(0);
4225 gsym(u);
4226 /* put again first value and cast it */
4227 *vtop = sv;
4228 gen_cast(&type);
4229 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4230 gaddrof();
4231 r1 = gv(rc);
4232 move_reg(r2, r1);
4233 vtop->r = r2;
4234 gsym(tt);
4235 }
4236 }
4237}
4238
4239static void expr_eq(void)
4240{
4241 int t;
4242
4243 expr_cond();
4244 if (tok == '=' ||
4245 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4246 tok == TOK_A_XOR || tok == TOK_A_OR ||
4247 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4248 test_lvalue();
4249 t = tok;
4250 next();
4251 if (t == '=') {
4252 expr_eq();
4253 } else {
4254 vdup();
4255 expr_eq();
4256 gen_op(t & 0x7f);
4257 }
4258 vstore();
4259 }
4260}
4261
4262ST_FUNC void gexpr(void)
4263{
4264 while (1) {
4265 expr_eq();
4266 if (tok != ',')
4267 break;
4268 vpop();
4269 next();
4270 }
4271}
4272
4273/* parse an expression and return its type without any side effect. */
4274static void expr_type(CType *type)
4275{
4276 int saved_nocode_wanted;
4277
4278 saved_nocode_wanted = nocode_wanted;
4279 nocode_wanted = 1;
4280 gexpr();
4281 *type = vtop->type;
4282 vpop();
4283 nocode_wanted = saved_nocode_wanted;
4284}
4285
4286/* parse a unary expression and return its type without any side
4287 effect. */
4288static void unary_type(CType *type)
4289{
4290 int a;
4291
4292 a = nocode_wanted;
4293 nocode_wanted = 1;
4294 unary();
4295 *type = vtop->type;
4296 vpop();
4297 nocode_wanted = a;
4298}
4299
4300/* parse a constant expression and return value in vtop. */
4301static void expr_const1(void)
4302{
4303 int a;
4304 a = const_wanted;
4305 const_wanted = 1;
4306 expr_cond();
4307 const_wanted = a;
4308}
4309
4310/* parse an integer constant and return its value. */
4311ST_FUNC int expr_const(void)
4312{
4313 int c;
4314 expr_const1();
4315 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4316 expect("constant expression");
4317 c = vtop->c.i;
4318 vpop();
4319 return c;
4320}
4321
4322/* return the label token if current token is a label, otherwise
4323 return zero */
4324static int is_label(void)
4325{
4326 int last_tok;
4327
4328 /* fast test first */
4329 if (tok < TOK_UIDENT)
4330 return 0;
4331 /* no need to save tokc because tok is an identifier */
4332 last_tok = tok;
4333 next();
4334 if (tok == ':') {
4335 next();
4336 return last_tok;
4337 } else {
4338 unget_tok(last_tok);
4339 return 0;
4340 }
4341}
4342
4343static void label_or_decl(int l)
4344{
4345 int last_tok;
4346
4347 /* fast test first */
4348 if (tok >= TOK_UIDENT)
4349 {
4350 /* no need to save tokc because tok is an identifier */
4351 last_tok = tok;
4352 next();
4353 if (tok == ':') {
4354 unget_tok(last_tok);
4355 return;
4356 }
4357 unget_tok(last_tok);
4358 }
4359 decl(l);
4360}
4361
4362static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4363 int case_reg, int is_expr)
4364{
4365 int a, b, c, d;
4366 Sym *s, *frame_bottom;
4367
4368 /* generate line number info */
4369 if (tcc_state->do_debug &&
4370 (last_line_num != file->line_num || last_ind != ind)) {
4371 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4372 last_ind = ind;
4373 last_line_num = file->line_num;
4374 }
4375
4376 if (is_expr) {
4377 /* default return value is (void) */
4378 vpushi(0);
4379 vtop->type.t = VT_VOID;
4380 }
4381
4382 if (tok == TOK_IF) {
4383 /* if test */
4384 next();
4385 skip('(');
4386 gexpr();
4387 skip(')');
4388 a = gtst(1, 0);
4389 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4390 c = tok;
4391 if (c == TOK_ELSE) {
4392 next();
4393 d = gjmp(0);
4394 gsym(a);
4395 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4396 gsym(d); /* patch else jmp */
4397 } else
4398 gsym(a);
4399 } else if (tok == TOK_WHILE) {
4400 next();
4401 d = ind;
4402 skip('(');
4403 gexpr();
4404 skip(')');
4405 a = gtst(1, 0);
4406 b = 0;
4407 block(&a, &b, case_sym, def_sym, case_reg, 0);
4408 gjmp_addr(d);
4409 gsym(a);
4410 gsym_addr(b, d);
4411 } else if (tok == '{') {
4412 Sym *llabel;
4413
4414 next();
4415 /* record local declaration stack position */
4416 s = local_stack;
4417 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4418 frame_bottom->next = scope_stack_bottom;
4419 scope_stack_bottom = frame_bottom;
4420 llabel = local_label_stack;
4421 /* handle local labels declarations */
4422 if (tok == TOK_LABEL) {
4423 next();
4424 for(;;) {
4425 if (tok < TOK_UIDENT)
4426 expect("label identifier");
4427 label_push(&local_label_stack, tok, LABEL_DECLARED);
4428 next();
4429 if (tok == ',') {
4430 next();
4431 } else {
4432 skip(';');
4433 break;
4434 }
4435 }
4436 }
4437 while (tok != '}') {
4438 label_or_decl(VT_LOCAL);
4439 if (tok != '}') {
4440 if (is_expr)
4441 vpop();
4442 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4443 }
4444 }
4445 /* pop locally defined labels */
4446 label_pop(&local_label_stack, llabel);
4447 if(is_expr) {
4448 /* XXX: this solution makes only valgrind happy...
4449 triggered by gcc.c-torture/execute/20000917-1.c */
4450 Sym *p;
4451 switch(vtop->type.t & VT_BTYPE) {
4452 case VT_PTR:
4453 case VT_STRUCT:
4454 case VT_ENUM:
4455 case VT_FUNC:
4456 for(p=vtop->type.ref;p;p=p->prev)
4457 if(p->prev==s)
4458 tcc_error("unsupported expression type");
4459 }
4460 }
4461 /* pop locally defined symbols */
4462 scope_stack_bottom = scope_stack_bottom->next;
4463 sym_pop(&local_stack, s);
4464 next();
4465 } else if (tok == TOK_RETURN) {
4466 next();
4467 if (tok != ';') {
4468 gexpr();
4469 gen_assign_cast(&func_vt);
4470 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4471 CType type;
4472 /* if returning structure, must copy it to implicit
4473 first pointer arg location */
4474#ifdef TCC_ARM_EABI
4475 int align, size;
4476 size = type_size(&func_vt,&align);
4477 if(size <= 4)
4478 {
4479 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4480 && (align & 3))
4481 {
4482 int addr;
4483 loc = (loc - size) & -4;
4484 addr = loc;
4485 type = func_vt;
4486 vset(&type, VT_LOCAL | VT_LVAL, addr);
4487 vswap();
4488 vstore();
4489 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4490 }
4491 vtop->type = int_type;
4492 gv(RC_IRET);
4493 } else {
4494#endif
4495 type = func_vt;
4496 mk_pointer(&type);
4497 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4498 indir();
4499 vswap();
4500 /* copy structure value to pointer */
4501 vstore();
4502#ifdef TCC_ARM_EABI
4503 }
4504#endif
4505 } else if (is_float(func_vt.t)) {
4506 gv(rc_fret(func_vt.t));
4507 } else {
4508 gv(RC_IRET);
4509 }
4510 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4511 }
4512 skip(';');
4513 rsym = gjmp(rsym); /* jmp */
4514 } else if (tok == TOK_BREAK) {
4515 /* compute jump */
4516 if (!bsym)
4517 tcc_error("cannot break");
4518 *bsym = gjmp(*bsym);
4519 next();
4520 skip(';');
4521 } else if (tok == TOK_CONTINUE) {
4522 /* compute jump */
4523 if (!csym)
4524 tcc_error("cannot continue");
4525 *csym = gjmp(*csym);
4526 next();
4527 skip(';');
4528 } else if (tok == TOK_FOR) {
4529 int e;
4530 next();
4531 skip('(');
4532 s = local_stack;
4533 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4534 frame_bottom->next = scope_stack_bottom;
4535 scope_stack_bottom = frame_bottom;
4536 if (tok != ';') {
4537 /* c99 for-loop init decl? */
4538 if (!decl0(VT_LOCAL, 1)) {
4539 /* no, regular for-loop init expr */
4540 gexpr();
4541 vpop();
4542 }
4543 }
4544 skip(';');
4545 d = ind;
4546 c = ind;
4547 a = 0;
4548 b = 0;
4549 if (tok != ';') {
4550 gexpr();
4551 a = gtst(1, 0);
4552 }
4553 skip(';');
4554 if (tok != ')') {
4555 e = gjmp(0);
4556 c = ind;
4557 gexpr();
4558 vpop();
4559 gjmp_addr(d);
4560 gsym(e);
4561 }
4562 skip(')');
4563 block(&a, &b, case_sym, def_sym, case_reg, 0);
4564 gjmp_addr(c);
4565 gsym(a);
4566 gsym_addr(b, c);
4567 scope_stack_bottom = scope_stack_bottom->next;
4568 sym_pop(&local_stack, s);
4569 } else
4570 if (tok == TOK_DO) {
4571 next();
4572 a = 0;
4573 b = 0;
4574 d = ind;
4575 block(&a, &b, case_sym, def_sym, case_reg, 0);
4576 skip(TOK_WHILE);
4577 skip('(');
4578 gsym(b);
4579 gexpr();
4580 c = gtst(0, 0);
4581 gsym_addr(c, d);
4582 skip(')');
4583 gsym(a);
4584 skip(';');
4585 } else
4586 if (tok == TOK_SWITCH) {
4587 next();
4588 skip('(');
4589 gexpr();
4590 /* XXX: other types than integer */
4591 case_reg = gv(RC_INT);
4592 vpop();
4593 skip(')');
4594 a = 0;
4595 b = gjmp(0); /* jump to first case */
4596 c = 0;
4597 block(&a, csym, &b, &c, case_reg, 0);
4598 /* if no default, jmp after switch */
4599 if (c == 0)
4600 c = ind;
4601 /* default label */
4602 gsym_addr(b, c);
4603 /* break label */
4604 gsym(a);
4605 } else
4606 if (tok == TOK_CASE) {
4607 int v1, v2;
4608 if (!case_sym)
4609 expect("switch");
4610 next();
4611 v1 = expr_const();
4612 v2 = v1;
4613 if (gnu_ext && tok == TOK_DOTS) {
4614 next();
4615 v2 = expr_const();
4616 if (v2 < v1)
4617 tcc_warning("empty case range");
4618 }
4619 /* since a case is like a label, we must skip it with a jmp */
4620 b = gjmp(0);
4621 gsym(*case_sym);
4622 vseti(case_reg, 0);
4623 vpushi(v1);
4624 if (v1 == v2) {
4625 gen_op(TOK_EQ);
4626 *case_sym = gtst(1, 0);
4627 } else {
4628 gen_op(TOK_GE);
4629 *case_sym = gtst(1, 0);
4630 vseti(case_reg, 0);
4631 vpushi(v2);
4632 gen_op(TOK_LE);
4633 *case_sym = gtst(1, *case_sym);
4634 }
4635 gsym(b);
4636 skip(':');
4637 is_expr = 0;
4638 goto block_after_label;
4639 } else
4640 if (tok == TOK_DEFAULT) {
4641 next();
4642 skip(':');
4643 if (!def_sym)
4644 expect("switch");
4645 if (*def_sym)
4646 tcc_error("too many 'default'");
4647 *def_sym = ind;
4648 is_expr = 0;
4649 goto block_after_label;
4650 } else
4651 if (tok == TOK_GOTO) {
4652 next();
4653 if (tok == '*' && gnu_ext) {
4654 /* computed goto */
4655 next();
4656 gexpr();
4657 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4658 expect("pointer");
4659 ggoto();
4660 } else if (tok >= TOK_UIDENT) {
4661 s = label_find(tok);
4662 /* put forward definition if needed */
4663 if (!s) {
4664 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4665 } else {
4666 if (s->r == LABEL_DECLARED)
4667 s->r = LABEL_FORWARD;
4668 }
4669 /* label already defined */
4670 if (s->r & LABEL_FORWARD)
4671 s->jnext = gjmp(s->jnext);
4672 else
4673 gjmp_addr(s->jnext);
4674 next();
4675 } else {
4676 expect("label identifier");
4677 }
4678 skip(';');
4679 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4680 asm_instr();
4681 } else {
4682 b = is_label();
4683 if (b) {
4684 /* label case */
4685 s = label_find(b);
4686 if (s) {
4687 if (s->r == LABEL_DEFINED)
4688 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
4689 gsym(s->jnext);
4690 s->r = LABEL_DEFINED;
4691 } else {
4692 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4693 }
4694 s->jnext = ind;
4695 /* we accept this, but it is a mistake */
4696 block_after_label:
4697 if (tok == '}') {
4698 tcc_warning("deprecated use of label at end of compound statement");
4699 } else {
4700 if (is_expr)
4701 vpop();
4702 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4703 }
4704 } else {
4705 /* expression case */
4706 if (tok != ';') {
4707 if (is_expr) {
4708 vpop();
4709 gexpr();
4710 } else {
4711 gexpr();
4712 vpop();
4713 }
4714 }
4715 skip(';');
4716 }
4717 }
4718}
4719
4720/* t is the array or struct type. c is the array or struct
4721 address. cur_index/cur_field is the pointer to the current
4722 value. 'size_only' is true if only size info is needed (only used
4723 in arrays) */
4724static void decl_designator(CType *type, Section *sec, unsigned long c,
4725 int *cur_index, Sym **cur_field,
4726 int size_only)
4727{
4728 Sym *s, *f;
4729 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4730 CType type1;
4731
4732 notfirst = 0;
4733 elem_size = 0;
4734 nb_elems = 1;
4735 if (gnu_ext && (l = is_label()) != 0)
4736 goto struct_field;
4737 while (tok == '[' || tok == '.') {
4738 if (tok == '[') {
4739 if (!(type->t & VT_ARRAY))
4740 expect("array type");
4741 s = type->ref;
4742 next();
4743 index = expr_const();
4744 if (index < 0 || (s->c >= 0 && index >= s->c))
4745 expect("invalid index");
4746 if (tok == TOK_DOTS && gnu_ext) {
4747 next();
4748 index_last = expr_const();
4749 if (index_last < 0 ||
4750 (s->c >= 0 && index_last >= s->c) ||
4751 index_last < index)
4752 expect("invalid index");
4753 } else {
4754 index_last = index;
4755 }
4756 skip(']');
4757 if (!notfirst)
4758 *cur_index = index_last;
4759 type = pointed_type(type);
4760 elem_size = type_size(type, &align);
4761 c += index * elem_size;
4762 /* NOTE: we only support ranges for last designator */
4763 nb_elems = index_last - index + 1;
4764 if (nb_elems != 1) {
4765 notfirst = 1;
4766 break;
4767 }
4768 } else {
4769 next();
4770 l = tok;
4771 next();
4772 struct_field:
4773 if ((type->t & VT_BTYPE) != VT_STRUCT)
4774 expect("struct/union type");
4775 s = type->ref;
4776 l |= SYM_FIELD;
4777 f = s->next;
4778 while (f) {
4779 if (f->v == l)
4780 break;
4781 f = f->next;
4782 }
4783 if (!f)
4784 expect("field");
4785 if (!notfirst)
4786 *cur_field = f;
4787 /* XXX: fix this mess by using explicit storage field */
4788 type1 = f->type;
4789 type1.t |= (type->t & ~VT_TYPE);
4790 type = &type1;
4791 c += f->c;
4792 }
4793 notfirst = 1;
4794 }
4795 if (notfirst) {
4796 if (tok == '=') {
4797 next();
4798 } else {
4799 if (!gnu_ext)
4800 expect("=");
4801 }
4802 } else {
4803 if (type->t & VT_ARRAY) {
4804 index = *cur_index;
4805 type = pointed_type(type);
4806 c += index * type_size(type, &align);
4807 } else {
4808 f = *cur_field;
4809 if (!f)
4810 tcc_error("too many field init");
4811 /* XXX: fix this mess by using explicit storage field */
4812 type1 = f->type;
4813 type1.t |= (type->t & ~VT_TYPE);
4814 type = &type1;
4815 c += f->c;
4816 }
4817 }
4818 decl_initializer(type, sec, c, 0, size_only);
4819
4820 /* XXX: make it more general */
4821 if (!size_only && nb_elems > 1) {
4822 unsigned long c_end;
4823 uint8_t *src, *dst;
4824 int i;
4825
4826 if (!sec)
4827 tcc_error("range init not supported yet for dynamic storage");
4828 c_end = c + nb_elems * elem_size;
4829 if (c_end > sec->data_allocated)
4830 section_realloc(sec, c_end);
4831 src = sec->data + c;
4832 dst = src;
4833 for(i = 1; i < nb_elems; i++) {
4834 dst += elem_size;
4835 memcpy(dst, src, elem_size);
4836 }
4837 }
4838}
4839
4840#define EXPR_VAL 0
4841#define EXPR_CONST 1
4842#define EXPR_ANY 2
4843
4844/* store a value or an expression directly in global data or in local array */
4845static void init_putv(CType *type, Section *sec, unsigned long c,
4846 int v, int expr_type)
4847{
4848 int saved_global_expr, bt, bit_pos, bit_size;
4849 void *ptr;
4850 unsigned long long bit_mask;
4851 CType dtype;
4852
4853 switch(expr_type) {
4854 case EXPR_VAL:
4855 vpushi(v);
4856 break;
4857 case EXPR_CONST:
4858 /* compound literals must be allocated globally in this case */
4859 saved_global_expr = global_expr;
4860 global_expr = 1;
4861 expr_const1();
4862 global_expr = saved_global_expr;
4863 /* NOTE: symbols are accepted */
4864 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4865 tcc_error("initializer element is not constant");
4866 break;
4867 case EXPR_ANY:
4868 expr_eq();
4869 break;
4870 }
4871
4872 dtype = *type;
4873 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4874
4875 if (sec) {
4876 /* XXX: not portable */
4877 /* XXX: generate error if incorrect relocation */
4878 gen_assign_cast(&dtype);
4879 bt = type->t & VT_BTYPE;
4880 /* we'll write at most 12 bytes */
4881 if (c + 12 > sec->data_allocated) {
4882 section_realloc(sec, c + 12);
4883 }
4884 ptr = sec->data + c;
4885 /* XXX: make code faster ? */
4886 if (!(type->t & VT_BITFIELD)) {
4887 bit_pos = 0;
4888 bit_size = 32;
4889 bit_mask = -1LL;
4890 } else {
4891 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4892 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4893 bit_mask = (1LL << bit_size) - 1;
4894 }
4895 if ((vtop->r & VT_SYM) &&
4896 (bt == VT_BYTE ||
4897 bt == VT_SHORT ||
4898 bt == VT_DOUBLE ||
4899 bt == VT_LDOUBLE ||
4900 bt == VT_LLONG ||
4901 (bt == VT_INT && bit_size != 32)))
4902 tcc_error("initializer element is not computable at load time");
4903 switch(bt) {
4904 case VT_BOOL:
4905 vtop->c.i = (vtop->c.i != 0);
4906 case VT_BYTE:
4907 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4908 break;
4909 case VT_SHORT:
4910 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4911 break;
4912 case VT_DOUBLE:
4913 *(double *)ptr = vtop->c.d;
4914 break;
4915 case VT_LDOUBLE:
4916 *(long double *)ptr = vtop->c.ld;
4917 break;
4918 case VT_LLONG:
4919 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4920 break;
4921 default:
4922 if (vtop->r & VT_SYM) {
4923 greloc(sec, vtop->sym, c, R_DATA_PTR);
4924 }
4925 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4926 break;
4927 }
4928 vtop--;
4929 } else {
4930 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4931 vswap();
4932 vstore();
4933 vpop();
4934 }
4935}
4936
4937/* put zeros for variable based init */
4938static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4939{
4940 if (sec) {
4941 /* nothing to do because globals are already set to zero */
4942 } else {
4943 vpush_global_sym(&func_old_type, TOK_memset);
4944 vseti(VT_LOCAL, c);
4945 vpushi(0);
4946 vpushi(size);
4947 gfunc_call(3);
4948 }
4949}
4950
4951/* 't' contains the type and storage info. 'c' is the offset of the
4952 object in section 'sec'. If 'sec' is NULL, it means stack based
4953 allocation. 'first' is true if array '{' must be read (multi
4954 dimension implicit array init handling). 'size_only' is true if
4955 size only evaluation is wanted (only for arrays). */
4956static void decl_initializer(CType *type, Section *sec, unsigned long c,
4957 int first, int size_only)
4958{
4959 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
4960 int size1, align1, expr_type;
4961 Sym *s, *f;
4962 CType *t1;
4963
4964 if (type->t & VT_VLA) {
4965#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
4966 int a;
4967 CValue retcval;
4968
4969 vpush_global_sym(&func_old_type, TOK_alloca);
4970 vla_runtime_type_size(type, &a);
4971 gfunc_call(1);
4972
4973 /* return value */
4974 retcval.i = 0;
4975 vsetc(type, REG_IRET, &retcval);
4976 vset(type, VT_LOCAL|VT_LVAL, c);
4977 vswap();
4978 vstore();
4979 vpop();
4980#else
4981 tcc_error("variable length arrays unsupported for this target");
4982#endif
4983 } else if (type->t & VT_ARRAY) {
4984 s = type->ref;
4985 n = s->c;
4986 array_length = 0;
4987 t1 = pointed_type(type);
4988 size1 = type_size(t1, &align1);
4989
4990 no_oblock = 1;
4991 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4992 tok == '{') {
4993 if (tok != '{')
4994 tcc_error("character array initializer must be a literal,"
4995 " optionally enclosed in braces");
4996 skip('{');
4997 no_oblock = 0;
4998 }
4999
5000 /* only parse strings here if correct type (otherwise: handle
5001 them as ((w)char *) expressions */
5002 if ((tok == TOK_LSTR &&
5003#ifdef TCC_TARGET_PE
5004 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5005#else
5006 (t1->t & VT_BTYPE) == VT_INT
5007#endif
5008 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5009 while (tok == TOK_STR || tok == TOK_LSTR) {
5010 int cstr_len, ch;
5011 CString *cstr;
5012
5013 cstr = tokc.cstr;
5014 /* compute maximum number of chars wanted */
5015 if (tok == TOK_STR)
5016 cstr_len = cstr->size;
5017 else
5018 cstr_len = cstr->size / sizeof(nwchar_t);
5019 cstr_len--;
5020 nb = cstr_len;
5021 if (n >= 0 && nb > (n - array_length))
5022 nb = n - array_length;
5023 if (!size_only) {
5024 if (cstr_len > nb)
5025 tcc_warning("initializer-string for array is too long");
5026 /* in order to go faster for common case (char
5027 string in global variable, we handle it
5028 specifically */
5029 if (sec && tok == TOK_STR && size1 == 1) {
5030 memcpy(sec->data + c + array_length, cstr->data, nb);
5031 } else {
5032 for(i=0;i<nb;i++) {
5033 if (tok == TOK_STR)
5034 ch = ((unsigned char *)cstr->data)[i];
5035 else
5036 ch = ((nwchar_t *)cstr->data)[i];
5037 init_putv(t1, sec, c + (array_length + i) * size1,
5038 ch, EXPR_VAL);
5039 }
5040 }
5041 }
5042 array_length += nb;
5043 next();
5044 }
5045 /* only add trailing zero if enough storage (no
5046 warning in this case since it is standard) */
5047 if (n < 0 || array_length < n) {
5048 if (!size_only) {
5049 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5050 }
5051 array_length++;
5052 }
5053 } else {
5054 index = 0;
5055 while (tok != '}') {
5056 decl_designator(type, sec, c, &index, NULL, size_only);
5057 if (n >= 0 && index >= n)
5058 tcc_error("index too large");
5059 /* must put zero in holes (note that doing it that way
5060 ensures that it even works with designators) */
5061 if (!size_only && array_length < index) {
5062 init_putz(t1, sec, c + array_length * size1,
5063 (index - array_length) * size1);
5064 }
5065 index++;
5066 if (index > array_length)
5067 array_length = index;
5068 /* special test for multi dimensional arrays (may not
5069 be strictly correct if designators are used at the
5070 same time) */
5071 if (index >= n && no_oblock)
5072 break;
5073 if (tok == '}')
5074 break;
5075 skip(',');
5076 }
5077 }
5078 if (!no_oblock)
5079 skip('}');
5080 /* put zeros at the end */
5081 if (!size_only && n >= 0 && array_length < n) {
5082 init_putz(t1, sec, c + array_length * size1,
5083 (n - array_length) * size1);
5084 }
5085 /* patch type size if needed */
5086 if (n < 0)
5087 s->c = array_length;
5088 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5089 (sec || !first || tok == '{')) {
5090 int par_count;
5091
5092 /* NOTE: the previous test is a specific case for automatic
5093 struct/union init */
5094 /* XXX: union needs only one init */
5095
5096 /* XXX: this test is incorrect for local initializers
5097 beginning with ( without {. It would be much more difficult
5098 to do it correctly (ideally, the expression parser should
5099 be used in all cases) */
5100 par_count = 0;
5101 if (tok == '(') {
5102 AttributeDef ad1;
5103 CType type1;
5104 next();
5105 while (tok == '(') {
5106 par_count++;
5107 next();
5108 }
5109 if (!parse_btype(&type1, &ad1))
5110 expect("cast");
5111 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5112#if 0
5113 if (!is_assignable_types(type, &type1))
5114 tcc_error("invalid type for cast");
5115#endif
5116 skip(')');
5117 }
5118 no_oblock = 1;
5119 if (first || tok == '{') {
5120 skip('{');
5121 no_oblock = 0;
5122 }
5123 s = type->ref;
5124 f = s->next;
5125 array_length = 0;
5126 index = 0;
5127 n = s->c;
5128 while (tok != '}') {
5129 decl_designator(type, sec, c, NULL, &f, size_only);
5130 index = f->c;
5131 if (!size_only && array_length < index) {
5132 init_putz(type, sec, c + array_length,
5133 index - array_length);
5134 }
5135 index = index + type_size(&f->type, &align1);
5136 if (index > array_length)
5137 array_length = index;
5138
5139 /* gr: skip fields from same union - ugly. */
5140 while (f->next) {
5141 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5142 /* test for same offset */
5143 if (f->next->c != f->c)
5144 break;
5145 /* if yes, test for bitfield shift */
5146 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5147 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5148 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5149 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5150 if (bit_pos_1 != bit_pos_2)
5151 break;
5152 }
5153 f = f->next;
5154 }
5155
5156 f = f->next;
5157 if (no_oblock && f == NULL)
5158 break;
5159 if (tok == '}')
5160 break;
5161 skip(',');
5162 }
5163 /* put zeros at the end */
5164 if (!size_only && array_length < n) {
5165 init_putz(type, sec, c + array_length,
5166 n - array_length);
5167 }
5168 if (!no_oblock)
5169 skip('}');
5170 while (par_count) {
5171 skip(')');
5172 par_count--;
5173 }
5174 } else if (tok == '{') {
5175 next();
5176 decl_initializer(type, sec, c, first, size_only);
5177 skip('}');
5178 } else if (size_only) {
5179 /* just skip expression */
5180 parlevel = parlevel1 = 0;
5181 while ((parlevel > 0 || parlevel1 > 0 ||
5182 (tok != '}' && tok != ',')) && tok != -1) {
5183 if (tok == '(')
5184 parlevel++;
5185 else if (tok == ')')
5186 parlevel--;
5187 else if (tok == '{')
5188 parlevel1++;
5189 else if (tok == '}')
5190 parlevel1--;
5191 next();
5192 }
5193 } else {
5194 /* currently, we always use constant expression for globals
5195 (may change for scripting case) */
5196 expr_type = EXPR_CONST;
5197 if (!sec)
5198 expr_type = EXPR_ANY;
5199 init_putv(type, sec, c, 0, expr_type);
5200 }
5201}
5202
5203/* parse an initializer for type 't' if 'has_init' is non zero, and
5204 allocate space in local or global data space ('r' is either
5205 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5206 variable 'v' with an associated name represented by 'asm_label' of
5207 scope 'scope' is declared before initializers are parsed. If 'v' is
5208 zero, then a reference to the new object is put in the value stack.
5209 If 'has_init' is 2, a special parsing is done to handle string
5210 constants. */
5211static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5212 int has_init, int v, char *asm_label,
5213 int scope)
5214{
5215 int size, align, addr, data_offset;
5216 int level;
5217 ParseState saved_parse_state = {0};
5218 TokenString init_str;
5219 Section *sec;
5220 Sym *flexible_array;
5221
5222 flexible_array = NULL;
5223 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5224 Sym *field;
5225 field = type->ref;
5226 while (field && field->next)
5227 field = field->next;
5228 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5229 flexible_array = field;
5230 }
5231
5232 size = type_size(type, &align);
5233 /* If unknown size, we must evaluate it before
5234 evaluating initializers because
5235 initializers can generate global data too
5236 (e.g. string pointers or ISOC99 compound
5237 literals). It also simplifies local
5238 initializers handling */
5239 tok_str_new(&init_str);
5240 if (size < 0 || (flexible_array && has_init)) {
5241 if (!has_init)
5242 tcc_error("unknown type size");
5243 /* get all init string */
5244 if (has_init == 2) {
5245 /* only get strings */
5246 while (tok == TOK_STR || tok == TOK_LSTR) {
5247 tok_str_add_tok(&init_str);
5248 next();
5249 }
5250 } else {
5251 level = 0;
5252 while (level > 0 || (tok != ',' && tok != ';')) {
5253 if (tok < 0)
5254 tcc_error("unexpected end of file in initializer");
5255 tok_str_add_tok(&init_str);
5256 if (tok == '{')
5257 level++;
5258 else if (tok == '}') {
5259 level--;
5260 if (level <= 0) {
5261 next();
5262 break;
5263 }
5264 }
5265 next();
5266 }
5267 }
5268 tok_str_add(&init_str, -1);
5269 tok_str_add(&init_str, 0);
5270
5271 /* compute size */
5272 save_parse_state(&saved_parse_state);
5273
5274 macro_ptr = init_str.str;
5275 next();
5276 decl_initializer(type, NULL, 0, 1, 1);
5277 /* prepare second initializer parsing */
5278 macro_ptr = init_str.str;
5279 next();
5280
5281 /* if still unknown size, error */
5282 size = type_size(type, &align);
5283 if (size < 0)
5284 tcc_error("unknown type size");
5285 }
5286 if (flexible_array)
5287 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5288 /* take into account specified alignment if bigger */
5289 if (ad->aligned) {
5290 if (ad->aligned > align)
5291 align = ad->aligned;
5292 } else if (ad->packed) {
5293 align = 1;
5294 }
5295 if ((r & VT_VALMASK) == VT_LOCAL) {
5296 sec = NULL;
5297#ifdef CONFIG_TCC_BCHECK
5298 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5299 loc--;
5300 }
5301#endif
5302 loc = (loc - size) & -align;
5303 addr = loc;
5304#ifdef CONFIG_TCC_BCHECK
5305 /* handles bounds */
5306 /* XXX: currently, since we do only one pass, we cannot track
5307 '&' operators, so we add only arrays */
5308 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5309 unsigned long *bounds_ptr;
5310 /* add padding between regions */
5311 loc--;
5312 /* then add local bound info */
5313 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5314 bounds_ptr[0] = addr;
5315 bounds_ptr[1] = size;
5316 }
5317#endif
5318 if (v) {
5319 /* local variable */
5320 sym_push(v, type, r, addr);
5321 } else {
5322 /* push local reference */
5323 vset(type, r, addr);
5324 }
5325 } else {
5326 Sym *sym;
5327
5328 sym = NULL;
5329 if (v && scope == VT_CONST) {
5330 /* see if the symbol was already defined */
5331 sym = sym_find(v);
5332 if (sym) {
5333 if (!is_compatible_types(&sym->type, type))
5334 tcc_error("incompatible types for redefinition of '%s'",
5335 get_tok_str(v, NULL));
5336 if (sym->type.t & VT_EXTERN) {
5337 /* if the variable is extern, it was not allocated */
5338 sym->type.t &= ~VT_EXTERN;
5339 /* set array size if it was ommited in extern
5340 declaration */
5341 if ((sym->type.t & VT_ARRAY) &&
5342 sym->type.ref->c < 0 &&
5343 type->ref->c >= 0)
5344 sym->type.ref->c = type->ref->c;
5345 } else {
5346 /* we accept several definitions of the same
5347 global variable. this is tricky, because we
5348 must play with the SHN_COMMON type of the symbol */
5349 /* XXX: should check if the variable was already
5350 initialized. It is incorrect to initialized it
5351 twice */
5352 /* no init data, we won't add more to the symbol */
5353 if (!has_init)
5354 goto no_alloc;
5355 }
5356 }
5357 }
5358
5359 /* allocate symbol in corresponding section */
5360 sec = ad->section;
5361 if (!sec) {
5362 if (has_init)
5363 sec = data_section;
5364 else if (tcc_state->nocommon)
5365 sec = bss_section;
5366 }
5367 if (sec) {
5368 data_offset = sec->data_offset;
5369 data_offset = (data_offset + align - 1) & -align;
5370 addr = data_offset;
5371 /* very important to increment global pointer at this time
5372 because initializers themselves can create new initializers */
5373 data_offset += size;
5374#ifdef CONFIG_TCC_BCHECK
5375 /* add padding if bound check */
5376 if (tcc_state->do_bounds_check)
5377 data_offset++;
5378#endif
5379 sec->data_offset = data_offset;
5380 /* allocate section space to put the data */
5381 if (sec->sh_type != SHT_NOBITS &&
5382 data_offset > sec->data_allocated)
5383 section_realloc(sec, data_offset);
5384 /* align section if needed */
5385 if (align > sec->sh_addralign)
5386 sec->sh_addralign = align;
5387 } else {
5388 addr = 0; /* avoid warning */
5389 }
5390
5391 if (v) {
5392 if (scope != VT_CONST || !sym) {
5393 sym = sym_push(v, type, r | VT_SYM, 0);
5394 sym->asm_label = asm_label;
5395 }
5396 /* update symbol definition */
5397 if (sec) {
5398 put_extern_sym(sym, sec, addr, size);
5399 } else {
5400 ElfW(Sym) *esym;
5401 /* put a common area */
5402 put_extern_sym(sym, NULL, align, size);
5403 /* XXX: find a nicer way */
5404 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5405 esym->st_shndx = SHN_COMMON;
5406 }
5407 } else {
5408 CValue cval;
5409
5410 /* push global reference */
5411 sym = get_sym_ref(type, sec, addr, size);
5412 cval.ul = 0;
5413 vsetc(type, VT_CONST | VT_SYM, &cval);
5414 vtop->sym = sym;
5415 }
5416 /* patch symbol weakness */
5417 if (type->t & VT_WEAK)
5418 weaken_symbol(sym);
5419#ifdef CONFIG_TCC_BCHECK
5420 /* handles bounds now because the symbol must be defined
5421 before for the relocation */
5422 if (tcc_state->do_bounds_check) {
5423 unsigned long *bounds_ptr;
5424
5425 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5426 /* then add global bound info */
5427 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5428 bounds_ptr[0] = 0; /* relocated */
5429 bounds_ptr[1] = size;
5430 }
5431#endif
5432 }
5433 if (has_init || (type->t & VT_VLA)) {
5434 decl_initializer(type, sec, addr, 1, 0);
5435 /* restore parse state if needed */
5436 if (init_str.str) {
5437 tok_str_free(init_str.str);
5438 restore_parse_state(&saved_parse_state);
5439 }
5440 /* patch flexible array member size back to -1, */
5441 /* for possible subsequent similar declarations */
5442 if (flexible_array)
5443 flexible_array->type.ref->c = -1;
5444 }
5445 no_alloc: ;
5446}
5447
5448static void put_func_debug(Sym *sym)
5449{
5450 char buf[512];
5451
5452 /* stabs info */
5453 /* XXX: we put here a dummy type */
5454 snprintf(buf, sizeof(buf), "%s:%c1",
5455 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5456 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5457 cur_text_section, sym->c);
5458 /* //gr gdb wants a line at the function */
5459 put_stabn(N_SLINE, 0, file->line_num, 0);
5460 last_ind = 0;
5461 last_line_num = 0;
5462}
5463
5464/* parse an old style function declaration list */
5465/* XXX: check multiple parameter */
5466static void func_decl_list(Sym *func_sym)
5467{
5468 AttributeDef ad;
5469 int v;
5470 Sym *s;
5471 CType btype, type;
5472
5473 /* parse each declaration */
5474 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5475 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5476 if (!parse_btype(&btype, &ad))
5477 expect("declaration list");
5478 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5479 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5480 tok == ';') {
5481 /* we accept no variable after */
5482 } else {
5483 for(;;) {
5484 type = btype;
5485 type_decl(&type, &ad, &v, TYPE_DIRECT);
5486 /* find parameter in function parameter list */
5487 s = func_sym->next;
5488 while (s != NULL) {
5489 if ((s->v & ~SYM_FIELD) == v)
5490 goto found;
5491 s = s->next;
5492 }
5493 tcc_error("declaration for parameter '%s' but no such parameter",
5494 get_tok_str(v, NULL));
5495 found:
5496 /* check that no storage specifier except 'register' was given */
5497 if (type.t & VT_STORAGE)
5498 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
5499 convert_parameter_type(&type);
5500 /* we can add the type (NOTE: it could be local to the function) */
5501 s->type = type;
5502 /* accept other parameters */
5503 if (tok == ',')
5504 next();
5505 else
5506 break;
5507 }
5508 }
5509 skip(';');
5510 }
5511}
5512
5513/* parse a function defined by symbol 'sym' and generate its code in
5514 'cur_text_section' */
5515static void gen_function(Sym *sym)
5516{
5517 int saved_nocode_wanted = nocode_wanted;
5518 nocode_wanted = 0;
5519 ind = cur_text_section->data_offset;
5520 /* NOTE: we patch the symbol size later */
5521 put_extern_sym(sym, cur_text_section, ind, 0);
5522 funcname = get_tok_str(sym->v, NULL);
5523 func_ind = ind;
5524 /* put debug symbol */
5525 if (tcc_state->do_debug)
5526 put_func_debug(sym);
5527 /* push a dummy symbol to enable local sym storage */
5528 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5529 gfunc_prolog(&sym->type);
5530 rsym = 0;
5531 block(NULL, NULL, NULL, NULL, 0, 0);
5532 gsym(rsym);
5533 gfunc_epilog();
5534 cur_text_section->data_offset = ind;
5535 label_pop(&global_label_stack, NULL);
5536 /* reset local stack */
5537 scope_stack_bottom = NULL;
5538 sym_pop(&local_stack, NULL);
5539 /* end of function */
5540 /* patch symbol size */
5541 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5542 ind - func_ind;
5543 /* patch symbol weakness (this definition overrules any prototype) */
5544 if (sym->type.t & VT_WEAK)
5545 weaken_symbol(sym);
5546 if (tcc_state->do_debug) {
5547 put_stabn(N_FUN, 0, 0, ind - func_ind);
5548 }
5549 /* It's better to crash than to generate wrong code */
5550 cur_text_section = NULL;
5551 funcname = ""; /* for safety */
5552 func_vt.t = VT_VOID; /* for safety */
5553 ind = 0; /* for safety */
5554 nocode_wanted = saved_nocode_wanted;
5555}
5556
5557ST_FUNC void gen_inline_functions(void)
5558{
5559 Sym *sym;
5560 int *str, inline_generated, i;
5561 struct InlineFunc *fn;
5562
5563 /* iterate while inline function are referenced */
5564 for(;;) {
5565 inline_generated = 0;
5566 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5567 fn = tcc_state->inline_fns[i];
5568 sym = fn->sym;
5569 if (sym && sym->c) {
5570 /* the function was used: generate its code and
5571 convert it to a normal function */
5572 str = fn->token_str;
5573 fn->sym = NULL;
5574 if (file)
5575 pstrcpy(file->filename, sizeof file->filename, fn->filename);
5576 sym->r = VT_SYM | VT_CONST;
5577 sym->type.t &= ~VT_INLINE;
5578
5579 macro_ptr = str;
5580 next();
5581 cur_text_section = text_section;
5582 gen_function(sym);
5583 macro_ptr = NULL; /* fail safe */
5584
5585 inline_generated = 1;
5586 }
5587 }
5588 if (!inline_generated)
5589 break;
5590 }
5591 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5592 fn = tcc_state->inline_fns[i];
5593 str = fn->token_str;
5594 tok_str_free(str);
5595 }
5596 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5597}
5598
5599/* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5600static int decl0(int l, int is_for_loop_init)
5601{
5602 int v, has_init, r;
5603 CType type, btype;
5604 Sym *sym;
5605 AttributeDef ad;
5606
5607 while (1) {
5608 if (!parse_btype(&btype, &ad)) {
5609 if (is_for_loop_init)
5610 return 0;
5611 /* skip redundant ';' */
5612 /* XXX: find more elegant solution */
5613 if (tok == ';') {
5614 next();
5615 continue;
5616 }
5617 if (l == VT_CONST &&
5618 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5619 /* global asm block */
5620 asm_global_instr();
5621 continue;
5622 }
5623 /* special test for old K&R protos without explicit int
5624 type. Only accepted when defining global data */
5625 if (l == VT_LOCAL || tok < TOK_DEFINE)
5626 break;
5627 btype.t = VT_INT;
5628 }
5629 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5630 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5631 tok == ';') {
5632 /* we accept no variable after */
5633 next();
5634 continue;
5635 }
5636 while (1) { /* iterate thru each declaration */
5637 char *asm_label; // associated asm label
5638 type = btype;
5639 type_decl(&type, &ad, &v, TYPE_DIRECT);
5640#if 0
5641 {
5642 char buf[500];
5643 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5644 printf("type = '%s'\n", buf);
5645 }
5646#endif
5647 if ((type.t & VT_BTYPE) == VT_FUNC) {
5648 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
5649 tcc_error("function without file scope cannot be static");
5650 }
5651 /* if old style function prototype, we accept a
5652 declaration list */
5653 sym = type.ref;
5654 if (sym->c == FUNC_OLD)
5655 func_decl_list(sym);
5656 }
5657
5658 asm_label = NULL;
5659 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5660 CString astr;
5661
5662 asm_label_instr(&astr);
5663 asm_label = tcc_strdup(astr.data);
5664 cstr_free(&astr);
5665
5666 /* parse one last attribute list, after asm label */
5667 parse_attribute(&ad);
5668 }
5669
5670 if (ad.weak)
5671 type.t |= VT_WEAK;
5672#ifdef TCC_TARGET_PE
5673 if (ad.func_import)
5674 type.t |= VT_IMPORT;
5675 if (ad.func_export)
5676 type.t |= VT_EXPORT;
5677#endif
5678 if (tok == '{') {
5679 if (l == VT_LOCAL)
5680 tcc_error("cannot use local functions");
5681 if ((type.t & VT_BTYPE) != VT_FUNC)
5682 expect("function definition");
5683
5684 /* reject abstract declarators in function definition */
5685 sym = type.ref;
5686 while ((sym = sym->next) != NULL)
5687 if (!(sym->v & ~SYM_FIELD))
5688 expect("identifier");
5689
5690 /* XXX: cannot do better now: convert extern line to static inline */
5691 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5692 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5693
5694 sym = sym_find(v);
5695 if (sym) {
5696 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5697 goto func_error1;
5698
5699 r = sym->type.ref->r;
5700 /* use func_call from prototype if not defined */
5701 if (FUNC_CALL(r) != FUNC_CDECL
5702 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5703 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5704
5705 /* use export from prototype */
5706 if (FUNC_EXPORT(r))
5707 FUNC_EXPORT(type.ref->r) = 1;
5708
5709 /* use static from prototype */
5710 if (sym->type.t & VT_STATIC)
5711 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5712
5713 if (!is_compatible_types(&sym->type, &type)) {
5714 func_error1:
5715 tcc_error("incompatible types for redefinition of '%s'",
5716 get_tok_str(v, NULL));
5717 }
5718 /* if symbol is already defined, then put complete type */
5719 sym->type = type;
5720 } else {
5721 /* put function symbol */
5722 sym = global_identifier_push(v, type.t, 0);
5723 sym->type.ref = type.ref;
5724 }
5725
5726 /* static inline functions are just recorded as a kind
5727 of macro. Their code will be emitted at the end of
5728 the compilation unit only if they are used */
5729 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5730 (VT_INLINE | VT_STATIC)) {
5731 TokenString func_str;
5732 int block_level;
5733 struct InlineFunc *fn;
5734 const char *filename;
5735
5736 tok_str_new(&func_str);
5737
5738 block_level = 0;
5739 for(;;) {
5740 int t;
5741 if (tok == TOK_EOF)
5742 tcc_error("unexpected end of file");
5743 tok_str_add_tok(&func_str);
5744 t = tok;
5745 next();
5746 if (t == '{') {
5747 block_level++;
5748 } else if (t == '}') {
5749 block_level--;
5750 if (block_level == 0)
5751 break;
5752 }
5753 }
5754 tok_str_add(&func_str, -1);
5755 tok_str_add(&func_str, 0);
5756 filename = file ? file->filename : "";
5757 fn = tcc_malloc(sizeof *fn + strlen(filename));
5758 strcpy(fn->filename, filename);
5759 fn->sym = sym;
5760 fn->token_str = func_str.str;
5761 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5762
5763 } else {
5764 /* compute text section */
5765 cur_text_section = ad.section;
5766 if (!cur_text_section)
5767 cur_text_section = text_section;
5768 sym->r = VT_SYM | VT_CONST;
5769 gen_function(sym);
5770 }
5771 break;
5772 } else {
5773 if (btype.t & VT_TYPEDEF) {
5774 /* save typedefed type */
5775 /* XXX: test storage specifiers ? */
5776 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5777 sym->type.t |= VT_TYPEDEF;
5778 } else {
5779 r = 0;
5780 if ((type.t & VT_BTYPE) == VT_FUNC) {
5781 /* external function definition */
5782 /* specific case for func_call attribute */
5783 type.ref->r = INT_ATTR(&ad);
5784 } else if (!(type.t & VT_ARRAY)) {
5785 /* not lvalue if array */
5786 r |= lvalue_type(type.t);
5787 }
5788 has_init = (tok == '=');
5789 if (has_init && (type.t & VT_VLA))
5790 tcc_error("Variable length array cannot be initialized");
5791 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
5792 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5793 !has_init && l == VT_CONST && type.ref->c < 0)) {
5794 /* external variable or function */
5795 /* NOTE: as GCC, uninitialized global static
5796 arrays of null size are considered as
5797 extern */
5798 sym = external_sym(v, &type, r, asm_label);
5799
5800 if (type.t & VT_WEAK)
5801 weaken_symbol(sym);
5802
5803 if (ad.alias_target) {
5804 Section tsec;
5805 Elf32_Sym *esym;
5806 Sym *alias_target;
5807
5808 alias_target = sym_find(ad.alias_target);
5809 if (!alias_target || !alias_target->c)
5810 tcc_error("unsupported forward __alias__ attribute");
5811 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
5812 tsec.sh_num = esym->st_shndx;
5813 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
5814 }
5815 } else {
5816 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5817 if (type.t & VT_STATIC)
5818 r |= VT_CONST;
5819 else
5820 r |= l;
5821 if (has_init)
5822 next();
5823 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
5824 }
5825 }
5826 if (tok != ',') {
5827 if (is_for_loop_init)
5828 return 1;
5829 skip(';');
5830 break;
5831 }
5832 next();
5833 }
5834 ad.aligned = 0;
5835 }
5836 }
5837 return 0;
5838}
5839
5840ST_FUNC void decl(int l)
5841{
5842 decl0(l, 0);
5843}
Note: See TracBrowser for help on using the repository browser.