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: dumpidf.c,v 3.22 1994/06/24 12:03:23 ceriel Exp $ */
13 #include "nobitfield.h"
26 /* Some routines (symbol2str, token2str, type2str) which should have
27 * yielded strings are written to yield a pointer to a transient piece
28 * of memory, containing the string, since this is the only reasonable
29 * thing to do in C. `Transient' means that the result may soon
30 * disappear, which is generally not a problem, since normally it is
31 * consumed immediately. Sometimes we need more than one of them, and
32 * MAXTRANS is the maximum number we will need simultaneously.
36 extern char options[];
38 extern struct idf *idf_hashtable[];
39 extern char *symbol2str(), *type2str(), *next_transient();
41 enum sdef_kind {selector, field}; /* parameter for dumpsdefs */
47 register int dl = dumplevel;
61 /* Dumps the identifier table in readable form (but in
63 Unless opt & 1, macros are not dumped.
64 Unless opt & 2, reserved identifiers are not dumped.
65 Unless opt & 4, universal identifiers are not dumped.
69 print(">>> DUMPIDF, %s (start)", msg);
71 for (i = 0; i < HASHSIZE; i++) {
72 register struct idf *notch = idf_hashtable[i];
80 print(">>> DUMPIDF, %s (end)\n", msg);
85 /* Dumps the identifier stack, starting at the top.
87 register struct stack_level *stl = local_level;
90 register struct stack_entry *se = stl->sl_entry;
93 print("%3d: ", stl->sl_level);
95 print("%s ", se->se_idf->id_text);
98 stl = stl->sl_previous;
104 register struct idf *idf;
106 /* All information about the identifier idf is divulged in a
107 hopefully readable format.
114 if ((opt&1) && idf->id_macro) {
117 print("%s:", idf->id_text);
122 if ((opt&2) && idf->id_reserved) {
125 print("%s:", idf->id_text);
127 print(" reserved: %d;", idf->id_reserved);
129 if (idf->id_def && ((opt&4) || idf->id_def->df_level)) {
132 print("%s:", idf->id_text);
134 dumpdefs(idf->id_def, opt);
139 print("%s:", idf->id_text);
141 dumpsdefs(idf->id_sdef, selector);
143 if (idf->id_struct) {
146 print("%s:", idf->id_text);
148 dumptags(idf->id_struct);
153 print("%s:", idf->id_text);
155 dumptags(idf->id_enum);
160 register struct def *def;
163 while (def && ((opt&4) || def->df_level)) {
165 print("L%d: %s %s%s%s%s %lo;",
167 symbol2str(def->df_sc),
168 def->df_initialized ? "init'd " : "",
169 def->df_used ? "used " : "",
170 type2str(def->df_type),
171 def->df_sc == ENUM ? ", =" : " at",
175 def->df_file ? def->df_file : "NO_FILE", def->df_line);
182 register struct tag *tag;
186 register struct type *tp = tag->tg_type;
187 register int fund = tp->tp_fund;
192 fund == STRUCT ? "struct" :
193 fund == UNION ? "union" :
194 fund == ENUM ? "enum" : "<UNKNOWN>",
197 if (is_struct_or_union(fund)) {
199 dumpsdefs(tp->tp_sdef, field);
210 register struct sdef *sdef;
213 /* Since sdef's are members of two chains, there are actually
214 two dumpsdefs's, one following the chain of all selectors
215 belonging to the same idf, starting at idf->id_sdef;
216 and the other following the chain of all selectors belonging
217 to the same struct, starting at stp->tp_sdef.
223 print("L%d: ", sdef->sd_level);
226 #endif /* NOBITFIELD */
227 print("selector %s at offset %lu in %s;",
228 type2str(sdef->sd_type),
229 sdef->sd_offset, type2str(sdef->sd_stype)
232 else print("field %s at offset %lu;",
233 type2str(sdef->sd_type), sdef->sd_offset
235 #endif /* NOBITFIELD */
236 sdef = (sdk == selector ? sdef->next : sdef->sd_sdef);
243 register struct type *tp;
245 /* Yields a pointer to a one-line description of the type tp.
247 char *buf = next_transient();
252 sprint(buf, "<NILTYPE>");
256 sprint(buf, "%s(#%ld, &%d) ", buf, (long)tp->tp_size, tp->tp_align);
258 switch (tp->tp_fund) {
260 sprint(buf, "%spointer to ", buf);
263 sprint(buf, "%sarray [%ld] of ", buf, tp->tp_size);
266 sprint(buf, "%sfunction yielding ", buf);
269 sprint(buf, "%s%s%s", buf,
270 tp->tp_unsigned ? "unsigned " : "",
271 symbol2str(tp->tp_fund)
274 sprint(buf, "%s %s", buf,
275 tp->tp_idf->id_text);
278 struct field *fd = tp->tp_field;
280 sprint(buf, "%s [s=%ld,w=%ld] of ", buf,
281 fd->fd_shift, fd->fd_width);
284 #endif /* NOBITFIELD */
293 GSTATIC char trans_buf[MAXTRANS][300];
295 char * /* the ultimate transient buffer supplier */
300 if (++bnum == MAXTRANS)
302 return trans_buf[bnum];
305 print_expr(msg, expr)
309 /* Provisional routine to print an expression preceded by a
313 print("\n%s: ", msg);
314 print("(L=line, T=type, r/lV=r/lvalue, F=flags, D=depth)\n");
320 register struct expr *expr;
327 print("expr: L=%u, T=%s, %cV, F=%03o, D=%d, %s: ",
329 type2str(expr->ex_type),
330 expr->ex_lvalue ? 'l' : 'r',
331 expr->ex_flags & 0xFF,
333 expr->ex_class == Value ? "Value" :
334 expr->ex_class == String ? "String" :
336 expr->ex_class == Float ? "Float" :
338 expr->ex_class == Oper ? "Oper" :
339 expr->ex_class == Type ? "Type" : "UNKNOWN CLASS"
341 switch (expr->ex_class) {
344 switch (expr->VL_CLASS) {
349 print("(Name) %s + ", expr->VL_IDF->id_text);
352 print("(Label) .%lu + ", expr->VL_LBL);
358 print(expr->ex_type->tp_unsigned ? "%lu\n" : "%ld\n",
367 bts2str(expr->SG_VALUE, expr->SG_LEN-1,
374 print("%s\n", expr->FL_VALUE);
378 o = &expr->ex_object.ex_oper;
380 p1_expr(lvl+1, o->op_left);
382 print("%s <%s>\n", symbol2str(o->op_oper),
385 p1_expr(lvl+1, o->op_right);
391 print("UNKNOWN CLASS\n");