aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Documentation/types.rst
blob: 5c10725fa71aa549bfb050027531f7dc30532d48 (plain)
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
********************
Sparse's 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.