*********** Type System *********** struct symbol is used to represent symbols & types but most parts pertaining to the types are in the field 'ctype'. For the purpose of this document, things can be simplified into: .. code-block:: c struct symbol { enum type type; // SYM_... struct ctype { struct symbol *base_type; unsigned long modifiers; unsigned long alignment; struct context_list *contexts; struct indent *as; }; }; Some bits, also related to the type, are in struct symbol itself: * type * size_bits * rank * variadic * string * designated_init * forced_arg * accessed * transparent_union * ``base_type`` is used for the associated base type. * ``modifiers`` is a bit mask for type specifiers (MOD_UNSIGNED, ...), type qualifiers (MOD_CONST, MOD_VOLATILE), storage classes (MOD_STATIC, MOD_EXTERN, ...), as well for various attributes. It's also used internally to keep track of some states (MOD_ACCESS or MOD_ADDRESSABLE). * ``alignment`` is used for the alignment, in bytes. * ``contexts`` is used to store the informations associated with the attribute ``context()``. * ``as`` is used to hold the identifier of the attribute ``address_space()``. Kind of types ============= SYM_BASETYPE ------------ Used by integer, floating-point, void, 'type', 'incomplete' & bad types. For integer types: * .ctype.base_type points to ``int_ctype``, the generic/abstract integer type * .ctype.modifiers has MOD_UNSIGNED/SIGNED/EXPLICITLY_SIGNED set accordingly. For floating-point types: * .ctype.base_type points to ``fp_ctype``, the generic/abstract float type * .ctype.modifiers is zero. For the other base types: * .ctype.base_type is NULL * .ctype.modifiers is zero. SYM_NODE -------- It's used to make variants of existing types. For example, it's used as a top node for all declarations which can then have their own modifiers, address_space, contexts or alignment as well as the declaration's identifier. Usage: * .ctype.base_type points to the unmodified type (which must not be a SYM_NODE itself) * .ctype.modifiers, .as, .alignment, .contexts will contains the 'variation' (MOD_CONST, the attributes, ...). SYM_PTR ------- For pointers: * .ctype.base_type points to the pointee type * .ctype.modifiers & .as are about the pointee too! SYM_FN ------ For functions: * .ctype.base_type points to the return type * .ctype.modifiers & .as should be about the function itself but some return type's modifiers creep here (for example, in int foo(void), MOD_SIGNED will be set for the function). SYM_ARRAY --------- For arrays: * .ctype.base_type points to the underlying type * .ctype.modifiers & .as are a copy of the parent type (and unused)? * for literal strings, the modifier also contains MOD_STATIC * sym->array_size is *expression* for the array size. SYM_STRUCT ---------- For structs: * .ctype.base_type is NULL * .ctype.modifiers & .as are not used? * .ident is the name tag. SYM_UNION --------- Same as for structs. SYM_ENUM -------- For enums: * .ctype.base_type points to the underlying type (integer) * .ctype.modifiers contains the enum signedness * .ident is the name tag. SYM_BITFIELD ------------ For bitfields: * .ctype.base_type points to the underlying type (integer) * .ctype.modifiers & .as are a copy of the parent type (and unused)? * .bit_size is the size of the bitfield. SYM_RESTRICT ------------ Used for bitwise types (aka 'restricted' types): * .ctype.base_type points to the underlying type (integer) * .ctype.modifiers & .as are like for SYM_NODE and the modifiers are inherited from the base type with MOD_SPECIFIER removed * .ident is the typedef name (if any). SYM_FOULED ---------- Used for bitwise types when the negation op (~) is used and the bit_size is smaller than an ``int``. There is a 1-to-1 mapping between a fouled type and its parent bitwise type. Usage: * .ctype.base_type points to the parent type * .ctype.modifiers & .as are the same as for the parent type * .bit_size is bits_in_int. SYM_TYPEOF ---------- Should not be present after evaluation: * .initializer points to the expression representing the type * .ctype is not used. Typeofs with a type as argument are directly evaluated during parsing. SYM_LABEL --------- Used for labels only. SYM_KEYWORD ----------- Used for parsing only. SYM_BAD ------- Should not be used. SYM_UNINTIALIZED ---------------- Should not be used.