/*
 * C compiler
 * ==========
 *
 * Copyright 1989, 1990, 1991 Christoph van Wuellen.
 * Credits to Matthew Brandt.
 * All commercial rights reserved.
 *
 * This compiler may be redistributed as long there is no
 * commercial interest. The compiler must not be redistributed
 * without its full sources. This notice must stay intact.
 *
 * History:
 *
 * 1989   starting an 68000 C compiler, starting with material
 *        originally by M. Brandt
 * 1990   68000 C compiler further bug fixes
 *        started i386 port (December)
 * 1991   i386 port finished (January)
 *        further corrections in the front end and in the 68000
 *        code generator.
 *        The next port will be a SPARC port
 */

#include	"c.h"
#include	"expr.h"
#include	"gen.h"
#include	"cglbdec.h"

put_sc(scl)
    enum e_sc       scl;
{
    switch (scl) {
      case sc_static:
	fprintf(list, "Static      ");
	break;
      case sc_auto:
	fprintf(list, "Auto        ");
	break;
      case sc_global:
	fprintf(list, "Global      ");
	break;
      case sc_external:
	fprintf(list, "External    ");
	break;
      case sc_type:
	fprintf(list, "Type        ");
	break;
      case sc_typedef:
	fprintf(list, "Typedef     ");
	break;
      case sc_const:
	fprintf(list, "Constant    ");
	break;
      case sc_member:
	fprintf(list, "Member      ");
	break;
      case sc_label:
	fprintf(list, "Label");
	break;
      case sc_ulabel:
	fprintf(list, "Undefined label");
	break;
    }
}

put_ty(tp)
    TYP            *tp;
{
    if (tp == 0)
	return;
    switch (tp->type) {
      case bt_void:
	fprintf(list, "void ");
	break;
      case bt_uchar:
	fprintf(list, "unsigned ");
      case bt_char:
	fprintf(list, "Char");
	break;
      case bt_ushort:
	fprintf(list, "unsigned ");
      case bt_short:
	fprintf(list, "Short");
	break;
      case bt_ulong:
	fprintf(list, "unsigned ");
      case bt_long:
	fprintf(list, "Long");
	break;
      case bt_float:
	fprintf(list, "Float");
	break;
      case bt_double:
	fprintf(list, "Double");
	break;
      case bt_pointer:
	if (tp->val_flag == 0)
	    fprintf(list, "Pointer to ");
	else
	    fprintf(list, "Array of ");
	put_ty(tp->btp);
	break;
      case bt_union:
	fprintf(list, "union ");
	goto ucont;
      case bt_struct:
	fprintf(list, "struct ");
ucont:	if (tp->sname == 0)
	    fprintf(list, "<no name> ");
	else
	    fprintf(list, "%s ", tp->sname);
	break;
      case bt_func:
	fprintf(list, "Function returning ");
	put_ty(tp->btp);
	break;
      case bt_bitfield:
	fprintf(list, "Bitfield offset=%d width=%d",
		(int) tp->bit_offset,
		(int) tp->bit_width);
	break;
      default:
	fatal("PUT_TY");
    }
}

list_var(sp, i)
    struct sym     *sp;
    int             i;
{
    int             j;
    nl();			/* start new line in the output file */
    if (sp->storage_class == sc_external && sp->used)
	put_external(sp->name);
    else if (sp->storage_class == sc_global && sp->value.i != -1)
	put_global(sp->name);

    /* sp->tp==0 if generated by call_library */
    if (sp->tp == 0 && sp->storage_class == sc_external)
	return;

    if (list_option) {
	for (j = i; j; --j)
	    fprintf(list, "    ");
	fprintf(list, "%-12s =%08X ", sp->name, sp->value.u);
    }
    if (list_option) {
	put_sc(sp->storage_class);
	put_ty(sp->tp);
	fprintf(list, "\n");
	if (sp->tp == 0)
	    return;
	if ((sp->tp->type == bt_struct || sp->tp->type == bt_union) &&
	    sp->storage_class == sc_type)
	    list_table(&(sp->tp->lst), i + 1);
    }
}

list_table(t, i)
    TABLE          *t;
    int             i;
{
    struct sym     *sp;
    sp = t->head;
    while (sp != NULL) {
	list_var(sp, i);
	sp = sp->next;
    }
}
