OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [lcc/] [src/] [decl.c] - Blame information for rev 106

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 hellwig
#include "c.h"
2
 
3
static char rcsid[] = "$Id: decl.c,v 1.1 2002/08/28 23:12:42 drh Exp $";
4
 
5
#define add(x,n) (x > inttype->u.sym->u.limits.max.i-(n) ? (overflow=1,x) : x+(n))
6
#define chkoverflow(x,n) ((void)add(x,n))
7
#define bits2bytes(n) (((n) + 7)/8)
8
static int regcount;
9
 
10
static List autos, registers;
11
Symbol cfunc;           /* current function */
12
Symbol retv;            /* return value location for structs */
13
 
14
static void checkref(Symbol, void *);
15
static Symbol dclglobal(int, char *, Type, Coordinate *);
16
static Symbol dcllocal(int, char *, Type, Coordinate *);
17
static Symbol dclparam(int, char *, Type, Coordinate *);
18
static Type dclr(Type, char **, Symbol **, int);
19
static Type dclr1(char **, Symbol **, int);
20
static void decl(Symbol (*)(int, char *, Type, Coordinate *));
21
extern void doconst(Symbol, void *);
22
static void doglobal(Symbol, void *);
23
static void doextern(Symbol, void *);
24
static void exitparams(Symbol []);
25
static void fields(Type);
26
static void funcdefn(int, char *, Type, Symbol [], Coordinate);
27
static void initglobal(Symbol, int);
28
static void oldparam(Symbol, void *);
29
static Symbol *parameters(Type);
30
static Type specifier(int *);
31
static Type structdcl(int);
32
static Type tnode(int, Type);
33
void program(void) {
34
        int n;
35
 
36
        level = GLOBAL;
37
        for (n = 0; t != EOI; n++)
38
                if (kind[t] == CHAR || kind[t] == STATIC
39
                || t == ID || t == '*' || t == '(') {
40
                        decl(dclglobal);
41
                        deallocate(STMT);
42
                        if (!(glevel >= 3 || xref))
43
                        deallocate(FUNC);
44
                } else if (t == ';') {
45
                        warning("empty declaration\n");
46
                        t = gettok();
47
                } else {
48
                        error("unrecognized declaration\n");
49
                        t = gettok();
50
                }
51
        if (n == 0)
52
                warning("empty input file\n");
53
}
54
static Type specifier(int *sclass) {
55
        int cls, cons, sign, size, type, vol;
56
        Type ty = NULL;
57
 
58
        cls = vol = cons = sign = size = type = 0;
59
        if (sclass == NULL)
60
                cls = AUTO;
61
        for (;;) {
62
                int *p, tt = t;
63
                switch (t) {
64
                case AUTO:
65
                case REGISTER: if (level <= GLOBAL && cls == 0)
66
                                error("invalid use of `%k'\n", t);
67
                               p = &cls;  t = gettok();      break;
68
                case STATIC: case EXTERN:
69
                case TYPEDEF:  p = &cls;  t = gettok();      break;
70
                case CONST:    p = &cons; t = gettok();      break;
71
                case VOLATILE: p = &vol;  t = gettok();      break;
72
                case SIGNED:
73
                case UNSIGNED: p = &sign; t = gettok();      break;
74
                case LONG:     if (size == LONG) {
75
                                       size = 0;
76
                                       tt = LONG+LONG;
77
                               }
78
                               p = &size; t = gettok();      break;
79
                case SHORT:    p = &size; t = gettok();      break;
80
                case VOID: case CHAR: case INT: case FLOAT:
81
                case DOUBLE:   p = &type; ty = tsym->type;
82
                                          t = gettok();      break;
83
                case ENUM:     p = &type; ty = enumdcl();    break;
84
                case STRUCT:
85
                case UNION:    p = &type; ty = structdcl(t); break;
86
                case ID:
87
                        if (istypename(t, tsym) && type == 0
88
                        && sign == 0 && size == 0) {
89
                                use(tsym, src);
90
                                ty = tsym->type;
91
                                if (isqual(ty)
92
                                && ty->size != ty->type->size) {
93
                                        ty = unqual(ty);
94
                                        if (isconst(tsym->type))
95
                                                ty = qual(CONST, ty);
96
                                        if (isvolatile(tsym->type))
97
                                                ty = qual(VOLATILE, ty);
98
                                        tsym->type = ty;
99
                                }
100
                                p = &type;
101
                                t = gettok();
102
                        } else
103
                                p = NULL;
104
                        break;
105
                default: p = NULL;
106
                }
107
                if (p == NULL)
108
                        break;
109
                if (*p)
110
                        error("invalid use of `%k'\n", tt);
111
                *p = tt;
112
        }
113
        if (sclass)
114
                *sclass = cls;
115
        if (type == 0) {
116
                type = INT;
117
                ty = inttype;
118
        }
119
        if (size == SHORT     && type != INT
120
        ||  size == LONG+LONG && type != INT
121
        ||  size == LONG      && type != INT && type != DOUBLE
122
        ||  sign && type != INT && type != CHAR)
123
                error("invalid type specification\n");
124
        if (type == CHAR && sign)
125
                ty = sign == UNSIGNED ? unsignedchar : signedchar;
126
        else if (size == SHORT)
127
                ty = sign == UNSIGNED ? unsignedshort : shorttype;
128
        else if (size == LONG && type == DOUBLE)
129
                ty = longdouble;
130
        else if (size == LONG+LONG) {
131
                ty = sign == UNSIGNED ? unsignedlonglong : longlong;
132
                if (Aflag >= 1)
133
                        warning("`%t' is a non-ANSI type\n", ty);
134
        } else if (size == LONG)
135
                ty = sign == UNSIGNED ? unsignedlong : longtype;
136
        else if (sign == UNSIGNED && type == INT)
137
                ty = unsignedtype;
138
        if (cons == CONST)
139
                ty = qual(CONST, ty);
140
        if (vol  == VOLATILE)
141
                ty = qual(VOLATILE, ty);
142
        return ty;
143
}
144
static void decl(Symbol (*dcl)(int, char *, Type, Coordinate *)) {
145
        int sclass;
146
        Type ty, ty1;
147
        static char stop[] = { CHAR, STATIC, ID, 0 };
148
 
149
        ty = specifier(&sclass);
150
        if (t == ID || t == '*' || t == '(' || t == '[') {
151
                char *id;
152
                Coordinate pos;
153
                id = NULL;
154
                pos = src;
155
                if (level == GLOBAL) {
156
                        Symbol *params = NULL;
157
                        ty1 = dclr(ty, &id, &params, 0);
158
                        if (params && id && isfunc(ty1)
159
                            && (t == '{' || istypename(t, tsym)
160
                            || (kind[t] == STATIC && t != TYPEDEF))) {
161
                                if (sclass == TYPEDEF) {
162
                                        error("invalid use of `typedef'\n");
163
                                        sclass = EXTERN;
164
                                }
165
                                if (ty1->u.f.oldstyle)
166
                                        exitscope();
167
                                funcdefn(sclass, id, ty1, params, pos);
168
                                return;
169
                        } else if (params)
170
                                exitparams(params);
171
                } else
172
                        ty1 = dclr(ty, &id, NULL, 0);
173
                for (;;) {
174
                        if (Aflag >= 1 && !hasproto(ty1))
175
                                warning("missing prototype\n");
176
                        if (id == NULL)
177
                                error("missing identifier\n");
178
                        else if (sclass == TYPEDEF)
179
                                {
180
                                        Symbol p = lookup(id, identifiers);
181
                                        if (p && p->scope == level)
182
                                                error("redeclaration of `%s'\n", id);
183
                                        p = install(id, &identifiers, level,
184
                                                level < LOCAL ? PERM : FUNC);
185
                                        p->type = ty1;
186
                                        p->sclass = TYPEDEF;
187
                                        p->src = pos;
188
                                }
189
                        else
190
                                (void)(*dcl)(sclass, id, ty1, &pos);
191
                        if (t != ',')
192
                                break;
193
                        t = gettok();
194
                        id = NULL;
195
                        pos = src;
196
                        ty1 = dclr(ty, &id, NULL, 0);
197
                }
198
        } else if (ty == NULL
199
        || !(isenum(ty) ||
200
             isstruct(ty) && (*unqual(ty)->u.sym->name < '1' || *unqual(ty)->u.sym->name > '9')))
201
                error("empty declaration\n");
202
        test(';', stop);
203
}
204
static Symbol dclglobal(int sclass, char *id, Type ty, Coordinate *pos) {
205
        Symbol p;
206
 
207
        if (sclass == 0)
208
                sclass = AUTO;
209
        else if (sclass != EXTERN && sclass != STATIC) {
210
                error("invalid storage class `%k' for `%t %s'\n",
211
                        sclass, ty, id);
212
                sclass = AUTO;
213
        }
214
        p = lookup(id, identifiers);
215
        if (p && p->scope == GLOBAL) {
216
                if (p->sclass != TYPEDEF && eqtype(ty, p->type, 1))
217
                        ty = compose(ty, p->type);
218
                else
219
                        error("redeclaration of `%s' previously declared at %w\n", p->name, &p->src);
220
 
221
                if (!isfunc(ty) && p->defined && t == '=')
222
                        error("redefinition of `%s' previously defined at %w\n", p->name, &p->src);
223
 
224
                if (p->sclass == EXTERN && sclass == STATIC
225
                ||  p->sclass == STATIC && sclass == AUTO
226
                ||  p->sclass == AUTO   && sclass == STATIC)
227
                        warning("inconsistent linkage for `%s' previously declared at %w\n", p->name, &p->src);
228
 
229
        }
230
        if (p == NULL || p->scope != GLOBAL) {
231
                Symbol q = lookup(id, externals);
232
                if (q) {
233
                        if (sclass == STATIC || !eqtype(ty, q->type, 1))
234
                                warning("declaration of `%s' does not match previous declaration at %w\n", id, &q->src);
235
 
236
                        p = relocate(id, externals, globals);
237
                        p->sclass = sclass;
238
                } else {
239
                        p = install(id, &globals, GLOBAL, PERM);
240
                        p->sclass = sclass;
241
                        (*IR->defsymbol)(p);
242
                }
243
                if (p->sclass != STATIC) {
244
                        static int nglobals;
245
                        nglobals++;
246
                        if (Aflag >= 2 && nglobals == 512)
247
                                warning("more than 511 external identifiers\n");
248
                }
249
        } else if (p->sclass == EXTERN)
250
                p->sclass = sclass;
251
        p->type = ty;
252
        p->src = *pos;
253
        if (t == '=' && isfunc(p->type)) {
254
                error("illegal initialization for `%s'\n", p->name);
255
                t = gettok();
256
                initializer(p->type, 0);
257
        } else if (t == '=') {
258
                initglobal(p, 0);
259
                if (glevel > 0 && IR->stabsym) {
260
                        (*IR->stabsym)(p); swtoseg(p->u.seg); }
261
        } else if (p->sclass == STATIC && !isfunc(p->type)
262
        && p->type->size == 0)
263
                error("undefined size for `%t %s'\n", p->type, p->name);
264
        return p;
265
}
266
static void initglobal(Symbol p, int flag) {
267
        Type ty;
268
 
269
        if (t == '=' || flag) {
270
                if (p->sclass == STATIC) {
271
                        for (ty = p->type; isarray(ty); ty = ty->type)
272
                                ;
273
                        defglobal(p, isconst(ty) ? LIT : DATA);
274
                } else
275
                        defglobal(p, DATA);
276
                if (t == '=')
277
                        t = gettok();
278
                ty = initializer(p->type, 0);
279
                if (isarray(p->type) && p->type->size == 0)
280
                        p->type = ty;
281
                if (p->sclass == EXTERN)
282
                        p->sclass = AUTO;
283
        }
284
}
285
void defglobal(Symbol p, int seg) {
286
        p->u.seg = seg;
287
        swtoseg(p->u.seg);
288
        if (p->sclass != STATIC)
289
                (*IR->export)(p);
290
        (*IR->global)(p);
291
        p->defined = 1;
292
}
293
 
294
static Type dclr(Type basety, char **id, Symbol **params, int abstract) {
295
        Type ty = dclr1(id, params, abstract);
296
 
297
        for ( ; ty; ty = ty->type)
298
                switch (ty->op) {
299
                case POINTER:
300
                        basety = ptr(basety);
301
                        break;
302
                case FUNCTION:
303
                        basety = func(basety, ty->u.f.proto,
304
                                ty->u.f.oldstyle);
305
                        break;
306
                case ARRAY:
307
                        basety = array(basety, ty->size, 0);
308
                        break;
309
                case CONST: case VOLATILE:
310
                        basety = qual(ty->op, basety);
311
                        break;
312
                default: assert(0);
313
                }
314
        if (Aflag >= 2 && basety->size > 32767)
315
                warning("more than 32767 bytes in `%t'\n", basety);
316
        return basety;
317
}
318
static Type tnode(int op, Type type) {
319
        Type ty;
320
 
321
        NEW0(ty, STMT);
322
        ty->op = op;
323
        ty->type = type;
324
        return ty;
325
}
326
static Type dclr1(char **id, Symbol **params, int abstract) {
327
        Type ty = NULL;
328
 
329
        switch (t) {
330
        case ID:                if (id)
331
                                        *id = token;
332
                                else
333
                                        error("extraneous identifier `%s'\n", token);
334
                                t = gettok(); break;
335
        case '*': t = gettok(); if (t == CONST || t == VOLATILE) {
336
                                        Type ty1;
337
                                        ty1 = ty = tnode(t, NULL);
338
                                        while ((t = gettok()) == CONST || t == VOLATILE)
339
                                                ty1 = tnode(t, ty1);
340
                                        ty->type = dclr1(id, params, abstract);
341
                                        ty = ty1;
342
                                } else
343
                                        ty = dclr1(id, params, abstract);
344
                                ty = tnode(POINTER, ty); break;
345
        case '(': t = gettok(); if (abstract
346
                                && (t == REGISTER || istypename(t, tsym) || t == ')')) {
347
                                        Symbol *args;
348
                                        ty = tnode(FUNCTION, ty);
349
                                        enterscope();
350
                                        if (level > PARAM)
351
                                                enterscope();
352
                                        args = parameters(ty);
353
                                        exitparams(args);
354
                                } else {
355
                                        ty = dclr1(id, params, abstract);
356
                                        expect(')');
357
                                        if (abstract && ty == NULL
358
                                        && (id == NULL || *id == NULL))
359
                                                return tnode(FUNCTION, NULL);
360
                                } break;
361
        case '[': break;
362
        default:  return ty;
363
        }
364
        while (t == '(' || t == '[')
365
                switch (t) {
366
                case '(': t = gettok(); { Symbol *args;
367
                                          ty = tnode(FUNCTION, ty);
368
                                          enterscope();
369
                                          if (level > PARAM)
370
                                                enterscope();
371
                                          args = parameters(ty);
372
                                          if (params && *params == NULL)
373
                                                *params = args;
374
                                          else
375
                                                exitparams(args);
376
 }
377
                          break;
378
                case '[': t = gettok(); { int n = 0;
379
                                          if (kind[t] == ID) {
380
                                                n = intexpr(']', 1);
381
                                                if (n <= 0) {
382
                                                        error("`%d' is an illegal array size\n", n);
383
                                                        n = 1;
384
                                                }
385
                                          } else
386
                                                expect(']');
387
                                          ty = tnode(ARRAY, ty);
388
                                          ty->size = n; } break;
389
                default: assert(0);
390
                }
391
        return ty;
392
}
393
static Symbol *parameters(Type fty) {
394
        List list = NULL;
395
        Symbol *params;
396
 
397
        if (kind[t] == STATIC || istypename(t, tsym)) {
398
                int n = 0;
399
                Type ty1 = NULL;
400
                for (;;) {
401
                        Type ty;
402
                        int sclass = 0;
403
                        char *id = NULL;
404
                        if (ty1 && t == ELLIPSIS) {
405
                                static struct symbol sentinel;
406
                                if (sentinel.type == NULL) {
407
                                        sentinel.type = voidtype;
408
                                        sentinel.defined = 1;
409
                                }
410
                                if (ty1 == voidtype)
411
                                        error("illegal formal parameter types\n");
412
                                list = append(&sentinel, list);
413
                                t = gettok();
414
                                break;
415
                        }
416
                        if (!istypename(t, tsym) && t != REGISTER)
417
                                error("missing parameter type\n");
418
                        n++;
419
                        ty = dclr(specifier(&sclass), &id, NULL, 1);
420
                        if ( ty == voidtype && (ty1 || id)
421
                        ||  ty1 == voidtype)
422
                                error("illegal formal parameter types\n");
423
                        if (id == NULL)
424
                                id = stringd(n);
425
                        if (ty != voidtype)
426
                                list = append(dclparam(sclass, id, ty, &src), list);
427
                        if (Aflag >= 1 && !hasproto(ty))
428
                                warning("missing prototype\n");
429
                        if (ty1 == NULL)
430
                                ty1 = ty;
431
                        if (t != ',')
432
                                break;
433
                        t = gettok();
434
                }
435
                fty->u.f.proto = newarray(length(list) + 1,
436
                        sizeof (Type *), PERM);
437
                params = ltov(&list, FUNC);
438
                for (n = 0; params[n]; n++)
439
                        fty->u.f.proto[n] = params[n]->type;
440
                fty->u.f.proto[n] = NULL;
441
                fty->u.f.oldstyle = 0;
442
        } else {
443
                if (t == ID)
444
                        for (;;) {
445
                                Symbol p;
446
                                if (t != ID) {
447
                                        error("expecting an identifier\n");
448
                                        break;
449
                                }
450
                                p = dclparam(0, token, inttype, &src);
451
                                p->defined = 0;
452
                                list = append(p, list);
453
                                t = gettok();
454
                                if (t != ',')
455
                                        break;
456
                                t = gettok();
457
                        }
458
                params = ltov(&list, FUNC);
459
                fty->u.f.proto = NULL;
460
                fty->u.f.oldstyle = 1;
461
        }
462
        if (t != ')') {
463
                static char stop[] = { CHAR, STATIC, IF, ')', 0 };
464
                expect(')');
465
                skipto('{', stop);
466
        }
467
        if (t == ')')
468
                t = gettok();
469
        return params;
470
}
471
static void exitparams(Symbol params[]) {
472
        assert(params);
473
        if (params[0] && !params[0]->defined)
474
                error("extraneous old-style parameter list\n");
475
        if (level > PARAM)
476
                exitscope();
477
        exitscope();
478
}
479
 
480
static Symbol dclparam(int sclass, char *id, Type ty, Coordinate *pos) {
481
        Symbol p;
482
 
483
        if (isfunc(ty))
484
                ty = ptr(ty);
485
        else if (isarray(ty))
486
                ty = atop(ty);
487
        if (sclass == 0)
488
                sclass = AUTO;
489
        else if (sclass != REGISTER) {
490
                error("invalid storage class `%k' for `%t%s\n",
491
                        sclass, ty, stringf(id ? " %s'" : "' parameter", id));
492
                sclass = AUTO;
493
        } else if (isvolatile(ty) || isstruct(ty)) {
494
                warning("register declaration ignored for `%t%s\n",
495
                        ty, stringf(id ? " %s'" : "' parameter", id));
496
                sclass = AUTO;
497
        }
498
 
499
        p = lookup(id, identifiers);
500
        if (p && p->scope == level)
501
                error("duplicate declaration for `%s' previously declared at %w\n", id, &p->src);
502
 
503
        else
504
                p = install(id, &identifiers, level, FUNC);
505
        p->sclass = sclass;
506
        p->src = *pos;
507
        p->type = ty;
508
        p->defined = 1;
509
        if (t == '=') {
510
                error("illegal initialization for parameter `%s'\n", id);
511
                t = gettok();
512
                (void)expr1(0);
513
        }
514
        return p;
515
}
516
static Type structdcl(int op) {
517
        char *tag;
518
        Type ty;
519
        Symbol p;
520
        Coordinate pos;
521
 
522
        t = gettok();
523
        pos = src;
524
        if (t == ID) {
525
                tag = token;
526
                t = gettok();
527
        } else
528
                tag = "";
529
        if (t == '{') {
530
                static char stop[] = { IF, ',', 0 };
531
                ty = newstruct(op, tag);
532
                ty->u.sym->src = pos;
533
                ty->u.sym->defined = 1;
534
                t = gettok();
535
                if (istypename(t, tsym))
536
                        fields(ty);
537
                else
538
                        error("invalid %k field declarations\n", op);
539
                test('}', stop);
540
        }
541
        else if (*tag && (p = lookup(tag, types)) != NULL
542
        && p->type->op == op) {
543
                ty = p->type;
544
                if (t == ';' && p->scope < level)
545
                        ty = newstruct(op, tag);
546
        }
547
        else {
548
                if (*tag == 0)
549
                        error("missing %k tag\n", op);
550
                ty = newstruct(op, tag);
551
        }
552
        if (*tag && xref)
553
                use(ty->u.sym, pos);
554
        return ty;
555
}
556
static void fields(Type ty) {
557
        { int n = 0;
558
          while (istypename(t, tsym)) {
559
                static char stop[] = { IF, CHAR, '}', 0 };
560
                Type ty1 = specifier(NULL);
561
                for (;;) {
562
                        Field p;
563
                        char *id = NULL;
564
                        Type fty = dclr(ty1, &id, NULL, 0);
565
                        p = newfield(id, ty, fty);
566
                        if (Aflag >= 1 && !hasproto(p->type))
567
                                warning("missing prototype\n");
568
                        if (t == ':') {
569
                                if (unqual(p->type) != inttype
570
                                &&  unqual(p->type) != unsignedtype) {
571
                                        error("`%t' is an illegal bit-field type\n",
572
                                                p->type);
573
                                        p->type = inttype;
574
                                }
575
                                t = gettok();
576
                                p->bitsize = intexpr(0, 0);
577
                                if (p->bitsize > 8*inttype->size || p->bitsize < 0) {
578
                                        error("`%d' is an illegal bit-field size\n",
579
                                                p->bitsize);
580
                                        p->bitsize = 8*inttype->size;
581
                                } else if (p->bitsize == 0 && id) {
582
                                        warning("extraneous 0-width bit field `%t %s' ignored\n", p->type, id);
583
 
584
                                        p->name = stringd(genlabel(1));
585
                                }
586
                                p->lsb = 1;
587
                        }
588
                        else {
589
                                if (id == NULL)
590
                                        error("field name missing\n");
591
                                else if (isfunc(p->type))
592
                                        error("`%t' is an illegal field type\n", p->type);
593
                                else if (p->type->size == 0)
594
                                        error("undefined size for field `%t %s'\n",
595
                                                p->type, id);
596
                        }
597
                        if (isconst(p->type))
598
                                ty->u.sym->u.s.cfields = 1;
599
                        if (isvolatile(p->type))
600
                                ty->u.sym->u.s.vfields = 1;
601
                        n++;
602
                        if (Aflag >= 2 && n == 128)
603
                                warning("more than 127 fields in `%t'\n", ty);
604
                        if (t != ',')
605
                                break;
606
                        t = gettok();
607
                }
608
                test(';', stop);
609
          } }
610
        { int bits = 0, off = 0, overflow = 0;
611
          Field p, *q = &ty->u.sym->u.s.flist;
612
          ty->align = IR->structmetric.align;
613
          for (p = *q; p; p = p->link) {
614
                int a = p->type->align ? p->type->align : 1;
615
                if (p->lsb)
616
                        a = unsignedtype->align;
617
                if (ty->op == UNION)
618
                        off = bits = 0;
619
                else if (p->bitsize == 0 || bits == 0
620
                || bits - 1 + p->bitsize > 8*unsignedtype->size) {
621
                        off = add(off, bits2bytes(bits-1));
622
                        bits = 0;
623
                        chkoverflow(off, a - 1);
624
                        off = roundup(off, a);
625
                }
626
                if (a > ty->align)
627
                        ty->align = a;
628
                p->offset = off;
629
 
630
                if (p->lsb) {
631
                        if (bits == 0)
632
                                bits = 1;
633
                        if (IR->little_endian)
634
                                p->lsb = bits;
635
                        else
636
                                p->lsb = 8*unsignedtype->size - bits + 1
637
                                        - p->bitsize + 1;
638
                        bits += p->bitsize;
639
                } else
640
                        off = add(off, p->type->size);
641
                if (off + bits2bytes(bits-1) > ty->size)
642
                        ty->size = off + bits2bytes(bits-1);
643
                if (p->name == NULL
644
                || !('1' <= *p->name && *p->name <= '9')) {
645
                        *q = p;
646
                        q = &p->link;
647
                }
648
          }
649
          *q = NULL;
650
          chkoverflow(ty->size, ty->align - 1);
651
          ty->size = roundup(ty->size, ty->align);
652
          if (overflow) {
653
                error("size of `%t' exceeds %d bytes\n", ty, inttype->u.sym->u.limits.max.i);
654
                ty->size = inttype->u.sym->u.limits.max.i&(~(ty->align - 1));
655
          } }
656
}
657
static void funcdefn(int sclass, char *id, Type ty, Symbol params[], Coordinate pt) {
658
        int i, n;
659
        Symbol *callee, *caller, p;
660
        Type rty = freturn(ty);
661
 
662
        if (isstruct(rty) && rty->size == 0)
663
                error("illegal use of incomplete type `%t'\n", rty);
664
        for (n = 0; params[n]; n++)
665
                ;
666
        if (n > 0 && params[n-1]->name == NULL)
667
                params[--n] = NULL;
668
        if (Aflag >= 2 && n > 31)
669
                warning("more than 31 parameters in function `%s'\n", id);
670
        if (ty->u.f.oldstyle) {
671
                if (Aflag >= 1)
672
                        warning("old-style function definition for `%s'\n", id);
673
                caller = params;
674
                callee = newarray(n + 1, sizeof *callee, FUNC);
675
                memcpy(callee, caller, (n+1)*sizeof *callee);
676
                enterscope();
677
                assert(level == PARAM);
678
                while (kind[t] == STATIC || istypename(t, tsym))
679
                        decl(dclparam);
680
                foreach(identifiers, PARAM, oldparam, callee);
681
 
682
                for (i = 0; (p = callee[i]) != NULL; i++) {
683
                        if (!p->defined)
684
                                callee[i] = dclparam(0, p->name, inttype, &p->src);
685
                        *caller[i] = *p;
686
                        caller[i]->sclass = AUTO;
687
                        caller[i]->type = promote(p->type);
688
                }
689
                p = lookup(id, identifiers);
690
                if (p && p->scope == GLOBAL && isfunc(p->type)
691
                && p->type->u.f.proto) {
692
                        Type *proto = p->type->u.f.proto;
693
                        for (i = 0; caller[i] && proto[i]; i++) {
694
                                Type ty = unqual(proto[i]);
695
                                if (eqtype(isenum(ty) ? ty->type : ty,
696
                                        unqual(caller[i]->type), 1) == 0)
697
                                        break;
698
                                else if (isenum(ty) && !isenum(unqual(caller[i]->type)))
699
                                        warning("compatibility of `%t' and `%t' is compiler dependent\n",
700
                                                proto[i], caller[i]->type);
701
                        }
702
                        if (proto[i] || caller[i])
703
                                error("conflicting argument declarations for function `%s'\n", id);
704
 
705
                }
706
                else {
707
                        Type *proto = newarray(n + 1, sizeof *proto, PERM);
708
                        if (Aflag >= 1)
709
                                warning("missing prototype for `%s'\n", id);
710
                        for (i = 0; i < n; i++)
711
                                proto[i] = caller[i]->type;
712
                        proto[i] = NULL;
713
                        ty = func(rty, proto, 1);
714
                }
715
        } else {
716
                callee = params;
717
                caller = newarray(n + 1, sizeof *caller, FUNC);
718
                for (i = 0; (p = callee[i]) != NULL && p->name; i++) {
719
                        NEW(caller[i], FUNC);
720
                        *caller[i] = *p;
721
                        if (isint(p->type))
722
                                caller[i]->type = promote(p->type);
723
                        caller[i]->sclass = AUTO;
724
                        if ('1' <= *p->name && *p->name <= '9')
725
                                error("missing name for parameter %d to function `%s'\n", i + 1, id);
726
 
727
                }
728
                caller[i] = NULL;
729
        }
730
        for (i = 0; (p = callee[i]) != NULL; i++)
731
                if (p->type->size == 0) {
732
                        error("undefined size for parameter `%t %s'\n",
733
                                p->type, p->name);
734
                        caller[i]->type = p->type = inttype;
735
                }
736
        if (Aflag >= 2 && sclass != STATIC && strcmp(id, "main") == 0) {
737
                if (ty->u.f.oldstyle)
738
                        warning("`%t %s()' is a non-ANSI definition\n", rty, id);
739
                else if (!(rty == inttype
740
                        && (n == 0 && callee[0] == NULL
741
                        ||  n == 2 && callee[0]->type == inttype
742
                        && isptr(callee[1]->type) && callee[1]->type->type == charptype
743
                        && !variadic(ty))))
744
                        warning("`%s' is a non-ANSI definition\n", typestring(ty, id));
745
        }
746
        p = lookup(id, identifiers);
747
        if (p && isfunc(p->type) && p->defined)
748
                error("redefinition of `%s' previously defined at %w\n",
749
                        p->name, &p->src);
750
        cfunc = dclglobal(sclass, id, ty, &pt);
751
        cfunc->u.f.label = genlabel(1);
752
        cfunc->u.f.callee = callee;
753
        cfunc->u.f.pt = src;
754
        cfunc->defined = 1;
755
        if (xref)
756
                use(cfunc, cfunc->src);
757
        if (Pflag)
758
                printproto(cfunc, cfunc->u.f.callee);
759
        if (ncalled >= 0)
760
                ncalled = findfunc(cfunc->name, pt.file);
761
        labels   = table(NULL, LABELS);
762
        stmtlabs = table(NULL, LABELS);
763
        refinc = 1.0;
764
        regcount = 0;
765
        codelist = &codehead;
766
        codelist->next = NULL;
767
        if (!IR->wants_callb && isstruct(rty))
768
                retv = genident(AUTO, ptr(unqual(rty)), PARAM);
769
        compound(0, NULL, 0);
770
 
771
        definelab(cfunc->u.f.label);
772
        if (events.exit)
773
                apply(events.exit, cfunc, NULL);
774
        walk(NULL, 0, 0);
775
        exitscope();
776
        assert(level == PARAM);
777
        foreach(identifiers, level, checkref, NULL);
778
        if (!IR->wants_callb && isstruct(rty)) {
779
                Symbol *a;
780
                a = newarray(n + 2, sizeof *a, FUNC);
781
                a[0] = retv;
782
                memcpy(&a[1], callee, (n+1)*sizeof *callee);
783
                callee = a;
784
                a = newarray(n + 2, sizeof *a, FUNC);
785
                NEW(a[0], FUNC);
786
                *a[0] = *retv;
787
                memcpy(&a[1], caller, (n+1)*sizeof *callee);
788
                caller = a;
789
        }
790
        if (!IR->wants_argb)
791
                for (i = 0; caller[i]; i++)
792
                        if (isstruct(caller[i]->type)) {
793
                                caller[i]->type = ptr(caller[i]->type);
794
                                callee[i]->type = ptr(callee[i]->type);
795
                                caller[i]->structarg = callee[i]->structarg = 1;
796
                        }
797
        if (glevel > 1) for (i = 0; callee[i]; i++) callee[i]->sclass = AUTO;
798
        if (cfunc->sclass != STATIC)
799
                (*IR->export)(cfunc);
800
        if (glevel && IR->stabsym) {
801
                swtoseg(CODE); (*IR->stabsym)(cfunc); }
802
        swtoseg(CODE);
803
        (*IR->function)(cfunc, caller, callee, cfunc->u.f.ncalls);
804
        if (glevel && IR->stabfend)
805
                (*IR->stabfend)(cfunc, lineno);
806
        foreach(stmtlabs, LABELS, checklab, NULL);
807
        exitscope();
808
        expect('}');
809
        labels = stmtlabs = NULL;
810
        retv  = NULL;
811
        cfunc = NULL;
812
}
813
static void oldparam(Symbol p, void *cl) {
814
        int i;
815
        Symbol *callee = cl;
816
 
817
        for (i = 0; callee[i]; i++)
818
                if (p->name == callee[i]->name) {
819
                        callee[i] = p;
820
                        return;
821
                }
822
        error("declared parameter `%s' is missing\n", p->name);
823
}
824
void compound(int loop, struct swtch *swp, int lev) {
825
        Code cp;
826
        int nregs;
827
 
828
        walk(NULL, 0, 0);
829
        cp = code(Blockbeg);
830
        enterscope();
831
        assert(level >= LOCAL);
832
        if (level == LOCAL && events.entry)
833
                apply(events.entry, cfunc, NULL);
834
        definept(NULL);
835
        expect('{');
836
        autos = registers = NULL;
837
        if (level == LOCAL && IR->wants_callb
838
        && isstruct(freturn(cfunc->type))) {
839
                retv = genident(AUTO, ptr(unqual(freturn(cfunc->type))), level);
840
                retv->defined = 1;
841
                retv->ref = 1;
842
                registers = append(retv, registers);
843
        }
844
        while (kind[t] == CHAR || kind[t] == STATIC
845
        || istypename(t, tsym) && getchr() != ':')
846
                decl(dcllocal);
847
        {
848
                int i;
849
                Symbol *a = ltov(&autos, STMT);
850
                nregs = length(registers);
851
                for (i = 0; a[i]; i++)
852
                        registers = append(a[i], registers);
853
                cp->u.block.locals = ltov(&registers, FUNC);
854
        }
855
        if (events.blockentry)
856
                apply(events.blockentry, cp->u.block.locals, NULL);
857
        while (kind[t] == IF || kind[t] == ID)
858
                statement(loop, swp, lev);
859
        walk(NULL, 0, 0);
860
        foreach(identifiers, level, checkref, NULL);
861
        {
862
                int i = nregs, j;
863
                Symbol p;
864
                for ( ; (p = cp->u.block.locals[i]) != NULL; i++) {
865
                        for (j = i; j > nregs
866
                                && cp->u.block.locals[j-1]->ref < p->ref; j--)
867
                                cp->u.block.locals[j] = cp->u.block.locals[j-1];
868
                        cp->u.block.locals[j] = p;
869
                }
870
        }
871
        if (level == LOCAL) {
872
                Code cp;
873
                for (cp = codelist; cp->kind < Label; cp = cp->prev)
874
                        ;
875
                if (cp->kind != Jump) {
876
                        if (freturn(cfunc->type) != voidtype) {
877
                                warning("missing return value\n");
878
                                retcode(cnsttree(inttype, 0L));
879
                        } else
880
                                retcode(NULL);
881
                }
882
        }
883
        if (events.blockexit)
884
                apply(events.blockexit, cp->u.block.locals, NULL);
885
        cp->u.block.level = level;
886
        cp->u.block.identifiers = identifiers;
887
        cp->u.block.types = types;
888
        code(Blockend)->u.begin = cp;
889
        if (reachable(Gen))
890
                definept(NULL);
891
        if (level > LOCAL) {
892
                exitscope();
893
                expect('}');
894
        }
895
}
896
static void checkref(Symbol p, void *cl) {
897
        if (p->scope >= PARAM
898
        && (isvolatile(p->type) || isfunc(p->type)))
899
                p->addressed = 1;
900
        if (Aflag >= 2 && p->defined && p->ref == 0) {
901
                if (p->sclass == STATIC)
902
                        warning("static `%t %s' is not referenced\n",
903
                                p->type, p->name);
904
                else if (p->scope == PARAM)
905
                        warning("parameter `%t %s' is not referenced\n",
906
                                p->type, p->name);
907
                else if (p->scope >= LOCAL && p->sclass != EXTERN)
908
                        warning("local `%t %s' is not referenced\n",
909
                                p->type, p->name);
910
        }
911
        if (p->sclass == AUTO
912
        && (p->scope  == PARAM && regcount == 0
913
         || p->scope  >= LOCAL)
914
        && !p->addressed && isscalar(p->type) && p->ref >= 3.0)
915
                p->sclass = REGISTER;
916
        if (level == GLOBAL && p->sclass == STATIC && !p->defined
917
        && isfunc(p->type) && p->ref)
918
                error("undefined static `%t %s'\n", p->type, p->name);
919
        assert(!(level == GLOBAL && p->sclass == STATIC && !p->defined && !isfunc(p->type)));
920
}
921
static Symbol dcllocal(int sclass, char *id, Type ty, Coordinate *pos) {
922
        Symbol p, q;
923
 
924
        if (sclass == 0)
925
                sclass = isfunc(ty) ? EXTERN : AUTO;
926
        else if (isfunc(ty) && sclass != EXTERN) {
927
                error("invalid storage class `%k' for `%t %s'\n",
928
                        sclass, ty, id);
929
                sclass = EXTERN;
930
        } else if (sclass == REGISTER
931
        && (isvolatile(ty) || isstruct(ty) || isarray(ty))) {
932
                warning("register declaration ignored for `%t %s'\n",
933
                        ty, id);
934
                sclass = AUTO;
935
        }
936
        q = lookup(id, identifiers);
937
        if (q && q->scope >= level
938
        ||  q && q->scope == PARAM && level == LOCAL)
939
                if (sclass == EXTERN && q->sclass == EXTERN
940
                && eqtype(q->type, ty, 1))
941
                        ty = compose(ty, q->type);
942
                else
943
                        error("redeclaration of `%s' previously declared at %w\n", q->name, &q->src);
944
 
945
        assert(level >= LOCAL);
946
        p = install(id, &identifiers, level, sclass == STATIC || sclass == EXTERN ? PERM : FUNC);
947
        p->type = ty;
948
        p->sclass = sclass;
949
        p->src = *pos;
950
        switch (sclass) {
951
        case EXTERN:   q = lookup(id, globals);
952
                       if (q == NULL || q->sclass == TYPEDEF || q->sclass == ENUM) {
953
                        q = lookup(id, externals);
954
                        if (q == NULL) {
955
                                q = install(p->name, &externals, GLOBAL, PERM);
956
                                q->type = p->type;
957
                                q->sclass = EXTERN;
958
                                q->src = src;
959
                                (*IR->defsymbol)(q);
960
                        }
961
                       }
962
                       if (!eqtype(p->type, q->type, 1))
963
                        warning("declaration of `%s' does not match previous declaration at %w\n", q->name, &q->src);
964
 
965
                       p->u.alias = q; break;
966
        case STATIC:   (*IR->defsymbol)(p);
967
                       initglobal(p, 0);
968
                       if (!p->defined)
969
                        if (p->type->size > 0) {
970
                                defglobal(p, BSS);
971
                                (*IR->space)(p->type->size);
972
                        } else
973
                                error("undefined size for `%t %s'\n",
974
                                        p->type, p->name);
975
                       p->defined = 1; break;
976
        case REGISTER: registers = append(p, registers);
977
                       regcount++;
978
                       p->defined = 1;
979
 break;
980
        case AUTO:     autos = append(p, autos);
981
                       p->defined = 1;
982
                       if (isarray(ty))
983
                        p->addressed = 1; break;
984
        default: assert(0);
985
        }
986
        if (t == '=') {
987
                Tree e;
988
                if (sclass == EXTERN)
989
                        error("illegal initialization of `extern %s'\n", id);
990
                t = gettok();
991
                definept(NULL);
992
                if (isscalar(p->type)
993
                ||  isstruct(p->type) && t != '{') {
994
                        if (t == '{') {
995
                                t = gettok();
996
                                e = expr1(0);
997
                                expect('}');
998
                        } else
999
                                e = expr1(0);
1000
                } else {
1001
                        Symbol t1;
1002
                        Type ty = p->type, ty1 = ty;
1003
                        while (isarray(ty1))
1004
                                ty1 = ty1->type;
1005
                        if (!isconst(ty) && (!isarray(ty) || !isconst(ty1)))
1006
                                ty = qual(CONST, ty);
1007
                        t1 = genident(STATIC, ty, GLOBAL);
1008
                        initglobal(t1, 1);
1009
                        if (isarray(p->type) && p->type->size == 0
1010
                        && t1->type->size > 0)
1011
                                p->type = array(p->type->type,
1012
                                        t1->type->size/t1->type->type->size, 0);
1013
                        e = idtree(t1);
1014
                }
1015
                walk(root(asgn(p, e)), 0, 0);
1016
                p->ref = 1;
1017
        }
1018
        if (!isfunc(p->type) && p->defined && p->type->size <= 0)
1019
                error("undefined size for `%t %s'\n", p->type, id);
1020
        return p;
1021
}
1022
void finalize(void) {
1023
        foreach(externals,   GLOBAL,    doextern, NULL);
1024
        foreach(identifiers, GLOBAL,    doglobal, NULL);
1025
        foreach(identifiers, GLOBAL,    checkref, NULL);
1026
        foreach(constants,   CONSTANTS, doconst,  NULL);
1027
}
1028
static void doextern(Symbol p, void *cl) {
1029
        (*IR->import)(p);
1030
}
1031
static void doglobal(Symbol p, void *cl) {
1032
        if (!p->defined && (p->sclass == EXTERN
1033
        || isfunc(p->type) && p->sclass == AUTO))
1034
                (*IR->import)(p);
1035
        else if (!p->defined && !isfunc(p->type)
1036
        && (p->sclass == AUTO || p->sclass == STATIC)) {
1037
                if (isarray(p->type)
1038
                && p->type->size == 0 && p->type->type->size > 0)
1039
                        p->type = array(p->type->type, 1, 0);
1040
                if (p->type->size > 0) {
1041
                        defglobal(p, BSS);
1042
                        (*IR->space)(p->type->size);
1043
                        if (glevel > 0 && IR->stabsym)
1044
                                (*IR->stabsym)(p);
1045
                } else
1046
                        error("undefined size for `%t %s'\n",
1047
                                p->type, p->name);
1048
                p->defined = 1;
1049
        }
1050
        if (Pflag
1051
        && !isfunc(p->type)
1052
        && !p->generated && p->sclass != EXTERN)
1053
                printdecl(p, p->type);
1054
}
1055
void doconst(Symbol p, void *cl) {
1056
        if (p->u.c.loc) {
1057
                assert(p->u.c.loc->u.seg == 0);
1058
                defglobal(p->u.c.loc, LIT);
1059
                if (isarray(p->type) && p->type->type == widechar) {
1060
                        unsigned int *s = p->u.c.v.p;
1061
                        int n = p->type->size/widechar->size;
1062
                        while (n-- > 0) {
1063
                                Value v;
1064
                                v.u = *s++;
1065
                                (*IR->defconst)(widechar->op, widechar->size, v);
1066
                        }
1067
                } else if (isarray(p->type))
1068
                        (*IR->defstring)(p->type->size, p->u.c.v.p);
1069
                else
1070
                        (*IR->defconst)(p->type->op, p->type->size, p->u.c.v);
1071
                p->u.c.loc = NULL;
1072
        }
1073
}
1074
void checklab(Symbol p, void *cl) {
1075
        if (!p->defined)
1076
                error("undefined label `%s'\n", p->name);
1077
        p->defined = 1;
1078
}
1079
 
1080
Type enumdcl(void) {
1081
        char *tag;
1082
        Type ty;
1083
        Symbol p;
1084
        Coordinate pos;
1085
 
1086
        t = gettok();
1087
        pos = src;
1088
        if (t == ID) {
1089
                tag = token;
1090
                t = gettok();
1091
        } else
1092
                tag = "";
1093
        if (t == '{') {
1094
                static char follow[] = { IF, 0 };
1095
                int n = 0;
1096
                long k = -1;
1097
                List idlist = 0;
1098
                ty = newstruct(ENUM, tag);
1099
                t = gettok();
1100
                if (t != ID)
1101
                        error("expecting an enumerator identifier\n");
1102
                while (t == ID) {
1103
                        char *id = token;
1104
                        Coordinate s;
1105
                        if (tsym && tsym->scope == level)
1106
                                error("redeclaration of `%s' previously declared at %w\n",
1107
                                        token, &tsym->src);
1108
                        s = src;
1109
                        t = gettok();
1110
                        if (t == '=') {
1111
                                t = gettok();
1112
                                k = intexpr(0, 0);
1113
                        } else {
1114
                                if (k == inttype->u.sym->u.limits.max.i)
1115
                                        error("overflow in value for enumeration constant `%s'\n", id);
1116
                                k++;
1117
                        }
1118
                        p = install(id, &identifiers, level,  level < LOCAL ? PERM : FUNC);
1119
                        p->src = s;
1120
                        p->type = ty;
1121
                        p->sclass = ENUM;
1122
                        p->u.value = k;
1123
                        idlist = append(p, idlist);
1124
                        n++;
1125
                        if (Aflag >= 2 && n == 128)
1126
                                warning("more than 127 enumeration constants in `%t'\n", ty);
1127
                        if (t != ',')
1128
                                break;
1129
                        t = gettok();
1130
                        if (Aflag >= 2 && t == '}')
1131
                                warning("non-ANSI trailing comma in enumerator list\n");
1132
                }
1133
                test('}', follow);
1134
                ty->type = inttype;
1135
                ty->size = ty->type->size;
1136
                ty->align = ty->type->align;
1137
                ty->u.sym->u.idlist = ltov(&idlist, PERM);
1138
                ty->u.sym->defined = 1;
1139
        } else if ((p = lookup(tag, types)) != NULL && p->type->op == ENUM) {
1140
                ty = p->type;
1141
                if (t == ';')
1142
                        error("empty declaration\n");
1143
        } else {
1144
                error("unknown enumeration `%s'\n",  tag);
1145
                ty = newstruct(ENUM, tag);
1146
                ty->type = inttype;
1147
        }
1148
        if (*tag && xref)
1149
                use(p, pos);
1150
        return ty;
1151
}
1152
 
1153
Type typename(void) {
1154
        Type ty = specifier(NULL);
1155
 
1156
        if (t == '*' || t == '(' || t == '[') {
1157
                ty = dclr(ty, NULL, NULL, 1);
1158
                if (Aflag >= 1 && !hasproto(ty))
1159
                        warning("missing prototype\n");
1160
        }
1161
        return ty;
1162
}
1163
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.