V8/usr/src/cmd/cyntax/cem/type.c

Compare this file to the similar file:
Show the results in this format:

#include	"cem.h"
#define	STD_OBJ	1
#include	"stdobj.h"
#include	"symbol.h"
#include	"type.h"

/*
 *	Type creation routines.
 */

/*
 *	We keep a cache of data objects rather than allowing malloc
 *	to inefficiently recycle them.
 */
static e_elt	*e_elt_free;
static s_elt	*s_elt_free;
static u_elt	*u_elt_free;
static e_data	*e_data_free;
static s_data	*s_data_free;
static u_data	*u_data_free;
static type	*type_free;

/*
 *	Allocation routines.
 */
static type	*
new_type()
{
	register type	*p;

	if (type_free == NULL)
		return talloc(type);

	p = type_free;
	type_free = p->t_subtype;
	return p;
}

static void
free_e_elt(p)
e_elt	*p;
{
	p->e_next = e_elt_free;
	e_elt_free = p;
}

static void
free_s_elt(p)
s_elt	*p;
{
	p->s_next = s_elt_free;
	s_elt_free = p;
}

static void
free_u_elt(p)
u_elt	*p;
{
	p->u_next = u_elt_free;
	u_elt_free = p;
}

static void
free_type(p)
type	*p;
{
	p->t_subtype = type_free;
	type_free = p;
}

static void
free_e_data(p)
e_data	*p;
{
	p->e_u.e_n = e_data_free;
	e_data_free = p;
}

static void
free_s_data(p)
s_data	*p;
{
	p->s_u.s_n = s_data_free;
	s_data_free = p;
}

static void
free_u_data(p)
u_data	*p;
{
	p->u_u.u_n = u_data_free;
	u_data_free = p;
}

static void
free_elist(p)
register e_elt	*p;
{
	register e_elt	*q;

	while (p != NULL)
	{
		q = p->e_next;
		p->e_next = e_elt_free;
		e_elt_free = p;
		p = q;
	}
}

static void
free_slist(p)
register s_elt	*p;
{
	register s_elt	*q;

	while (p != NULL)
	{
		q = p->s_next;
		p->s_next = s_elt_free;
		s_elt_free = p;
		p = q;
	}
}

static void
free_ulist(p)
register u_elt	*p;
{
	register u_elt	*q;

	while (p != NULL)
	{
		q = p->u_next;
		p->u_next = u_elt_free;
		u_elt_free = p;
		p = q;
	}
}

void
delete_type(p)
register type	*p;
{
	switch (p->t_type)
	{
	case t_enum:
		free_elist(p->d.e->e_list);
		p->d.e->e_u.e_n = e_data_free;
		e_data_free = p->d.e;
		break;

	case t_structof:
		free_slist(p->d.s->s_list);
		p->d.s->s_u.s_n = s_data_free;
		s_data_free = p->d.s;
		break;

	case t_unionof:
		free_ulist(p->d.u->u_list);
		p->d.u->u_u.u_n = u_data_free;
		u_data_free = p->d.u;
	}

	p->t_subtype = type_free;
	type_free = p;
}

/*
 *	Constructors.
 */
static type	*
make_enum(n, f, l)
symbol	*n;
symbol	*f;
long	l;
{
	register type	*p;
	register e_data	*e;

	if (e_data_free == NULL)
		e = talloc(e_data);
	else
	{
		e = e_data_free;
		e_data_free = e->e_u.e_n;
	}

	p = new_type();
	p->t_type = t_enum;
	p->d.e = e;
	e->e_file = f;
	e->e_line = l;
	e->e_name = n;
	e->e_list = NULL;
	return p;
}

static type	*
make_struct(n, f, l)
symbol	*n;
symbol	*f;
long	l;
{
	register type	*p;
	register s_data	*s;

	if (s_data_free == NULL)
		s = talloc(s_data);
	else
	{
		s = s_data_free;
		s_data_free = s->s_u.s_n;
	}

	p = new_type();
	p->t_type = t_structof;
	p->d.s = s;
	s->s_file = f;
	s->s_line = l;
	s->s_name = n;
	s->s_list = NULL;
	return p;
}

static type	*
make_union(n, f, l)
symbol	*n;
symbol	*f;
long	l;
{
	register type	*p;
	register u_data	*u;

	if (u_data_free == NULL)
		u = talloc(u_data);
	else
	{
		u = u_data_free;
		u_data_free = u->u_u.u_n;
	}

	p = new_type();
	p->t_type = t_unionof;
	p->d.u = u;
	u->u_file = f;
	u->u_line = l;
	u->u_name = n;
	u->u_list = NULL;
	return p;
}

/*
 *	Elaborators.
 */
static void
elab_enum(p, f, l, m)
type	*p;
symbol	*f;
long	l;
long	m;
{
	register e_data	*e;
	register e_elt	**n;
	register long	l0;

	e = p->d.e;
	e->e_file = f;
	e->e_line = l;
	n = &e->e_list;
	l0 = m;

	do
	{
		if (e_elt_free == NULL)
			*n = talloc(e_elt);
		else
		{
			*n = e_elt_free;
			e_elt_free = (*n)->e_next;
		}

		(*n)->e_name = str_trans[l0];
		(*n)->e_value = getv();
		n = &(*n)->e_next;
	}
	while ((l0 = getv()) != 0);

	*n = NULL;
	e->e_low = getu();
	e->e_high = getu();
}

static void
elab_struct(p, f, l)
type	*p;
symbol	*f;
long	l;
{
	register s_data	*s;
	register s_elt	**n;
	register long	l0;

	s = p->d.s;
	s->s_file = f;
	s->s_line = l;
	n = &s->s_list;

	l0 = getv();

	do
	{
		if (s_elt_free == NULL)
			*n = talloc(s_elt);
		else
		{
			*n = s_elt_free;
			s_elt_free = (*n)->s_next;
		}

		(*n)->s_name = str_trans[l0];
		(*n)->s_ptype.index = getv();
		(*n)->s_offset = getv();
		n = &(*n)->s_next;
	}
	while ((l0 = getv()) != 0);

	*n = NULL;
	s->s_size = getv();
}

static void
elab_union(p, f, l)
type	*p;
symbol	*f;
long	l;
{
	register u_data	*u;
	register u_elt	**n;
	register long	l0;

	u = p->d.u;
	u->u_file = f;
	u->u_line = l;
	n = &u->u_list;

	l0 = getv();

	do
	{
		if (u_elt_free == NULL)
			*n = talloc(u_elt);
		else
		{
			*n = u_elt_free;
			u_elt_free = (*n)->u_next;
		}

		(*n)->u_name = str_trans[l0];
		(*n)->u_ptype.index = getv();
		n = &(*n)->u_next;
	}
	while ((l0 = getv()) != 0);

	*n = NULL;
	u->u_size = getv();
}

/*
 *	Enter types from input file.  Construct type translation table.
 */
void
enter_types(n)
register long	n;
{
	register int	i;
	register type	*p;
	register type	**v;

	v = (type **)salloc(n * sizeof (type *));
	type_trans = v;

	while (data_ptr < data_end)
	{
		register long	l0;
		register long	l1;
		register long	l2;

		i = getd();

		switch (obj_item(i))
		{
		case i_data:
			skip();
			skip();
			skip();

			loop
			{
				i = getd();

				switch (obj_item(i))
				{
				case d_addr:
					skip4();
					continue;

				case d_bytes:
					if (obj_id(i) == 0)
						l0 = getv();
					else
						l0 = obj_id(i);

					data_ptr += l0;
					continue;

				case d_end:
					break;

				case d_istring:
					if (obj_id(i) == 0)
						l0 = getv();
					else
						l0 = obj_id(i);

					str_num++;
					data_ptr += l0;
					continue;

				case d_irstring:
					if (obj_id(i) == 0)
						l0 = getv();
					else
						l0 = obj_id(i);

					str_num++;
					data_ptr += l0;
					skip4();
					continue;

				case d_space:
					if (obj_id(i) == 0)
						skip();

					continue;

				case d_string:
					skip();
					continue;

				case d_reloc:
				case d_rstring:
					skip();
					skip4();
					continue;

				default:
					fprintf(stderr, "%s: unknown data id %d\n", my_name, i);
					exit(1);
				}

				break;
			}

			break;

		case i_lib:
			in_lib = 1;
			src_file = str_trans[getv()];
			break;

		case i_src:
			in_lib = 0;
			src_file = str_trans[getv()];
			break;

		case i_string:
			if (obj_id(i) == 0)
				l0 = getv();
			else
				l0 = obj_id(i);

			data_ptr += l0;
			break;

		case i_type:
			switch (obj_id(i))
			{
			case t_arrayof:
				p = talloc(type);
				p->t_type = t_arrayof;
				p->d.dim = getv();
				p->t_subindex = getv();
				v[type_index++] = p;
				break;

			case t_basetype:
				p = talloc(type);
				p->t_type = t_basetype;
				p->d.mask = getd();
				v[type_index++] = p;
				break;

			case t_bitfield:
				p = talloc(type);
				p->t_type = t_bitfield;
				p->d.size = getv();
				p->t_subindex = getv();
				v[type_index++] = p;
				break;

			case t_dimless:
				p = talloc(type);
				p->t_type = t_dimless;
				p->t_subindex = getv();
				v[type_index++] = p;
				break;

			case t_elaboration:
				l0 = getv();
				l1 = getv();
				l2 = getv();

				switch (i = obj_id(getd()))
				{
				case t_enum:
					elab_enum(v[l0], str_trans[l1], l2, getv());
					break;

				case t_structof:
					elab_struct(v[l0], str_trans[l1], l2);
					break;

				case t_unionof:
					elab_union(v[l0], str_trans[l1], l2);
					break;

				default:
					fprintf(stderr, "%s: unknown elaboration id %d\n", my_name, i);
					exit(1);
				}

				break;

			case t_enum:
				l0 = getv();
				l1 = getv();
				l2 = getv();
				v[type_index] = make_enum(str_trans[l0], str_trans[l1], l2);
				l0 = getv();

				if (l0 != 0)
					elab_enum(v[type_index], str_trans[l1], l2, l0);
				type_index++;
				break;

			case t_ftnreturning:
				p = talloc(type);
				p->t_type = t_ftnreturning;
				p->t_subindex = getv();
				v[type_index++] = p;
				break;

			case t_ptrto:
				p = talloc(type);
				p->t_type = t_ptrto;
				p->t_subindex = getv();
				v[type_index++] = p;
				break;

			case t_structof:
				l0 = getv();
				l1 = getv();
				l2 = getv();
				v[type_index++] = make_struct(str_trans[l0], str_trans[l1], l2);
				break;

			case t_unionof:
				l0 = getv();
				l1 = getv();
				l2 = getv();
				v[type_index++] = make_union(str_trans[l0], str_trans[l1], l2);
				break;

			default:
				fprintf(stderr, "%s: unknown type id %d\n", my_name, obj_id(i));
				exit(1);
			}

			break;

		case i_var:
			switch (obj_id(i))
			{
			case v_arglist:
				skip();
				skip();
				skip();

				while (getv() != 0)
				{
					skip();
					skip();
					skip();
				}

				break;

			case v_array_size:
				skip();
				skip();
				break;

			case v_call:
				skip();
				skip();
				skip();

				while (getv() != 0)
					;

				break;

			case v_auto:
			case v_block_static:
			case v_global:
			case v_implicit_function:
			case v_static:
				skip();
				skip();
				skip();
				skip();
				break;

			case v_varargs:
				skip();
				skip();
				break;

			default:
				fprintf(stderr, "%s: unknown var id %d\n", my_name, obj_id(i));
				exit(1);
			}

			break;

		default:
			fprintf(stderr, "%s: unknown obj_item %d\n", my_name, obj_item(i));
			exit(1);
		}
	}

	fix_types(n);
}