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".
5 /* $Id: struct.c,v 1.18 1994/06/27 08:02:46 ceriel Exp $ */
6 /* ADMINISTRATION OF STRUCT AND UNION DECLARATIONS */
8 #include "nobitfield.h"
10 #include "botch_free.h"
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.
30 static field_busy = 0;
32 extern char options[];
36 /* The semantics of the identification of structure/union tags is
37 obscure. Some highly regarded compilers are found out to accept,
39 f(xp) struct aap *xp; {
40 struct aap {char *za;};
43 Equally highly regarded software uses this feature, so we shall
46 1. A structure definition applies at the level where it is
47 found, unless there is a structure declaration without a
48 definition on an outer level, in which case the definition
49 is applied at that level.
50 2. A selector is applied on the same level as on which its
51 structure is being defined.
53 If below struct is mentioned, union is implied (and sometimes enum
57 add_sel(stp, tp, idf, sdefpp, szp, fd) /* this is horrible */
58 register struct type *stp; /* type of the structure */
59 struct type *tp; /* type of the selector */
60 register struct idf *idf; /* idf of the selector */
61 struct sdef ***sdefpp; /* address of hook to selector definition */
62 arith *szp; /* pointer to struct size upto here */
65 /* The selector idf with type tp is added to two chains: the
66 selector identification chain starting at idf->id_sdef,
67 and to the end of the member list starting at stp->tp_sdef.
68 The address of the hook in the latest member (sdef) is
69 given in sdefpp; the hook itself must still be empty.
73 extern arith add_field();
74 #endif /* NOBITFIELD */
76 struct tag *tg = stp->tp_idf->id_tag; /* or union */
77 struct sdef *sdef = idf->id_sdef;
78 register struct sdef *newsdef;
79 int lvl = tg->tg_level;
81 if (stp->tp_fund == STRUCT) {
83 if (fd == 0) { /* no field width specified */
84 offset = align(*szp, tp->tp_align);
88 /* if something is wrong, the type of the
89 specified selector remains unchanged; its
90 bitfield specifier, however, is thrown away.
92 offset = add_field(szp, fd, &tp, idf, stp);
94 #else /* NOBITFIELD */
95 offset = align(*szp, tp->tp_align);
97 #endif /* NOBITFIELD */
99 else { /* (stp->tp_fund == UNION) */
100 if (fd) offset = add_field(szp, fd, &tp, idf, stp);
104 check_selector(idf, stp);
106 newsdef = new_sdef();
107 /* newsdef->sd_sdef = (struct sdef *) 0; */
109 /* link into selector descriptor list of this id
111 newsdef->next = sdef;
112 idf->id_sdef = newsdef;
114 newsdef->sd_level = lvl;
115 newsdef->sd_idf = idf;
116 newsdef->sd_stype = stp;
117 newsdef->sd_type = tp;
118 newsdef->sd_offset = offset;
121 if (tp->tp_fund == FIELD)
122 tp->tp_field->fd_sdef = newsdef;
123 #endif /* NOBITFIELD */
125 stack_idf(idf, stack_level_of(lvl));
127 /* link into selector definition list of the struct/union
130 *sdefpp = &newsdef->sd_sdef;
132 /* update the size of the struct/union upward */
133 if (stp->tp_fund == STRUCT && fd == 0) {
134 /* Note: the case that a bitfield is declared is
135 handled by add_field() !
137 *szp = offset + size_of_type(tp, "member");
138 stp->tp_align = lcm(stp->tp_align, tp->tp_align);
141 if (stp->tp_fund == UNION && fd == 0) {
142 /* Note: the case that a bitfield is declared is
143 handled by add_field() !
145 arith sel_size = size_of_type(tp, "member");
149 stp->tp_align = lcm(stp->tp_align, tp->tp_align);
153 check_selector(idf, stp)
154 register struct idf *idf;
155 struct type *stp; /* the type of the struct */
157 /* checks if idf occurs already as a selector in
158 struct or union *stp.
160 register struct sdef *sdef = stp->tp_sdef;
163 if (sdef->sd_idf == idf)
164 error("multiple selector %s", idf->id_text);
165 sdef = sdef->sd_sdef;
169 declare_struct(fund, idf, tpp)
170 register struct idf *idf;
173 /* A struct, union or enum (depending on fund) with tag (!)
174 idf is declared, and its type (incomplete as it may be) is
176 The idf may be missing (i.e. idf == 0), in which case an
177 anonymous struct etc. is defined.
179 register struct tag **tgp;
180 register struct tag *tg;
183 if (*tpp) error("multiple types in declaration");
189 && tg->tg_type->tp_size < 0
190 && tg->tg_type->tp_fund == fund
191 && (tg->tg_level == level
192 || (level >= L_FORMAL2
194 && tg->tg_level == L_FORMAL2))) {
195 /* An unfinished declaration has preceded it.
196 We just fill in the answer.
199 error("recursive declaration of struct/union %s",
201 declare_struct(fund, gen_idf(), tpp);
204 /* hint: if (level <= L_PROTO) */
208 else if (tg && tg->tg_level == level && tg->tg_type->tp_size >= 0) {
209 /* There is an already defined struct/union of this name
212 error("redeclaration of struct/union %s", idf->id_text);
213 declare_struct(fund, gen_idf(), tpp);
214 /* to allow a second struct_declaration_pack */
217 /* The struct is new. */
218 /* Hook in a new struct tag */
219 if (level <= L_PROTO)
220 warning("declaration of %s-tag inside parameter list",
225 tg->tg_level = level;
226 /* and supply room for a type */
227 tg->tg_type = create_type(fund);
228 tg->tg_type->tp_align =
229 fund == ENUM ? int_align :
230 fund == STRUCT ? struct_align :
231 /* fund == UNION */ union_align;
232 tg->tg_type->tp_idf = idf;
234 stack_idf(idf, local_level);
238 apply_struct(fund, idf, tpp)
239 register struct idf *idf;
242 /* The occurrence of a struct, union or enum (depending on
243 fund) with tag idf is noted. It may or may not have been
244 declared before. Its type (complete or incomplete) is
247 register struct tag **tgp;
252 if (fund != (*tgp)->tg_type->tp_fund) {
253 error("tag %s indicates a %s, not a %s",
255 symbol2str((*tgp)->tg_type->tp_fund),
258 *tpp = (*tgp)->tg_type;
261 declare_struct(fund, idf, tpp);
266 register struct idf *idf;
269 /* The identifier idf is identified as a selector
271 If there is no such member, give a member with the same
273 If this fails too, a selector of type error_type is
276 register struct sdef **sdefp = &idf->id_sdef, *sdef;
278 /* Follow chain from idf, to meet tp. */
279 while ((sdef = *sdefp)) {
280 if (equal_type(sdef->sd_stype, tp, -999, 0)) /* ??? hack */
282 sdefp = &(*sdefp)->next;
285 /* Tp not met; take an identification. */
286 if (sdef = idf->id_sdef) {
287 /* There is an identification */
288 error("illegal use of selector %s", idf->id_text);
292 /* No luck; create an error entry. */
293 if (!is_anon_idf(idf))
294 error("unknown selector %s", idf->id_text);
295 *sdefp = sdef = new_sdef();
297 sdef->sd_stype = sdef->sd_type = error_type;
303 uniq_selector(idf_sdef)
304 register struct sdef *idf_sdef;
306 /* Returns true if idf_sdef (which is guaranteed to exist)
307 is unique for this level, i.e there is no other selector
308 on this level with the same name or the other selectors
309 with the same name have the same offset.
310 See /usr/src/cmd/sed/sed.h for an example of this absurd
314 register struct sdef *sdef = idf_sdef->next;
316 while (sdef && sdef->sd_level == idf_sdef->sd_level) {
317 if ( sdef->sd_type != idf_sdef->sd_type
318 || sdef->sd_offset != idf_sdef->sd_offset
320 return 0; /* ambiguity found */
330 add_field(szp, fd, fdtpp, idf, stp)
331 arith *szp; /* size of struct upto here */
332 register struct field *fd; /* bitfield, containing width */
333 register struct type **fdtpp; /* type of selector */
334 struct idf *idf; /* name of selector */
335 register struct type *stp; /* current struct descriptor */
337 /* The address where this selector is put is returned. If the
338 selector with specified width does not fit in the word, or
339 an explicit alignment is given, a new address is needed.
340 Note that the fields are packed into machine words.
342 int bits_in_type = (int) (*fdtpp)->tp_size * 8;
343 static int field_offset = (arith)0;
344 static struct type *current_struct = 0;
345 static int bits_declared; /* nr of bits used in *field_offset */
347 if (current_struct != stp) {
348 /* This struct differs from the last one
351 current_struct = stp;
354 if ( fd->fd_width < 0 ||
355 (fd->fd_width == 0 && !is_anon_idf(idf)) ||
356 fd->fd_width > bits_in_type
358 error("illegal field-width specified");
363 switch ((*fdtpp)->tp_fund) {
368 strict("non-portable field type");
370 /* right type; size OK? */
371 if ((int) (*fdtpp)->tp_size > (int) word_size) {
372 error("bit field type %s does not fit in a word",
373 symbol2str((*fdtpp)->tp_fund));
380 /* wrong type altogether */
381 error("field type cannot be %s",
382 symbol2str((*fdtpp)->tp_fund));
387 if (field_busy == 0) {
388 /* align this selector on the next boundary :
389 the previous selector wasn't a bitfield.
391 field_offset = align(*szp, int_align);
392 *szp = field_offset + int_size;
393 stp->tp_align = lcm(stp->tp_align, int_align);
398 if (fd->fd_width > bits_in_type - bits_declared) {
399 /* field overflow: fetch next memory unit
401 field_offset = align(*szp, int_align);
402 *szp = field_offset + int_size;
403 stp->tp_align = lcm(stp->tp_align, int_align);
404 bits_declared = fd->fd_width;
407 if (fd->fd_width == 0)
408 /* next field should be aligned on the next boundary.
409 This will take care that no field will fit in the
410 space allocated upto here.
412 bits_declared = bits_in_type + 1;
413 else /* the bitfield fits in the current field */
414 bits_declared += fd->fd_width;
416 /* Arrived here, the place where the selector is stored in the
418 Now we need a mask to use its value in expressions.
420 *fdtpp = construct_type(FIELD, *fdtpp, 0, (arith)0, NO_PROTO);
421 (*fdtpp)->tp_field = fd;
423 /* Set the mask right shifted. This solution avoids the
424 problem of having sign extension when using the mask for
425 extracting the value from the field-int.
426 Sign extension could occur on some machines when shifting
427 the mask to the left.
429 if (fd->fd_width >= 8*sizeof(arith)) fd->fd_mask = -1;
430 else fd->fd_mask = (1L << fd->fd_width) - 1;
432 if (options['r']) /* adjust the field at the right */
433 fd->fd_shift = bits_declared - fd->fd_width;
434 else /* adjust the field at the left */
435 fd->fd_shift = bits_in_type - bits_declared;
437 if (stp->tp_fund == UNION) bits_declared = 0;
441 #endif /* NOBITFIELD */
445 is_struct_or_union(fund)
448 return fund == STRUCT || fund == UNION;
451 /* Greatest Common Divisor
467 /* Least Common Multiple
473 return m * (n / gcd(m, n));