1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
***********
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.
|