3 static char rcsid
[] = "$Id$";
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)
10 static List autos
, registers
;
11 Symbol cfunc
; /* current function */
12 Symbol retv
; /* return value location for structs */
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
);
37 for (n
= 0; t
!= EOI
; n
++)
38 if (kind
[t
] == CHAR
|| kind
[t
] == STATIC
39 || t
== ID
|| t
== '*' || t
== '(') {
42 if (!(glevel
>= 3 || xref
))
44 } else if (t
== ';') {
45 warning("empty declaration\n");
48 error("unrecognized declaration\n");
52 warning("empty input file\n");
54 static Type
specifier(int *sclass
) {
55 int cls
, cons
, sign
, size
, type
, vol
;
58 cls
= vol
= cons
= sign
= size
= type
= 0;
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;
73 case UNSIGNED
: p
= &sign
; t
= gettok(); break;
74 case LONG
: if (size
== LONG
) {
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
;
83 case ENUM
: p
= &type
; ty
= enumdcl(); break;
85 case UNION
: p
= &type
; ty
= structdcl(t
); break;
87 if (istypename(t
, tsym
) && type
== 0
88 && sign
== 0 && size
== 0) {
92 && ty
->size
!= ty
->type
->size
) {
94 if (isconst(tsym
->type
))
96 if (isvolatile(tsym
->type
))
97 ty
= qual(VOLATILE
, ty
);
110 error("invalid use of `%k'\n", tt
);
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
)
130 else if (size
== LONG
+LONG
) {
131 ty
= sign
== UNSIGNED
? unsignedlonglong
: longlong
;
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
)
139 ty
= qual(CONST
, ty
);
141 ty
= qual(VOLATILE
, ty
);
144 static void decl(Symbol (*dcl
)(int, char *, Type
, Coordinate
*)) {
147 static char stop
[] = { CHAR
, STATIC
, ID
, 0 };
149 ty
= specifier(&sclass
);
150 if (t
== ID
|| t
== '*' || t
== '(' || t
== '[') {
155 if (level
== GLOBAL
) {
156 Symbol
*params
= NULL
;
157 ty1
= dclr(ty
, &id
, ¶ms
, 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");
165 if (ty1
->u
.f
.oldstyle
)
167 funcdefn(sclass
, id
, ty1
, params
, pos
);
172 ty1
= dclr(ty
, &id
, NULL
, 0);
174 if (Aflag
>= 1 && !hasproto(ty1
))
175 warning("missing prototype\n");
177 error("missing identifier\n");
178 else if (sclass
== TYPEDEF
)
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
);
190 (void)(*dcl
)(sclass
, id
, ty1
, &pos
);
196 ty1
= dclr(ty
, &id
, NULL
, 0);
198 } else if (ty
== NULL
200 isstruct(ty
) && (*unqual(ty
)->u
.sym
->name
< '1' || *unqual(ty
)->u
.sym
->name
> '9')))
201 error("empty declaration\n");
204 static Symbol
dclglobal(int sclass
, char *id
, Type ty
, Coordinate
*pos
) {
209 else if (sclass
!= EXTERN
&& sclass
!= STATIC
) {
210 error("invalid storage class `%k' for `%t %s'\n",
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
);
219 error("redeclaration of `%s' previously declared at %w\n", p
->name
, &p
->src
);
221 if (!isfunc(ty
) && p
->defined
&& t
== '=')
222 error("redefinition of `%s' previously defined at %w\n", p
->name
, &p
->src
);
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
);
230 if (p
== NULL
|| p
->scope
!= GLOBAL
) {
231 Symbol q
= lookup(id
, externals
);
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
);
236 p
= relocate(id
, externals
, globals
);
239 p
= install(id
, &globals
, GLOBAL
, PERM
);
243 if (p
->sclass
!= STATIC
) {
246 if (Aflag
>= 2 && nglobals
== 512)
247 warning("more than 511 external identifiers\n");
249 } else if (p
->sclass
== EXTERN
)
253 if (t
== '=' && isfunc(p
->type
)) {
254 error("illegal initialization for `%s'\n", p
->name
);
256 initializer(p
->type
, 0);
257 } else if (t
== '=') {
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
);
266 static void initglobal(Symbol p
, int flag
) {
269 if (t
== '=' || flag
) {
270 if (p
->sclass
== STATIC
) {
271 for (ty
= p
->type
; isarray(ty
); ty
= ty
->type
)
273 defglobal(p
, isconst(ty
) ? LIT
: DATA
);
278 ty
= initializer(p
->type
, 0);
279 if (isarray(p
->type
) && p
->type
->size
== 0)
281 if (p
->sclass
== EXTERN
)
285 void defglobal(Symbol p
, int seg
) {
288 if (p
->sclass
!= STATIC
)
294 static Type
dclr(Type basety
, char **id
, Symbol
**params
, int abstract
) {
295 Type ty
= dclr1(id
, params
, abstract
);
297 for ( ; ty
; ty
= ty
->type
)
300 basety
= ptr(basety
);
303 basety
= func(basety
, ty
->u
.f
.proto
,
307 basety
= array(basety
, ty
->size
, 0);
309 case CONST
: case VOLATILE
:
310 basety
= qual(ty
->op
, basety
);
314 if (Aflag
>= 2 && basety
->size
> 32767)
315 warning("more than 32767 bytes in `%t'\n", basety
);
318 static Type
tnode(int op
, Type type
) {
326 static Type
dclr1(char **id
, Symbol
**params
, int abstract
) {
333 error("extraneous identifier `%s'\n", token
);
335 case '*': t
= gettok(); if (t
== CONST
|| t
== VOLATILE
) {
337 ty1
= ty
= tnode(t
, NULL
);
338 while ((t
= gettok()) == CONST
|| t
== VOLATILE
)
340 ty
->type
= dclr1(id
, params
, abstract
);
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
== ')')) {
348 ty
= tnode(FUNCTION
, ty
);
352 args
= parameters(ty
);
355 ty
= dclr1(id
, params
, abstract
);
357 if (abstract
&& ty
== NULL
358 && (id
== NULL
|| *id
== NULL
))
359 return tnode(FUNCTION
, NULL
);
364 while (t
== '(' || t
== '[')
366 case '(': t
= gettok(); { Symbol
*args
;
367 ty
= tnode(FUNCTION
, ty
);
371 args
= parameters(ty
);
372 if (params
&& *params
== NULL
)
378 case '[': t
= gettok(); { int n
= 0;
382 error("`%d' is an illegal array size\n", n
);
387 ty
= tnode(ARRAY
, ty
);
388 ty
->size
= n
; } break;
393 static Symbol
*parameters(Type fty
) {
397 if (kind
[t
] == STATIC
|| istypename(t
, tsym
)) {
404 if (ty1
&& t
== ELLIPSIS
) {
405 static struct symbol sentinel
;
406 if (sentinel
.type
== NULL
) {
407 sentinel
.type
= voidtype
;
408 sentinel
.defined
= 1;
411 error("illegal formal parameter types\n");
412 list
= append(&sentinel
, list
);
416 if (!istypename(t
, tsym
) && t
!= REGISTER
)
417 error("missing parameter type\n");
419 ty
= dclr(specifier(&sclass
), &id
, NULL
, 1);
420 if ( ty
== voidtype
&& (ty1
|| id
)
422 error("illegal formal parameter types\n");
426 list
= append(dclparam(sclass
, id
, ty
, &src
), list
);
427 if (Aflag
>= 1 && !hasproto(ty
))
428 warning("missing prototype\n");
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;
447 error("expecting an identifier\n");
450 p
= dclparam(0, token
, inttype
, &src
);
452 list
= append(p
, list
);
458 params
= ltov(&list
, FUNC
);
459 fty
->u
.f
.proto
= NULL
;
460 fty
->u
.f
.oldstyle
= 1;
463 static char stop
[] = { CHAR
, STATIC
, IF
, ')', 0 };
471 static void exitparams(Symbol params
[]) {
473 if (params
[0] && !params
[0]->defined
)
474 error("extraneous old-style parameter list\n");
480 static Symbol
dclparam(int sclass
, char *id
, Type ty
, Coordinate
*pos
) {
485 else if (isarray(ty
))
489 else if (sclass
!= REGISTER
) {
490 error("invalid storage class `%k' for `%t%s\n",
491 sclass
, ty
, stringf(id
? " %s'" : "' parameter", id
));
493 } else if (isvolatile(ty
) || isstruct(ty
)) {
494 warning("register declaration ignored for `%t%s\n",
495 ty
, stringf(id
? " %s'" : "' parameter", id
));
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
);
504 p
= install(id
, &identifiers
, level
, FUNC
);
510 error("illegal initialization for parameter `%s'\n", id
);
516 static Type
structdcl(int op
) {
530 static char stop
[] = { IF
, ',', 0 };
531 ty
= newstruct(op
, tag
);
532 ty
->u
.sym
->src
= pos
;
533 ty
->u
.sym
->defined
= 1;
535 if (istypename(t
, tsym
))
538 error("invalid %k field declarations\n", op
);
541 else if (*tag
&& (p
= lookup(tag
, types
)) != NULL
542 && p
->type
->op
== op
) {
544 if (t
== ';' && p
->scope
< level
)
545 ty
= newstruct(op
, tag
);
549 error("missing %k tag\n", op
);
550 ty
= newstruct(op
, tag
);
556 static void fields(Type ty
) {
558 while (istypename(t
, tsym
)) {
559 static char stop
[] = { IF
, CHAR
, '}', 0 };
560 Type ty1
= specifier(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");
569 if (unqual(p
->type
) != inttype
570 && unqual(p
->type
) != unsignedtype
) {
571 error("`%t' is an illegal bit-field type\n",
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",
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
);
584 p
->name
= stringd(genlabel(1));
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",
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;
602 if (Aflag
>= 2 && n
== 128)
603 warning("more than 127 fields in `%t'\n", ty
);
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;
616 a
= unsignedtype
->align
;
619 else if (p
->bitsize
== 0 || bits
== 0
620 || bits
- 1 + p
->bitsize
> 8*unsignedtype
->size
) {
621 off
= add(off
, bits2bytes(bits
-1));
623 chkoverflow(off
, a
- 1);
624 off
= roundup(off
, a
);
633 if (IR
->little_endian
)
636 p
->lsb
= 8*unsignedtype
->size
- bits
+ 1
640 off
= add(off
, p
->type
->size
);
641 if (off
+ bits2bytes(bits
-1) > ty
->size
)
642 ty
->size
= off
+ bits2bytes(bits
-1);
644 || !('1' <= *p
->name
&& *p
->name
<= '9')) {
650 chkoverflow(ty
->size
, ty
->align
- 1);
651 ty
->size
= roundup(ty
->size
, ty
->align
);
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));
657 static void funcdefn(int sclass
, char *id
, Type ty
, Symbol params
[], Coordinate pt
) {
659 Symbol
*callee
, *caller
, p
;
660 Type rty
= freturn(ty
);
662 if (isstruct(rty
) && rty
->size
== 0)
663 error("illegal use of incomplete type `%t'\n", rty
);
664 for (n
= 0; params
[n
]; n
++)
666 if (n
> 0 && params
[n
-1]->name
== NULL
)
668 if (Aflag
>= 2 && n
> 31)
669 warning("more than 31 parameters in function `%s'\n", id
);
670 if (ty
->u
.f
.oldstyle
) {
672 warning("old-style function definition for `%s'\n", id
);
674 callee
= newarray(n
+ 1, sizeof *callee
, FUNC
);
675 memcpy(callee
, caller
, (n
+1)*sizeof *callee
);
677 assert(level
== PARAM
);
678 while (kind
[t
] == STATIC
|| istypename(t
, tsym
))
680 foreach(identifiers
, PARAM
, oldparam
, callee
);
682 for (i
= 0; (p
= callee
[i
]) != NULL
; i
++) {
684 callee
[i
] = dclparam(0, p
->name
, inttype
, &p
->src
);
686 caller
[i
]->sclass
= AUTO
;
687 caller
[i
]->type
= promote(p
->type
);
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)
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
);
702 if (proto
[i
] || caller
[i
])
703 error("conflicting argument declarations for function `%s'\n", id
);
707 Type
*proto
= newarray(n
+ 1, sizeof *proto
, PERM
);
709 warning("missing prototype for `%s'\n", id
);
710 for (i
= 0; i
< n
; i
++)
711 proto
[i
] = caller
[i
]->type
;
713 ty
= func(rty
, proto
, 1);
717 caller
= newarray(n
+ 1, sizeof *caller
, FUNC
);
718 for (i
= 0; (p
= callee
[i
]) != NULL
&& p
->name
; i
++) {
719 NEW(caller
[i
], FUNC
);
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
);
730 for (i
= 0; (p
= callee
[i
]) != NULL
; i
++)
731 if (p
->type
->size
== 0) {
732 error("undefined size for parameter `%t %s'\n",
734 caller
[i
]->type
= p
->type
= inttype
;
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
744 warning("`%s' is a non-ANSI definition\n", typestring(ty
, id
));
746 p
= lookup(id
, identifiers
);
747 if (p
&& isfunc(p
->type
) && p
->defined
)
748 error("redefinition of `%s' previously defined at %w\n",
750 cfunc
= dclglobal(sclass
, id
, ty
, &pt
);
751 cfunc
->u
.f
.label
= genlabel(1);
752 cfunc
->u
.f
.callee
= callee
;
756 use(cfunc
, cfunc
->src
);
758 printproto(cfunc
, cfunc
->u
.f
.callee
);
760 ncalled
= findfunc(cfunc
->name
, pt
.file
);
761 labels
= table(NULL
, LABELS
);
762 stmtlabs
= table(NULL
, LABELS
);
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);
771 definelab(cfunc
->u
.f
.label
);
773 apply(events
.exit
, cfunc
, NULL
);
776 assert(level
== PARAM
);
777 foreach(identifiers
, level
, checkref
, NULL
);
778 if (!IR
->wants_callb
&& isstruct(rty
)) {
780 a
= newarray(n
+ 2, sizeof *a
, FUNC
);
782 memcpy(&a
[1], callee
, (n
+1)*sizeof *callee
);
784 a
= newarray(n
+ 2, sizeof *a
, FUNC
);
787 memcpy(&a
[1], caller
, (n
+1)*sizeof *callee
);
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;
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
); }
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
);
809 labels
= stmtlabs
= NULL
;
813 static void oldparam(Symbol p
, void *cl
) {
817 for (i
= 0; callee
[i
]; i
++)
818 if (p
->name
== callee
[i
]->name
) {
822 error("declared parameter `%s' is missing\n", p
->name
);
824 void compound(int loop
, struct swtch
*swp
, int lev
) {
831 assert(level
>= LOCAL
);
832 if (level
== LOCAL
&& events
.entry
)
833 apply(events
.entry
, cfunc
, NULL
);
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
);
842 registers
= append(retv
, registers
);
844 while (kind
[t
] == CHAR
|| kind
[t
] == STATIC
845 || istypename(t
, tsym
) && getchr() != ':')
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(®isters
, FUNC
);
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
);
860 foreach(identifiers
, level
, checkref
, NULL
);
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
;
871 if (level
== LOCAL
) {
873 for (cp
= codelist
; cp
->kind
< Label
; cp
= cp
->prev
)
875 if (cp
->kind
!= Jump
) {
876 if (freturn(cfunc
->type
) != voidtype
) {
877 warning("missing return value\n");
878 retcode(cnsttree(inttype
, 0L));
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
;
896 static void checkref(Symbol p
, void *cl
) {
897 if (p
->scope
>= PARAM
898 && (isvolatile(p
->type
) || isfunc(p
->type
)))
900 if (Aflag
>= 2 && p
->defined
&& p
->ref
== 0) {
901 if (p
->sclass
== STATIC
)
902 warning("static `%t %s' is not referenced\n",
904 else if (p
->scope
== PARAM
)
905 warning("parameter `%t %s' is not referenced\n",
907 else if (p
->scope
>= LOCAL
&& p
->sclass
!= EXTERN
)
908 warning("local `%t %s' is not referenced\n",
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
)));
921 static Symbol
dcllocal(int sclass
, char *id
, Type ty
, Coordinate
*pos
) {
925 sclass
= isfunc(ty
) ? EXTERN
: AUTO
;
926 else if (isfunc(ty
) && sclass
!= EXTERN
) {
927 error("invalid storage class `%k' for `%t %s'\n",
930 } else if (sclass
== REGISTER
931 && (isvolatile(ty
) || isstruct(ty
) || isarray(ty
))) {
932 warning("register declaration ignored for `%t %s'\n",
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
);
943 error("redeclaration of `%s' previously declared at %w\n", q
->name
, &q
->src
);
945 assert(level
>= LOCAL
);
946 p
= install(id
, &identifiers
, level
, sclass
== STATIC
|| sclass
== EXTERN
? PERM
: FUNC
);
951 case EXTERN
: q
= lookup(id
, globals
);
952 if (q
== NULL
|| q
->sclass
== TYPEDEF
|| q
->sclass
== ENUM
) {
953 q
= lookup(id
, externals
);
955 q
= install(p
->name
, &externals
, GLOBAL
, PERM
);
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
);
965 p
->u
.alias
= q
; break;
966 case STATIC
: (*IR
->defsymbol
)(p
);
969 if (p
->type
->size
> 0) {
971 (*IR
->space
)(p
->type
->size
);
973 error("undefined size for `%t %s'\n",
975 p
->defined
= 1; break;
976 case REGISTER
: registers
= append(p
, registers
);
980 case AUTO
: autos
= append(p
, autos
);
983 p
->addressed
= 1; break;
988 if (sclass
== EXTERN
)
989 error("illegal initialization of `extern %s'\n", id
);
992 if (isscalar(p
->type
)
993 || isstruct(p
->type
) && t
!= '{') {
1002 Type ty
= p
->type
, ty1
= ty
;
1003 while (isarray(ty1
))
1005 if (!isconst(ty
) && (!isarray(ty
) || !isconst(ty1
)))
1006 ty
= qual(CONST
, ty
);
1007 t1
= genident(STATIC
, ty
, GLOBAL
);
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);
1015 walk(root(asgn(p
, e
)), 0, 0);
1018 if (!isfunc(p
->type
) && p
->defined
&& p
->type
->size
<= 0)
1019 error("undefined size for `%t %s'\n", p
->type
, id
);
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
);
1028 static void doextern(Symbol p
, void *cl
) {
1031 static void doglobal(Symbol p
, void *cl
) {
1032 if (!p
->defined
&& (p
->sclass
== EXTERN
1033 || isfunc(p
->type
) && p
->sclass
== AUTO
))
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) {
1042 (*IR
->space
)(p
->type
->size
);
1043 if (glevel
> 0 && IR
->stabsym
)
1046 error("undefined size for `%t %s'\n",
1052 && !p
->generated
&& p
->sclass
!= EXTERN
)
1053 printdecl(p
, p
->type
);
1055 void doconst(Symbol p
, void *cl
) {
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
;
1065 (*IR
->defconst
)(widechar
->op
, widechar
->size
, v
);
1067 } else if (isarray(p
->type
))
1068 (*IR
->defstring
)(p
->type
->size
, p
->u
.c
.v
.p
);
1070 (*IR
->defconst
)(p
->type
->op
, p
->type
->size
, p
->u
.c
.v
);
1074 void checklab(Symbol p
, void *cl
) {
1076 error("undefined label `%s'\n", p
->name
);
1080 Type
enumdcl(void) {
1094 static char follow
[] = { IF
, 0 };
1098 ty
= newstruct(ENUM
, tag
);
1101 error("expecting an enumerator identifier\n");
1105 if (tsym
&& tsym
->scope
== level
)
1106 error("redeclaration of `%s' previously declared at %w\n",
1114 if (k
== inttype
->u
.sym
->u
.limits
.max
.i
)
1115 error("overflow in value for enumeration constant `%s'\n", id
);
1118 p
= install(id
, &identifiers
, level
, level
< LOCAL
? PERM
: FUNC
);
1123 idlist
= append(p
, idlist
);
1125 if (Aflag
>= 2 && n
== 128)
1126 warning("more than 127 enumeration constants in `%t'\n", ty
);
1130 if (Aflag
>= 2 && t
== '}')
1131 warning("non-ANSI trailing comma in enumerator list\n");
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
) {
1142 error("empty declaration\n");
1144 error("unknown enumeration `%s'\n", tag
);
1145 ty
= newstruct(ENUM
, tag
);
1153 Type
typename(void) {
1154 Type ty
= specifier(NULL
);
1156 if (t
== '*' || t
== '(' || t
== '[') {
1157 ty
= dclr(ty
, NULL
, NULL
, 1);
1158 if (Aflag
>= 1 && !hasproto(ty
))
1159 warning("missing prototype\n");