Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / cemcom / struct.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  */
5 /* $Id: struct.c,v 3.18 1994/06/24 12:06:21 ceriel Exp $ */
6 /*      ADMINISTRATION OF STRUCT AND UNION DECLARATIONS */
7
8 #include        "nobitfield.h"
9 #include        "debug.h"
10 #include        "botch_free.h"
11 #include        <alloc.h>
12 #include        "arith.h"
13 #include        "stack.h"
14 #include        "idf.h"
15 #include        "def.h"
16 #include        "type.h"
17 #include        "struct.h"
18 #include        "field.h"
19 #include        "LLlex.h"
20 #include        "Lpars.h"
21 #include        "align.h"
22 #include        "level.h"
23 #include        "assert.h"
24 #include        "sizes.h"
25 #include        "noRoption.h"
26
27 /*      Type of previous selector declared with a field width specified,
28         if any.  If a selector is declared with no field with it is set to 0.
29 */
30 static field_busy = 0;
31
32 extern char options[];
33 int lcm();
34
35 /*      The semantics of the identification of structure/union tags is
36         obscure.  Some highly regarded compilers are found out to accept,
37         e.g.:
38                 f(xp) struct aap *xp;   {
39                         struct aap {char *za;};
40                         xp->za;
41                 }
42         Equally highly regarded software uses this feature, so we shall
43         humbly oblige.
44         The rules we use are:
45         1.      A structure definition applies at the level where it is
46                 found, unless there is a structure declaration without a
47                 definition on an outer level, in which case the definition
48                 is applied at that level.
49         2.      A selector is applied on the same level as on which its
50                 structure is being defined.
51
52         If below struct is mentioned, union is implied (and sometimes enum
53         as well).
54 */
55
56 add_sel(stp, tp, idf, sdefpp, szp, fd)  /* this is horrible */
57         register struct type *stp;      /* type of the structure */
58         struct type *tp;                /* type of the selector */
59         register struct idf *idf;       /* idf of the selector */
60         struct sdef ***sdefpp;  /* address of hook to selector definition */
61         arith *szp;             /* pointer to struct size upto here */
62         struct field *fd;
63 {
64         /*      The selector idf with type tp is added to two chains: the
65                 selector identification chain starting at idf->id_sdef,
66                 and to the end of the member list starting at stp->tp_sdef.
67                 The address of the hook in the latest member (sdef) is
68                 given in sdefpp; the hook itself must still be empty.
69         */
70         arith offset;
71 #ifndef NOBITFIELD
72         extern arith add_field();
73 #endif /* NOBITFIELD */
74
75         struct tag *tg = stp->tp_idf->id_struct;        /* or union */
76         struct sdef *sdef = idf->id_sdef;
77         register struct sdef *newsdef;
78         int lvl = tg->tg_level;
79         
80 #ifndef NOROPTION
81         if (options['R'] && !is_anon_idf(idf))  {
82                 /* a K & R test */
83                 if (idf->id_struct && idf->id_struct->tg_level == level)
84                         warning("%s is also a struct/union tag", idf->id_text);
85         }
86 #endif
87
88         if (stp->tp_fund == STRUCT)     {
89 #ifndef NOBITFIELD
90                 if (fd == 0)    {       /* no field width specified     */
91                         offset = align(*szp, tp->tp_align);
92                         field_busy = 0;
93                 }
94                 else    {
95                         /*      if something is wrong, the type of the
96                                 specified selector remains unchanged; its
97                                 bitfield specifier, however, is thrown away.
98                         */
99                         offset = add_field(szp, fd, &tp, idf, stp);
100                 }
101 #else /* NOBITFIELD */
102                 offset = align(*szp, tp->tp_align);
103                 field_busy = 0;
104 #endif /* NOBITFIELD */
105         }
106         else    {       /* (stp->tp_fund == UNION)              */
107                 if (fd) {
108                         error("fields not allowed in unions");
109                         free_field(fd);
110                         fd = 0;
111                 }
112                 offset = (arith)0;
113         }
114         
115         check_selector(idf, stp);
116 #ifndef NOROPTION
117         if (options['R'])       {
118                 if (    sdef && sdef->sd_level == lvl &&
119                         ( sdef->sd_offset != offset || sdef->sd_type != tp )
120                 )                               /* RM 8.5 */
121                         warning("selector %s redeclared", idf->id_text);
122         }
123 #endif
124
125         newsdef = new_sdef();
126         newsdef->sd_sdef = (struct sdef *) 0;
127
128         /*      link into selector descriptor list of this id
129         */
130         newsdef->next = sdef;
131         idf->id_sdef = newsdef;
132
133         newsdef->sd_level = lvl;
134         newsdef->sd_idf = idf;
135         newsdef->sd_stype = stp;
136         newsdef->sd_type = tp;
137         newsdef->sd_offset = offset;
138
139 #ifndef NOBITFIELD
140         if (tp->tp_fund == FIELD)
141                 tp->tp_field->fd_sdef = newsdef;
142 #endif /* NOBITFIELD */
143
144         stack_idf(idf, stack_level_of(lvl));
145
146         /*      link into selector definition list of the struct/union
147         */
148         **sdefpp = newsdef;
149         *sdefpp = &newsdef->sd_sdef;
150
151         /* update the size of the struct/union upward   */
152         if (stp->tp_fund == STRUCT && fd == 0)  {
153                 /*      Note: the case that a bitfield is declared is
154                         handled by add_field() !
155                 */
156                 *szp = offset + size_of_type(tp, "member");
157                 stp->tp_align = lcm(stp->tp_align, tp->tp_align);
158         }
159         else
160         if (stp->tp_fund == UNION)      {
161                 arith sel_size = size_of_type(tp, "member");
162
163                 if (*szp < sel_size)
164                         *szp = sel_size;
165                 stp->tp_align = lcm(stp->tp_align, tp->tp_align);
166         }
167 }
168
169 check_selector(idf, stp)
170         register struct idf *idf;
171         struct type *stp;       /* the type of the struct */
172 {
173         /*      checks if idf occurs already as a selector in
174                 struct or union *stp.
175         */
176         register struct sdef *sdef = stp->tp_sdef;
177         
178         while (sdef)    {
179                 if (sdef->sd_idf == idf)
180                         error("multiple selector %s", idf->id_text);
181                 sdef = sdef->sd_sdef;
182         }
183 }
184
185 char *symbol2str();
186
187 declare_struct(fund, idf, tpp)
188         register struct idf *idf;
189         struct type **tpp;
190 {
191         /*      A struct, union or enum (depending on fund) with tag (!)
192                 idf is declared, and its type (incomplete as it may be) is
193                 returned in *tpp.
194                 The idf may be missing (i.e. idf == 0), in which case an
195                 anonymous struct etc. is defined.
196         */
197         register struct tag **tgp;
198         register struct tag *tg;
199
200         if (!idf)
201                 idf = gen_idf();
202         tgp = (fund == ENUM ? &idf->id_enum : &idf->id_struct);
203         
204 #ifndef NOROPTION
205         if (options['R'] && !is_anon_idf(idf))  {
206                 /* a K & R test */
207                 if (    fund != ENUM &&
208                         idf->id_sdef && idf->id_sdef->sd_level == level
209                 )       {
210                         warning("%s is also a selector", idf->id_text);
211                 }
212                 if (    fund == ENUM &&
213                         idf->id_def && idf->id_def->df_level == level
214                 )       {
215                         warning("%s is also a variable", idf->id_text);
216                 }
217         }
218 #endif
219         
220         tg = *tgp;
221         if (tg && tg->tg_type->tp_size < 0 && tg->tg_type->tp_fund == fund) {
222                 /*      An unfinished declaration has preceded it, possibly on
223                         an earlier level.  We just fill in the answer.
224                 */
225                 if (tg->tg_busy) {
226                         error("recursive declaration of struct/union %s",
227                                 idf->id_text);
228                         declare_struct(fund, gen_idf(), tpp);
229                 }
230                 else {
231 #ifndef NOROPTION
232                         if (options['R'] && tg->tg_level != level)
233                                 warning("%s declares %s in different range",
234                                         idf->id_text, symbol2str(fund));
235 #endif
236                         *tpp = tg->tg_type;
237                 }
238         }
239         else
240         if (tg && tg->tg_level == level)        {
241                 /*      There is an already defined struct/union of this name
242                         on our level!
243                 */
244                 error("redeclaration of struct/union %s", idf->id_text);
245                 declare_struct(fund, gen_idf(), tpp);
246                 /* to allow a second struct_declaration_pack */
247         }
248         else    {
249                 /* The struct is new. */
250                 /* Hook in a new struct tag */
251                 tg = new_tag();
252                 tg->next = *tgp;
253                 *tgp = tg;
254                 tg->tg_level = level;
255                 /* and supply room for a type */
256                 tg->tg_type = create_type(fund);
257                 tg->tg_type->tp_align =
258                         fund == ENUM ? int_align :
259                         fund == STRUCT ? struct_align :
260                         /* fund == UNION */ union_align;
261                 tg->tg_type->tp_idf = idf;
262                 *tpp = tg->tg_type;
263                 stack_idf(idf, local_level);
264         }
265 }
266
267 apply_struct(fund, idf, tpp)
268         register struct idf *idf;
269         struct type **tpp;
270 {
271         /*      The occurrence of a struct, union or enum (depending on
272                 fund) with tag idf is noted. It may or may not have been
273                 declared before. Its type (complete or incomplete) is
274                 returned in *tpp.
275         */
276         register struct tag **tgp;
277
278         tgp = (is_struct_or_union(fund) ? &idf->id_struct : &idf->id_enum);
279
280         if (*tgp)
281                 *tpp = (*tgp)->tg_type;
282         else
283                 declare_struct(fund, idf, tpp);
284 }
285
286 struct sdef *
287 idf2sdef(idf, tp)
288         register struct idf *idf;
289         struct type *tp;
290 {
291         /*      The identifier idf is identified as a selector, preferably
292                 in the struct tp, but we will settle for any unique
293                 identification.
294                 If the attempt fails, a selector of type error_type is
295                 created.
296         */
297         register struct sdef **sdefp = &idf->id_sdef, *sdef;
298         
299         /* Follow chain from idf, to meet tp. */
300         while ((sdef = *sdefp)) {
301                 if (sdef->sd_stype == tp)
302                         return sdef;
303                 sdefp = &(*sdefp)->next;
304         }
305         
306         /* Tp not met; any unique identification will do. */
307         if (sdef = idf->id_sdef)        {
308                 /* There is an identification */
309                 if (uniq_selector(sdef))        {
310                         /* and it is unique, so we accept */
311                         warning("selector %s applied to alien type",
312                                         idf->id_text);
313                 }
314                 else    {
315                         /* it is ambiguous */
316                         error("ambiguous use of selector %s", idf->id_text);
317                 }
318                 return sdef;
319         }
320         
321         /* No luck; create an error entry. */
322         if (!is_anon_idf(idf))
323                 error("unknown selector %s", idf->id_text);
324         *sdefp = sdef = new_sdef();
325         sdef->sd_idf = idf;
326         sdef->sd_stype = sdef->sd_type = error_type;
327         return sdef;
328 }
329
330 int
331 uniq_selector(idf_sdef)
332         register struct sdef *idf_sdef;
333 {
334         /*      Returns true if idf_sdef (which is guaranteed to exist)
335                 is unique for this level, i.e there is no other selector
336                 on this level with the same name or the other selectors
337                 with the same name have the same offset.
338                 See /usr/src/cmd/sed/sed.h for an example of this absurd
339                 case!
340         */
341         
342         register struct sdef *sdef = idf_sdef->next;
343         
344         while (sdef && sdef->sd_level == idf_sdef->sd_level)    {
345                 if (    sdef->sd_type != idf_sdef->sd_type
346                 ||      sdef->sd_offset != idf_sdef->sd_offset
347                 )       {
348                         return 0;               /* ambiguity found */
349                 }
350                 sdef = sdef->next;
351         }
352         return 1;
353 }
354
355 #ifndef NOBITFIELD
356 arith
357 add_field(szp, fd, fdtpp, idf, stp)
358         arith *szp;                     /* size of struct upto here     */
359         register struct field *fd;      /* bitfield, containing width   */
360         register struct type **fdtpp;   /* type of selector             */
361         struct idf *idf;                /* name of selector             */
362         register struct type *stp;      /* current struct descriptor    */
363 {
364         /*      The address where this selector is put is returned. If the
365                 selector with specified width does not fit in the word, or
366                 an explicit alignment is given, a new address is needed.
367                 Note that the fields are packed into machine words (according
368                 to the RM.)
369         */
370         int bits_in_type = (int) (*fdtpp)->tp_size * 8;
371         static int field_offset = (arith)0;
372         static struct type *current_struct = 0;
373         static int bits_declared;       /* nr of bits used in *field_offset */
374
375         if (current_struct != stp)      {
376                 /*      This struct differs from the last one
377                 */
378                 field_busy = 0;
379                 current_struct = stp;
380         }
381
382         if (    fd->fd_width < 0 ||
383                 (fd->fd_width == 0 && !is_anon_idf(idf)) ||
384                 fd->fd_width > bits_in_type
385         )       {
386                 error("illegal field-width specified");
387                 *fdtpp = error_type;
388                 return field_offset;
389         }
390
391         switch ((*fdtpp)->tp_fund)      {
392         case CHAR:
393         case SHORT:
394         case INT:
395         case ENUM:
396         case LONG:
397                 /* right type; size OK? */
398                 if ((int) (*fdtpp)->tp_size > (int) word_size) {
399                         error("bit field type %s does not fit in a word",
400                                 symbol2str((*fdtpp)->tp_fund));
401                         *fdtpp = error_type;
402                         return field_offset;
403                 }
404                 break;
405
406         default:
407                 /* wrong type altogether */
408                 error("field type cannot be %s",
409                                 symbol2str((*fdtpp)->tp_fund));
410                 *fdtpp = error_type;
411                 return field_offset;
412         }
413
414         if (field_busy == 0)    {
415                 /*      align this selector on the next boundary :
416                         the previous selector wasn't a bitfield.
417                 */
418                 field_offset = align(*szp, int_align);
419                 *szp = field_offset + int_size;
420                 stp->tp_align = lcm(stp->tp_align, int_align);
421                 bits_declared = 0;
422                 field_busy = 1;
423         }
424
425         if (fd->fd_width > bits_in_type - bits_declared)        {
426                 /*      field overflow: fetch next memory unit
427                 */
428                 field_offset = align(*szp, int_align);
429                 *szp = field_offset + int_size;
430                 stp->tp_align = lcm(stp->tp_align, int_align);
431                 bits_declared = fd->fd_width;
432         }
433         else
434         if (fd->fd_width == 0)
435                 /*      next field should be aligned on the next boundary.
436                         This will take care that no field will fit in the
437                         space allocated upto here.
438                 */
439                 bits_declared = bits_in_type + 1;
440         else    /* the bitfield fits in the current field       */
441                 bits_declared += fd->fd_width;
442         
443         /*      Arrived here, the place where the selector is stored in the
444                 struct is computed.
445                 Now we need a mask to use its value in expressions.
446         */
447         *fdtpp = construct_type(FIELD, *fdtpp, (arith)0);
448         (*fdtpp)->tp_field = fd;
449
450         /*      Set the mask right shifted. This solution avoids the
451                 problem of having sign extension when using the mask for
452                 extracting the value from the field-int.
453                 Sign extension could occur on some machines when shifting
454                 the mask to the left.
455         */
456         if (fd->fd_width >= 8*sizeof(arith)) fd->fd_mask = -1;
457         else fd->fd_mask = (1L << fd->fd_width) - 1;
458
459         if (options['r'])       /* adjust the field at the right        */
460                 fd->fd_shift = bits_declared - fd->fd_width;
461         else                    /* adjust the field at the left         */
462                 fd->fd_shift = bits_in_type - bits_declared;
463         
464         return field_offset;
465 }
466 #endif /* NOBITFIELD */
467
468 /* some utilities */
469 int
470 is_struct_or_union(fund)
471         register int fund;
472 {
473         return fund == STRUCT || fund == UNION;
474 }
475
476 /*      Greatest Common Divisor
477  */
478 int
479 gcd(m, n)
480         register int m, n;
481 {
482         register int r;
483
484         while (n)       {
485                 r = m % n;
486                 m = n;
487                 n = r;
488         }
489         return m;
490 }
491
492 /*      Least Common Multiple
493  */
494 int
495 lcm(m, n)
496         register int m, n;
497 {
498         return m * (n / gcd(m, n));
499 }