ack/lang/cem/cemcom/dumpidf.c

368 lines
7.4 KiB
C
Raw Normal View History

1986-03-10 13:07:55 +00:00
/* $Header$ */
/* DUMP ROUTINES */
#include "debug.h"
#ifdef DEBUG
#include "nopp.h"
#include "nobitfield.h"
#include "arith.h"
#include "stack.h"
#include "idf.h"
#include "def.h"
#include "type.h"
#include "struct.h"
#include "field.h"
#include "Lpars.h"
#include "label.h"
#include "expr.h"
/* Some routines (symbol2str, token2str, type2str) which should have
* yielded strings are written to yield a pointer to a transient piece
* of memory, containing the string, since this is the only reasonable
* thing to do in C. `Transient' means that the result may soon
* disappear, which is generally not a problem, since normally it is
* consumed immediately. Sometimes we need more than one of them, and
* MAXTRANS is the maximum number we will need simultaneously.
*/
#define MAXTRANS 6
extern char options[];
extern char *sprintf();
extern struct idf *idf_hashtable[];
extern char *symbol2str(), *type2str(), *next_transient();
enum sdef_kind {selector, field}; /* parameter for dumpsdefs */
static int dumplevel;
static
newline() {
int dl = dumplevel;
printf("\n");
while (dl >= 2) {
printf("\t");
dl -= 2;
}
if (dl)
printf(" ");
}
dumpidftab(msg, opt)
char msg[];
{
/* Dumps the identifier table in readable form (but in
arbitrary order).
Unless opt & 1, macros are not dumped.
Unless opt & 2, reserved identifiers are not dumped.
Unless opt & 4, universal identifiers are not dumped.
*/
int i;
printf(">>> DUMPIDF, %s (start)", msg);
dumpstack();
for (i = 0; i < HASHSIZE; i++) {
struct idf *notch = idf_hashtable[i];
while (notch) {
dumpidf(notch, opt);
notch = notch->next;
}
}
newline();
printf(">>> DUMPIDF, %s (end)\n", msg);
}
dumpstack() {
/* Dumps the identifier stack, starting at the top.
*/
struct stack_level *stl = local_level;
while (stl) {
struct stack_entry *se = stl->sl_entry;
newline();
printf("%3d: ", stl->sl_level);
while (se) {
printf("%s ", se->se_idf->id_text);
se = se->next;
}
stl = stl->sl_previous;
}
printf("\n");
}
dumpidf(idf, opt)
struct idf *idf;
{
/* All information about the identifier idf is divulged in a
hopefully readable format.
*/
int started = 0;
if (!idf)
return;
#ifndef NOPP
if ((opt&1) && idf->id_macro) {
if (!started++) {
newline();
printf("%s:", idf->id_text);
}
printf(" macro");
}
#endif NOPP
if ((opt&2) && idf->id_reserved) {
if (!started++) {
newline();
printf("%s:", idf->id_text);
}
printf(" reserved: %d;", idf->id_reserved);
}
if (idf->id_def && ((opt&4) || idf->id_def->df_level)) {
if (!started++) {
newline();
printf("%s:", idf->id_text);
}
dumpdefs(idf->id_def, opt);
}
if (idf->id_sdef) {
if (!started++) {
newline();
printf("%s:", idf->id_text);
}
dumpsdefs(idf->id_sdef, selector);
}
if (idf->id_struct) {
if (!started++) {
newline();
printf("%s:", idf->id_text);
}
dumptags(idf->id_struct);
}
if (idf->id_enum) {
if (!started++) {
newline();
printf("%s:", idf->id_text);
}
dumptags(idf->id_enum);
}
}
dumpdefs(def, opt)
register struct def *def;
{
dumplevel++;
while (def && ((opt&4) || def->df_level)) {
newline();
printf("L%d: %s %s%s%s%s%s %lo;",
def->df_level,
symbol2str(def->df_sc),
(def->df_register != REG_NONE) ? "reg " : "",
def->df_initialized ? "init'd " : "",
def->df_used ? "used " : "",
type2str(def->df_type),
def->df_sc == ENUM ? ", =" : " at",
def->df_address
);
def = def->next;
}
dumplevel--;
}
dumptags(tag)
struct tag *tag;
{
dumplevel++;
while (tag) {
register struct type *tp = tag->tg_type;
register int fund = tp->tp_fund;
newline();
printf("L%d: %s %s",
tag->tg_level,
fund == STRUCT ? "struct" :
fund == UNION ? "union" :
fund == ENUM ? "enum" : "<UNKNOWN>",
tp->tp_idf->id_text
);
if (is_struct_or_union(fund)) {
printf(" {");
dumpsdefs(tp->tp_sdef, field);
newline();
printf("}");
}
printf(";");
tag = tag->next;
}
dumplevel--;
}
dumpsdefs(sdef, sdk)
struct sdef *sdef;
enum sdef_kind sdk;
{
/* Since sdef's are members of two chains, there are actually
two dumpsdefs's, one following the chain of all selectors
belonging to the same idf, starting at idf->id_sdef;
and the other following the chain of all selectors belonging
to the same struct, starting at stp->tp_sdef.
*/
dumplevel++;
while (sdef) {
newline();
printf("L%d: ", sdef->sd_level);
#ifndef NOBITFIELD
if (sdk == selector)
#endif NOBITFIELD
printf("selector %s at offset %lu in %s;",
type2str(sdef->sd_type),
sdef->sd_offset, type2str(sdef->sd_stype)
);
#ifndef NOBITFIELD
else printf("field %s at offset %lu;",
type2str(sdef->sd_type), sdef->sd_offset
);
#endif NOBITFIELD
sdef = (sdk == selector ? sdef->next : sdef->sd_sdef);
}
dumplevel--;
}
char *
type2str(tp)
struct type *tp;
{
/* Yields a pointer to a one-line description of the type tp.
*/
char *buf = next_transient();
int ops = 1;
buf[0] = '\0';
if (!tp) {
sprintf(buf, "<NILTYPE>");
return buf;
}
sprintf(buf, "(@%lx, #%ld, &%d) ", tp, (long)tp->tp_size, tp->tp_align);
while (ops) {
switch (tp->tp_fund) {
case POINTER:
sprintf(buf, "%spointer to ", buf);
break;
case ARRAY:
sprintf(buf, "%sarray [%ld] of ", buf, tp->tp_size);
break;
case FUNCTION:
sprintf(buf, "%sfunction yielding ", buf);
break;
default:
sprintf(buf, "%s%s%s", buf,
tp->tp_unsigned ? "unsigned " : "",
symbol2str(tp->tp_fund)
);
if (tp->tp_idf)
sprintf(buf, "%s %s", buf,
tp->tp_idf->id_text);
#ifndef NOBITFIELD
if (tp->tp_field) {
struct field *fd = tp->tp_field;
sprintf(buf, "%s [s=%ld,w=%ld]", buf,
fd->fd_shift, fd->fd_width);
}
#endif NOBITFIELD
ops = 0;
break;
}
tp = tp->tp_up;
}
return buf;
}
char * /* the ultimate transient buffer supplier */
next_transient() {
static int bnum;
static char buf[MAXTRANS][300];
if (++bnum == MAXTRANS)
bnum = 0;
return buf[bnum];
}
print_expr(msg, expr)
char msg[];
struct expr *expr;
{
/* Provisional routine to print an expression preceded by a
message msg.
*/
if (options['x']) {
printf("\n%s: ", msg);
printf("(L=line, T=type, r/lV=r/lvalue, F=flags, D=depth)\n");
p1_expr(0, expr);
}
}
p1_expr(lvl, expr)
struct expr *expr;
{
extern char *type2str(), *symbol2str();
p1_indent(lvl);
if (!expr) {
printf("NILEXPR\n");
return;
}
printf("expr: L=%u, T=%s, %cV, F=%02o, D=%d, %s: ",
expr->ex_line,
type2str(expr->ex_type),
expr->ex_lvalue ? 'l' : 'r',
expr->ex_flags,
expr->ex_depth,
expr->ex_class == Value ? "Value" :
expr->ex_class == String ? "String" :
expr->ex_class == Float ? "Float" :
expr->ex_class == Oper ? "Oper" :
expr->ex_class == Type ? "Type" : "UNKNOWN CLASS"
);
switch (expr->ex_class) {
struct value *v;
struct oper *o;
case Value:
v = &expr->ex_object.ex_value;
if (v->vl_idf)
printf("%s + ", v->vl_idf->id_text);
printf(expr->ex_type->tp_unsigned ? "%lu\n" : "%ld\n",
v->vl_value);
break;
case String:
printf("%s\n", expr->SG_VALUE);
break;
case Float:
printf("%s\n", expr->FL_VALUE);
break;
case Oper:
o = &expr->ex_object.ex_oper;
printf("\n");
p1_expr(lvl+1, o->op_left);
p1_indent(lvl); printf("%s\n", symbol2str(o->op_oper));
p1_expr(lvl+1, o->op_right);
break;
case Type:
printf("\n");
break;
default:
printf("UNKNOWN CLASS\n");
break;
}
}
p1_indent(lvl) {
while (lvl--)
printf(" ");
}
#endif DEBUG