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 1.13 1994/06/27 07:59:26 ceriel Exp $ */
13 #include "nobitfield.h"
14 #include <flt_arith.h>
29 /* Some routines (symbol2str, type2str, qual2str) which should have
30 * yielded strings are written to yield a pointer to a transient piece
31 * of memory, containing the string, since this is the only reasonable
32 * thing to do in C. `Transient' means that the result may soon
33 * disappear, which is generally not a problem, since normally it is
34 * consumed immediately. Sometimes we need more than one of them, and
35 * MAXTRANS is the maximum number we will need simultaneously.
39 extern char options[];
41 extern char *sprint();
43 extern struct idf *idf_hashtable[];
44 extern char *symbol2str(), *type2str(), *qual2str(), *next_transient();
46 enum sdef_kind {selector, field}; /* parameter for dumpsdefs */
51 register int dl = dumplevel;
67 /* Dumps the identifier table in readable form (but in
69 Unless opt & 1, macros are not dumped.
70 Unless opt & 2, reserved identifiers are not dumped.
71 Unless opt & 4, universal identifiers are not dumped.
74 print(">>> DUMPIDF, %s (start)", msg);
76 idfappfun(dumpidf, opt);
78 print(">>> DUMPIDF, %s (end)\n", msg);
83 /* Dumps the identifier stack, starting at the top.
85 register struct stack_level *stl = local_level;
88 register struct stack_entry *se = stl->sl_entry;
91 print("%3d: ", stl->sl_level);
93 print("%s ", se->se_idf->id_text);
96 stl = stl->sl_previous;
102 register struct idf *idf;
104 /* All information about the identifier idf is divulged in a
105 hopefully readable format.
112 if ((opt&1) && idf->id_macro) {
115 print("%s:", idf->id_text);
120 if ((opt&2) && idf->id_reserved) {
123 print("%s:", idf->id_text);
125 print(" reserved: %d;", idf->id_reserved);
127 if (idf->id_def && ((opt&4) || idf->id_def->df_level)) {
130 print("%s:", idf->id_text);
132 dumpdefs(idf->id_def, opt);
137 print("%s:", idf->id_text);
139 dumpsdefs(idf->id_sdef, selector);
144 print("%s:", idf->id_text);
146 dumptags(idf->id_tag);
151 register struct def *def;
154 while (def && ((opt&4) || def->df_level)) {
156 print("L%d: %s %s%stype%s %lo; ",
158 symbol2str(def->df_sc),
159 def->df_initialized ? "init'd " : "",
160 def->df_used ? "used " : "",
161 def->df_sc == ENUM ? ", =" : " at",
165 def->df_file ? def->df_file : "NO_FILE", def->df_line);
166 dumptype(def->df_type);
173 register struct tag *tag;
177 register struct type *tp = tag->tg_type;
178 register int fund = tp->tp_fund;
183 fund == STRUCT ? "struct" :
184 fund == UNION ? "union" :
185 fund == ENUM ? "enum" : "<UNKNOWN>",
188 if (is_struct_or_union(fund)) {
190 dumpsdefs(tp->tp_sdef, field);
201 register struct sdef *sdef;
204 /* Since sdef's are members of two chains, there are actually
205 two dumpsdefs's, one following the chain of all selectors
206 belonging to the same idf, starting at idf->id_sdef;
207 and the other following the chain of all selectors belonging
208 to the same struct, starting at stp->tp_sdef.
214 print("L%d: ", sdef->sd_level);
217 #endif /* NOBITFIELD */
218 print("selector %s at offset %lu in %s;",
219 type2str(sdef->sd_type),
220 sdef->sd_offset, type2str(sdef->sd_stype)
223 else print("field %s at offset %lu;",
224 type2str(sdef->sd_type), sdef->sd_offset
226 #endif /* NOBITFIELD */
227 sdef = (sdk == selector ? sdef->next : sdef->sd_sdef);
233 register struct proto *pl;
235 register struct type *type;
236 register int argcnt = 0;
239 print("dump proto type list (start)");
242 print("%d: %s", argcnt++,
243 pl->pl_flag & PL_FORMAL ?
244 (pl->pl_flag & PL_VOID ? "void" : "formal")
245 : (pl->pl_flag & PL_ELLIPSIS
246 ? "ellipsis" : "unknown" ));
248 if (type = pl->pl_type){
255 dumpidf(pl->pl_idf, 7);
261 print("dump proto type list (end)\n");
265 register struct type *tp;
278 print("(@%lx, #%ld, &%d) ", tp, (long)tp->tp_size, tp->tp_align);
281 print("%s", qual2str(tp->tp_typequal));
282 switch (tp->tp_fund) {
284 print("pointer to ");
287 print("array [%ld] of ", tp->tp_size);
292 print("with prototype");
294 dumpproto(tp->tp_proto);
301 print("%s%s ", tp->tp_unsigned ? "unsigned " : "",
302 symbol2str(tp->tp_fund));
304 print("%s ", tp->tp_idf->id_text);
306 if (tp->tp_fund == FIELD && tp->tp_field) {
307 struct field *fd = tp->tp_field;
309 print("[s=%ld,w=%ld] of ",
310 fd->fd_shift, fd->fd_width);
313 #endif /* NOBITFIELD */
317 if (ops) tp = tp->tp_up;
324 register struct type *tp;
326 /* Yields a pointer to a one-line description of the type tp.
328 char *buf = next_transient();
333 sprint(buf, "<NILTYPE>");
336 sprint(buf, "%s(@%lx, #%ld, &%d) ",
337 buf, tp, (long)tp->tp_size, tp->tp_align);
340 sprint(buf, "%s%s", buf, qual2str(tp->tp_typequal));
341 switch (tp->tp_fund) {
343 sprint(buf, "%spointer to ", buf);
346 sprint(buf, "%sarray [%ld] of ", buf, tp->tp_size);
349 sprint(buf, "%sfunction yielding ", buf);
352 sprint(buf, "%s%s%s ", buf,
353 tp->tp_unsigned ? "unsigned " : "",
354 symbol2str(tp->tp_fund)
357 sprint(buf, "%s %s ", buf,
358 tp->tp_idf->id_text);
360 if (tp->tp_fund == FIELD && tp->tp_field) {
361 struct field *fd = tp->tp_field;
363 sprint(buf, "%s [s=%ld,w=%ld] of ", buf,
364 fd->fd_shift, fd->fd_width);
367 #endif /* NOBITFIELD */
371 if (ops) tp = tp->tp_up;
380 char *buf = next_transient();
384 sprint(buf, "(none)");
386 sprint(buf, "%sconst ", buf);
387 if (qual & TQ_VOLATILE)
388 sprint(buf, "%svolatile ", buf);
390 return qual == 0 ? "" : buf;
393 GSTATIC char trans_buf[MAXTRANS][300];
395 char * /* the ultimate transient buffer supplier */
400 if (++bnum == MAXTRANS)
402 return trans_buf[bnum];
405 print_expr(msg, expr)
409 /* Provisional routine to print an expression preceded by a
413 print("\n%s: ", msg);
414 print("(L=line, T=type, r/lV=r/lvalue, F=flags, D=depth)\n");
420 register struct expr *expr;
427 print("expr: L=%u, T=%s, %cV, F=%03o, D=%d, %s: ",
429 type2str(expr->ex_type),
430 expr->ex_lvalue ? 'l' : 'r',
431 expr->ex_flags & 0xFF,
433 expr->ex_class == Value ? "Value" :
434 expr->ex_class == String ? "String" :
435 expr->ex_class == Float ? "Float" :
436 expr->ex_class == Oper ? "Oper" :
437 expr->ex_class == Type ? "Type" : "UNKNOWN CLASS"
439 switch (expr->ex_class) {
442 switch (expr->VL_CLASS) {
447 print("(Name) %s + ", expr->VL_IDF->id_text);
450 print("(Label) .%lu + ", expr->VL_LBL);
456 print(expr->ex_type->tp_unsigned ? "%lu\n" : "%ld\n",
465 bts2str(expr->SG_VALUE, expr->SG_LEN-1,
472 char buf[FLT_STRLEN];
474 flt_flt2str(&(expr->FL_ARITH), buf, FLT_STRLEN);
479 o = &expr->ex_object.ex_oper;
481 p1_expr(lvl+1, o->op_left);
483 print("%s <%s>\n", symbol2str(o->op_oper),
486 p1_expr(lvl+1, o->op_right);
492 print("UNKNOWN CLASS\n");