Subversion Repositories Kolibri OS

Rev

Rev 6429 | Details | Compare with Previous | Last modification | View Log | RSS feed

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