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.