~ubuntu-branches/ubuntu/wily/tcc/wily

« back to all changes in this revision

Viewing changes to .pc/0006-get_reg-try-to-free-r2-for-an-SValue-first.patch/tccgen.c

  • Committer: Package Import Robot
  • Author(s): Thomas Preud'homme, Paul Tagliamonte, Thomas Preud'homme
  • Date: 2012-07-21 03:43:35 UTC
  • mfrom: (17.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20120721034335-xxowewxahdkdlb4m
Tags: 0.9.26~git20120612.ad5f375-6
[Paul Tagliamonte]
  * Uploading Tom's fixes on his behalf. Although he's signed this upload
    (he issued a debdiff), I've prepared this upload. Fix verified on
    i386.

[Thomas Preud'homme]
  * debian/patches:
    + Fix incorrect reading of long long values on architecture with 32bits
      registers like i386 and armel (Closes: #681281).

Show diffs side-by-side

added added

removed removed

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