After simplification the structures are as follows:

The top-most scope contains of a double-linked list of declarations.

                   Declarations
		   ------------

Each declaration declares one of the following:

* a struct, union, enum
	The `identifier' field of the declaration struct is NULL in this
	case. The `type_name' field contains the struct, union, enum
	definition.
	The `storage', `mod_inline' fields don't contain any info.

* a type
	The `identifier' field of the declaration struct contains the
	name of the new type. The `type_name' field contains the
	type definitions.
	The `storage' field contains STORAGE_TYPEDEF.

* a variable
	The `identifier' contains the name of the variable.
	`type_name' is the type of the variable.
	If `storage' is STORAGE_EXTERN this is only an extern declaration.
	In case of STORAGE_STATIC it is a local variable. Otherwise
	(STORAGE_NONE) it is a global variable.
	STORAGE_AUTO and STORAGE_REGISTER define function local
	variables. Parameters are marked STORAGE_PARAM.
	If `initializer' field contains the initializer expressions if
	it isn't NULL.

* a function
	The `identifier' contains the name of the function.
	`type_name' is the type of the function. The type contains
	the parameter list.
	If `storage' is STORAGE_EXTERN this is only an extern declaration.
	It also is only a forward declaration if the `stmt' field is NULL.
	In case of STORAGE_STATIC it is a local function. Otherwise
	(STORAGE_NONE) it is a global function.
	`stmt' contains the code.
	The `mod_inline' marks functions to be inlined.
	Inlining is done during simplification. After simplification
	no inline function remain.
	`attr_noreturn' is true if the function doesn't return
	(like the exit/abort functions).

`nbits' is an expression only valid in struct/union scopes. It is not
used, yet.

`clone' is used during inlining only.

`assign_expr', `acount', `wcount' and `rcount' are used during optimization
only.

`live_noreg', `move_first', `move_last', `storage_class',
`choices', `storage_register', `spills' `degree',
`conflict_first', `conflict_last',
`conflict_save_first', `conflict_save_last' are used during 
register allocation only.

                 Code
		 ----

The `stmt' field of a declaration contains the code and the variables
of a function. The `stmt' points to a stmt struct of type STMT_BLOCK.
STMT_BLOCKs have a `scope' field pointing to a scope (containing a double
linked list of declarations; see above) and `stmt_first' and `stmt_last'
fields being the head/tail of a double linked list of stmt structs.

Each stmt struct is one of the following:

* a label
	In this case the `identifier' field contains a pointer to the
	name of the label. The `stmt0' field always contains a pointer
	to a null-statement (type = STMT_NULL).

* an expression statement
	The expression is an assignment or a function-call expression.

* an if statement
	The `expr0' field contains a pointer to an expression of type
	EXPR_EQUAL, EXPR_NOT_EQUAL, EXPR_LESS, EXPR_LESS_EQUAL,
	EXPR_GREATER, EXPR_GREATER_EQUAL.
	The `stmt0' pointer always points to a goto-statement.

* a switch statement
	The `expr0' field contains a pointer to an expression.
	The expression is always of type EXPR_IDENTIFIER.
	The `stmt0' pointer points to a block. The block (in a
	stmt struct) doesn't contain any declarations but only
	case and default statements. The case statements `expr0' fields
	always point to an expression of type EXPR_INTEGER.
	Case and default statements both always have `stmt0' pointers
	pointing to a goto statement. Switch statements always have
	a default statement.

* a goto statement
	All goto statements only have a valid `identifier' member
	containing a pointer to the name of the label to go to.

* a return statement
	Each function have one and only one return statement as the
	last statement in the statement list.
	In case the function is no `void' function the `expr0' member
	points to the return expression. The return expression is
	of type EXPR_IDENTIFIER or a constant (EXPR_INTEGER,
	EXPR_REAL, EXPR_AMPHERSAND).

* an asm statement
	The `code' member points to the string containing the asm
	statements.
	The `output', `input' and `change' fields (if non-NULL)
	contain a double linked list of constraints. Each constraint
	has a `string' field with the register/memory definition
	and an `expr' field with the expression to pass from/to
	the code.

* a va_start/va_end statement
	The `expr0' field containts the `args' parameter. The second
	parameter of the va_start call is stored in `expr1'.

No other types of statements are valid after simplification.
Optimization will stay with this constraints.

                  Expressions
		  -----------

All expressions are as follows:

* assignment expressions
	The `expr0' pointer points to the lhs of the assignment.
	The `expr1' field contains the pointer of the rhs.

* function/procedure calls
	The `expr0' is the name of the function to be called or
	a pointer to such a function.
	`expr1' is a pointer to an EXPR_LIST element which has
	the `first' and `last' fields used. `first' and `last'
	form a double linked list of `expr' objects. Each
	such expression holds one parameter for the function
	call. If no parameters are present, `first' and `last'
	are both NULL. All parameters are simple expressions.

Simple expressions are:

* an identifier
	`type' is EXPR_IDENTIFIER. `declaration' points to the
	declaration of the identifier. The declaration contains
	the name, type, storage type, etc. of the identifier.

* a constant
	`type' is EXPR_INTEGER, EXPR_REAL. `type_name' contains
	the type of the constant (int8, uint8, ..., uint64,
	float32, float64, float80). `integer' or `real' contain
	the constant.
	
* an address
	`type' is EXPR_TYPE_CONVERSION, `expr0' is EXPR_AMPHERSAND
	and `expr0->expr0' is EXPR_IDENTIFIER in this case.
	`expr0' might be EXPR_IDENTIFIER if the identifier is
	an array.
	Examples are expressions like "(int) &var" or "(int) array".

Unary expressions are:

* a star expression
	`type' is EXPR_STAR. `expr0' is a type conversion and
	`expr0->expr0' is an expression containing an address.
	An example expression is "*(int *) var".

* a type conversion
	`type' is EXPR_TYPE_CONVERSION. `type_name' contains the
	type be converted to. `expr0' is the expression to be converted.

* a NEG or INV expression
	`type' is EXPR_NEG or EXPR_INV. `expr0' containts the pointer
	to the expression to be negated/inverted.

Binary expressions are:
	`type' might contain: EXPR_ADD, EXPR_SUB, EXPR_MUL, EXPR_DIV,
	EXPR_MOD for the standard arithmetic operations, EXPR_LEFT,
	EXPR_RIGHT for shift operations, EXPR_EQUAL, EXPR_NOT_EQUAL,
	EXPR_LESS, EXPR_LESS_EQUAL, EXPR_GREATER, EXPR_GREATER_EQUAL
	for comparisons. `expr0' and `expr1' contain the two
	operands.

No other expressions remain after simplification/optimization steps
are performed.
