4 static int curseg
; /* current segment */
6 /* defpointer - initialize a pointer to p or to 0 if p==0 */
7 void defpointer(Symbol p
) {
13 (*IR
->defconst
)(P
, voidptype
->size
, v
);
17 /* genconst - generate/check constant expression e; return size */
18 static int genconst(Tree e
, int def
) {
20 switch (generic(e
->op
)) {
23 (*IR
->defaddress
)(e
->u
.sym
);
26 if (e
->op
== CNST
+P
&& isarray(e
->type
)) {
31 (*IR
->defconst
)(e
->type
->op
, e
->type
->size
, e
->u
.v
);
34 assert(e
->kids
[0] || e
->kids
[1]);
35 if (e
->kids
[1] && e
->kids
[0])
36 error("initializer must be constant\n");
37 e
= e
->kids
[1] ? e
->kids
[1] : e
->kids
[0];
41 error("cast from `%t' to `%t' is illegal in constant expressions\n",
42 e
->kids
[0]->type
, e
->type
);
44 case CVI
: case CVU
: case CVF
:
48 error("initializer must be constant\n");
50 genconst(consttree(0, inttype
), def
);
55 /* initvalue - evaluate a constant expression for a value of integer type ty */
56 static Tree
initvalue(Type ty
) {
62 if ((aty
= assign(ty
, e
)) != NULL
)
65 error("invalid initialization type; found `%t' expected `%t'\n",
67 e
= retype(consttree(0, inttype
), ty
);
70 if (generic(e
->op
) != CNST
) {
71 error("initializer must be constant\n");
72 e
= retype(consttree(0, inttype
), ty
);
77 /* initarray - initialize array of ty of <= len bytes; if len == 0, go to } */
78 static int initarray(int len
, Type ty
, int lev
) {
84 if ((len
> 0 && n
>= len
) || t
!= ',')
91 /* initchar - initialize array of <= len ty characters; if len == 0, go to } */
92 static int initchar(int len
, Type ty
) {
94 char buf
[16], *s
= buf
;
97 *s
++ = initvalue(ty
)->u
.v
.i
;
98 if (++n
%inttype
->size
== 0) {
99 (*IR
->defstring
)(inttype
->size
, buf
);
102 if ((len
> 0 && n
>= len
) || t
!= ',')
107 (*IR
->defstring
)(s
- buf
, buf
);
111 /* initend - finish off an initialization at level lev; accepts trailing comma */
112 static void initend(int lev
, char follow
[]) {
113 if (lev
== 0 && t
== ',')
118 /* initfields - initialize <= an unsigned's worth of bit fields in fields p to q */
119 static int initfields(Field p
, Field q
) {
120 unsigned int bits
= 0;
124 i
= initvalue(inttype
)->u
.v
.i
;
125 if (fieldsize(p
) < 8*p
->type
->size
) {
126 if ((p
->type
== inttype
&&
127 (i
< -(int)(fieldmask(p
)>>1)-1 || i
> (int)(fieldmask(p
)>>1)))
128 || (p
->type
== unsignedtype
&& (i
&~fieldmask(p
)) != 0))
129 warning("initializer exceeds bit-field width\n");
132 bits
|= i
<<fieldright(p
);
133 if (IR
->little_endian
) {
134 if (fieldsize(p
) + fieldright(p
) > n
)
135 n
= fieldsize(p
) + fieldright(p
);
137 if (fieldsize(p
) + fieldleft(p
) > n
)
138 n
= fieldsize(p
) + fieldleft(p
);
143 } while (t
== ',' && (t
= gettok()) != 0);
145 for (i
= 0; i
< n
; i
++) {
147 if (IR
->little_endian
) {
148 v
.u
= (unsigned char)bits
;
150 } else { /* a big endian */
151 v
.u
= (unsigned char)(bits
>>(8*(unsignedtype
->size
- 1)));
154 (*IR
->defconst
)(U
, unsignedchar
->size
, v
);
159 /* initstruct - initialize a struct ty of <= len bytes; if len == 0, go to } */
160 static int initstruct(int len
, Type ty
, int lev
) {
162 Field p
= ty
->u
.sym
->u
.s
.flist
;
166 (*IR
->space
)(p
->offset
- n
);
171 while (q
->link
&& q
->link
->offset
== p
->offset
)
173 n
+= initfields(p
, q
->link
);
176 initializer(p
->type
, lev
);
185 (*IR
->space
)(a
- n
%a
);
188 if ((len
> 0 && n
>= len
) || t
!= ',')
195 /* initializer - constexpr | { constexpr ( , constexpr )* [ , ] } */
196 Type
initializer(Type ty
, int lev
) {
200 static char follow
[] = { IF
, CHAR
, STATIC
, 0 };
208 initend(lev
, follow
);
212 if ((aty
= assign(ty
, e
)) != NULL
)
215 error("invalid initialization type; found `%t' expected `%t'\n",
221 if ((isunion(ty
) || isstruct(ty
)) && ty
->size
== 0) {
222 static char follow
[] = { CHAR
, STATIC
, 0 };
223 error("cannot initialize undefined `%t'\n", ty
);
226 } else if (isunion(ty
)) {
229 n
= initstruct(ty
->u
.sym
->u
.s
.flist
->type
->size
, ty
, lev
+ 1);
230 initend(lev
, follow
);
233 error("missing { in initialization of `%t'\n", ty
);
234 n
= initstruct(ty
->u
.sym
->u
.s
.flist
->type
->size
, ty
, lev
+ 1);
236 } else if (isstruct(ty
)) {
239 n
= initstruct(0, ty
, lev
+ 1);
242 n
= initstruct(ty
->size
, ty
, lev
+ 1);
244 error("missing { in initialization of `%t'\n", ty
);
245 n
= initstruct(ty
->u
.sym
->u
.s
.flist
->type
->size
, ty
, lev
+ 1);
249 aty
= unqual(ty
->type
);
250 if (isarray(ty
) && ischar(aty
)) {
252 if (ty
->size
> 0 && ty
->size
== tsym
->type
->size
- 1)
253 tsym
->type
= array(chartype
, ty
->size
, 0);
254 n
= tsym
->type
->size
;
255 (*IR
->defstring
)(tsym
->type
->size
, tsym
->u
.c
.v
.p
);
257 } else if (t
== '{') {
260 ty
= initializer(ty
, lev
+ 1);
261 initend(lev
, follow
);
264 n
= initchar(0, aty
);
266 } else if (lev
> 0 && ty
->size
> 0)
267 n
= initchar(ty
->size
, aty
);
268 else { /* eg, char c[] = 0; */
269 error("missing { in initialization of `%t'\n", ty
);
270 n
= initchar(1, aty
);
272 } else if (isarray(ty
)) {
273 if (t
== SCON
&& aty
== widechar
) {
275 unsigned int *s
= tsym
->u
.c
.v
.p
;
276 if (ty
->size
> 0 && ty
->size
== tsym
->type
->size
- widechar
->size
)
277 tsym
->type
= array(widechar
, ty
->size
/widechar
->size
, 0);
278 n
= tsym
->type
->size
;
279 for (i
= 0; i
< n
; i
+= widechar
->size
) {
282 (*IR
->defconst
)(widechar
->op
, widechar
->size
, v
);
285 } else if (t
== '{') {
287 if (t
== SCON
&& aty
== widechar
) {
288 ty
= initializer(ty
, lev
+ 1);
289 initend(lev
, follow
);
292 n
= initarray(0, aty
, lev
+ 1);
294 } else if (lev
> 0 && ty
->size
> 0)
295 n
= initarray(ty
->size
, aty
, lev
+ 1);
297 error("missing { in initialization of `%t'\n", ty
);
298 n
= initarray(aty
->size
, aty
, lev
+ 1);
303 error("too many initializers\n");
304 else if (n
< ty
->size
)
305 (*IR
->space
)(ty
->size
- n
);
306 } else if (isarray(ty
) && ty
->type
->size
> 0)
307 ty
= array(ty
->type
, n
/ty
->type
->size
, 0);
313 /* swtoseg - switch to segment seg, if necessary */
314 void swtoseg(int seg
) {