2 * Symbol lookup and handling.
4 * Copyright (C) 2003 Linus Torvalds, all rights reserved.
19 struct symbol
*lookup_symbol(struct ident
*ident
, enum namespace ns
)
23 for (sym
= ident
->symbols
; sym
; sym
= sym
->next_id
) {
24 if (sym
->namespace == ns
)
30 struct symbol
*alloc_symbol(struct token
*token
, int type
)
32 struct symbol
*sym
= __alloc_symbol(0);
38 struct struct_union_info
{
40 unsigned long max_align
;
41 unsigned long bit_size
;
43 unsigned long bit_offset
;
46 static void examine_one_member(struct symbol
*sym
, void *_info
, int flags
)
48 struct struct_union_info
*info
= _info
;
49 unsigned long offset
= info
->offset
;
50 unsigned long bit_size
;
52 examine_symbol_type(sym
);
53 if (sym
->alignment
> info
->max_align
)
54 info
->max_align
= sym
->alignment
;
56 offset
+= sym
->alignment
-1;
57 offset
&= ~(sym
->alignment
-1);
59 info
->offset
= offset
+ (sym
->bit_size
>> 3);
61 bit_size
= (offset
<< 3) + sym
->bit_size
;
64 * In the case of a union, we want to get the _biggest_ size.
65 * For structures, this will always be true, since the offset
66 * ends up being cumulative.
68 if (bit_size
> info
->bit_size
)
69 info
->bit_size
= bit_size
;
72 static void examine_struct_union_type(struct symbol
*sym
, int advance
)
74 struct struct_union_info info
= { advance
, 1, 0, 0 };
75 unsigned long bit_size
, bit_align
;
77 symbol_iterate(sym
->symbol_list
, examine_one_member
, &info
);
78 bit_size
= info
.bit_size
;
79 bit_align
= (info
.max_align
<< 3)-1;
80 bit_size
= (bit_size
+ bit_align
) & ~bit_align
;
81 sym
->bit_size
= bit_size
;
82 sym
->alignment
= info
.max_align
;
86 * Fill in type size and alignment information for
87 * regular SYM_TYPE things.
89 void examine_symbol_type(struct symbol
* sym
)
91 unsigned int bit_size
, alignment
;
92 struct symbol
*base_type
;
93 unsigned long modifiers
;
104 examine_struct_union_type(sym
, 1);
107 examine_struct_union_type(sym
, 0);
111 sym
->bit_size
= BITS_IN_POINTER
;
113 sym
->alignment
= POINTER_ALIGNMENT
;
114 examine_symbol_type(sym
->ctype
.base_type
);
118 sym
->bit_size
= BITS_IN_ENUM
;
120 sym
->alignment
= ENUM_ALIGNMENT
;
127 base_type
= sym
->ctype
.base_type
;
128 modifiers
= sym
->ctype
.modifiers
;
130 if (base_type
== &void_type
) {
135 if (base_type
== &int_type
) {
136 bit_size
= BITS_IN_INT
;
137 if (modifiers
& MOD_LONGLONG
) {
138 bit_size
= BITS_IN_LONGLONG
;
139 } else if (modifiers
& MOD_LONG
) {
140 bit_size
= BITS_IN_LONG
;
141 } else if (modifiers
& MOD_SHORT
) {
142 bit_size
= BITS_IN_SHORT
;
143 } else if (modifiers
& MOD_CHAR
) {
144 bit_size
= BITS_IN_CHAR
;
146 alignment
= bit_size
>> 3;
147 if (alignment
> MAX_INT_ALIGNMENT
)
148 alignment
= MAX_INT_ALIGNMENT
;
149 } else if (base_type
== &fp_type
) {
150 bit_size
= BITS_IN_FLOAT
;
151 if (modifiers
& MOD_LONGLONG
) {
152 bit_size
= BITS_IN_LONGDOUBLE
;
153 } else if (modifiers
& MOD_LONG
) {
154 bit_size
= BITS_IN_DOUBLE
;
156 alignment
= bit_size
>> 3;
157 if (alignment
> MAX_FP_ALIGNMENT
)
158 alignment
= MAX_FP_ALIGNMENT
;
159 } else if (base_type
) {
160 examine_symbol_type(base_type
);
162 bit_size
= base_type
->bit_size
;
163 alignment
= base_type
->alignment
;
168 warn(sym
->token
, "unknown type %d", sym
->type
);
172 if (sym
->type
== SYM_ARRAY
) {
173 int array_size
= sym
->array_size
;
174 bit_size
*= sym
->array_size
;
175 if (array_size
== -1)
180 sym
->alignment
= alignment
;
181 sym
->bit_size
= bit_size
;
184 void bind_symbol(struct symbol
*sym
, struct ident
*ident
, enum namespace ns
)
187 warn(sym
->token
, "internal error: symbol type already bound");
191 sym
->next_id
= ident
->symbols
;
192 ident
->symbols
= sym
;
193 sym
->id_list
= &ident
->symbols
;
197 struct symbol
*create_symbol(int stream
, const char *name
, int type
)
199 struct token
*token
= built_in_token(stream
, name
);
200 struct symbol
*sym
= alloc_symbol(token
, type
);
201 bind_symbol(sym
, token
->ident
, NS_TYPEDEF
);
206 * Type and storage class keywords need to have the symbols
207 * created for them, so that the parser can have enough semantic
208 * information to do parsing.
210 * "double" == "long float", "long double" == "long long float"
214 struct symbol
*base_type
;
215 unsigned int modifiers
;
216 } symbol_init_table
[] = {
218 { "auto", NULL
, MOD_AUTO
},
219 { "register", NULL
, MOD_REGISTER
},
220 { "static", NULL
, MOD_STATIC
},
221 { "extern", NULL
, MOD_EXTERN
},
223 /* Type specifiers */
224 { "void", &void_type
, 0 },
225 { "char", &int_type
, MOD_CHAR
},
226 { "short", &int_type
, MOD_SHORT
},
227 { "int", &int_type
, 0 },
228 { "long", NULL
, MOD_LONG
},
229 { "float", &fp_type
, 0 },
230 { "double", &fp_type
, MOD_LONG
},
231 { "signed", &int_type
, MOD_SIGNED
},
232 { "__signed", &int_type
, MOD_SIGNED
},
233 { "__signed__", &int_type
, MOD_SIGNED
},
234 { "unsigned", &int_type
, MOD_UNSIGNED
},
236 /* Type qualifiers */
237 { "const", NULL
, MOD_CONST
},
238 { "__const", NULL
, MOD_CONST
},
239 { "__const__", NULL
, MOD_CONST
},
240 { "volatile", NULL
, MOD_VOLATILE
},
242 /* Predeclared types */
243 { "__builtin_va_list", &int_type
, 0 },
246 { "typedef", NULL
, MOD_TYPEDEF
},
249 { "typeof", NULL
, MOD_TYPEOF
},
250 { "__typeof", NULL
, MOD_TYPEOF
},
251 { "__typeof__", NULL
, MOD_TYPEOF
},
253 { "attribute", NULL
, MOD_ATTRIBUTE
},
254 { "__attribute", NULL
, MOD_ATTRIBUTE
},
255 { "__attribute__", NULL
, MOD_ATTRIBUTE
},
257 { "struct", NULL
, MOD_STRUCTOF
},
258 { "union", NULL
, MOD_UNIONOF
},
259 { "enum", NULL
, MOD_ENUMOF
},
261 /* Ignored for now.. */
262 { "inline", NULL
, 0 },
263 { "__inline", NULL
, 0 },
264 { "__inline__", NULL
, 0 },
265 { "restrict", NULL
, 0 },
266 { "__restrict", NULL
, 0 },
274 struct symbol void_type
,
281 * C types (ie actual instances that the abstract types
284 struct symbol bool_ctype
, void_ctype
,
285 char_ctype
, uchar_ctype
,
286 short_ctype
, ushort_ctype
,
287 int_ctype
, uint_ctype
,
288 long_ctype
, ulong_ctype
,
289 llong_ctype
, ullong_ctype
,
290 float_ctype
, double_ctype
, ldouble_ctype
,
293 struct ctype_declare
{
295 unsigned long modifiers
;
296 unsigned long bit_size
;
297 unsigned long maxalign
;
298 struct symbol
*base_type
;
299 } ctype_declaration
[] = {
300 { &bool_ctype
, 0, BITS_IN_INT
, MAX_INT_ALIGNMENT
, &int_type
},
302 { &char_ctype
, MOD_SIGNED
| MOD_CHAR
, BITS_IN_CHAR
, MAX_INT_ALIGNMENT
, &int_type
},
303 { &uchar_ctype
, MOD_UNSIGNED
| MOD_CHAR
, BITS_IN_CHAR
, MAX_INT_ALIGNMENT
, &int_type
},
304 { &short_ctype
, MOD_SIGNED
| MOD_SHORT
, BITS_IN_SHORT
, MAX_INT_ALIGNMENT
, &int_type
},
305 { &ushort_ctype
, MOD_UNSIGNED
| MOD_SHORT
, BITS_IN_SHORT
, MAX_INT_ALIGNMENT
, &int_type
},
306 { &int_ctype
, 0, BITS_IN_INT
, MAX_INT_ALIGNMENT
, &int_type
},
307 { &uint_ctype
, MOD_UNSIGNED
, BITS_IN_INT
, MAX_INT_ALIGNMENT
, &int_type
},
308 { &long_ctype
, MOD_SIGNED
| MOD_LONG
, BITS_IN_LONG
, MAX_INT_ALIGNMENT
, &int_type
},
309 { &ulong_ctype
, MOD_UNSIGNED
| MOD_LONG
, BITS_IN_LONG
, MAX_INT_ALIGNMENT
, &int_type
},
310 { &llong_ctype
, MOD_SIGNED
| MOD_LONG
| MOD_LONGLONG
, BITS_IN_LONGLONG
, MAX_INT_ALIGNMENT
, &int_type
},
311 { &ullong_ctype
, MOD_UNSIGNED
| MOD_LONG
| MOD_LONGLONG
, BITS_IN_LONGLONG
, MAX_INT_ALIGNMENT
, &int_type
},
313 { &float_ctype
, 0, BITS_IN_FLOAT
, MAX_FP_ALIGNMENT
, &fp_type
},
314 { &double_ctype
, MOD_LONG
, BITS_IN_DOUBLE
, MAX_FP_ALIGNMENT
, &fp_type
},
315 { &ldouble_ctype
,MOD_LONG
| MOD_LONGLONG
, BITS_IN_LONGDOUBLE
,MAX_FP_ALIGNMENT
, &fp_type
},
317 { &string_ctype
, 0, BITS_IN_POINTER
, POINTER_ALIGNMENT
, &char_ctype
},
322 #define __IDENT(n,str) \
323 struct ident n ## _ident = { len: sizeof(str)-1, name: str }
324 #define IDENT(n) __IDENT(n, #n)
326 IDENT(struct); IDENT(union); IDENT(enum);
328 IDENT(alignof
); IDENT(__alignof
); IDENT(__alignof__
);
329 IDENT(if); IDENT(else); IDENT(return);
330 IDENT(switch); IDENT(case); IDENT(default);
331 IDENT(break); IDENT(continue);
332 IDENT(for); IDENT(while); IDENT(do); IDENT(goto);
334 IDENT(__asm__
); IDENT(__asm
); IDENT(asm);
335 IDENT(__volatile__
); IDENT(__volatile
); IDENT(volatile);
336 IDENT(__attribute__
); IDENT(__attribute
);
338 void init_symbols(void)
340 int stream
= init_stream("builtin", -1);
341 struct sym_init
*ptr
;
342 struct ctype_declare
*ctype
;
344 hash_ident(&sizeof_ident
);
345 hash_ident(&alignof_ident
);
346 hash_ident(&__alignof_ident
);
347 hash_ident(&__alignof___ident
);
348 hash_ident(&if_ident
);
349 hash_ident(&else_ident
);
350 hash_ident(&return_ident
);
351 hash_ident(&switch_ident
);
352 hash_ident(&case_ident
);
353 hash_ident(&default_ident
);
354 hash_ident(&break_ident
);
355 hash_ident(&continue_ident
);
356 hash_ident(&for_ident
);
357 hash_ident(&while_ident
);
358 hash_ident(&do_ident
);
359 hash_ident(&goto_ident
);
360 hash_ident(&__attribute___ident
);
361 hash_ident(&__attribute_ident
);
362 hash_ident(&__asm___ident
);
363 hash_ident(&__asm_ident
);
364 hash_ident(&asm_ident
);
365 hash_ident(&__volatile___ident
);
366 hash_ident(&__volatile_ident
);
367 hash_ident(&volatile_ident
);
368 for (ptr
= symbol_init_table
; ptr
->name
; ptr
++) {
370 sym
= create_symbol(stream
, ptr
->name
, SYM_NODE
);
371 sym
->ctype
.base_type
= ptr
->base_type
;
372 sym
->ctype
.modifiers
= ptr
->modifiers
;
375 string_ctype
.type
= SYM_PTR
;
376 for (ctype
= ctype_declaration
; ctype
->ptr
; ctype
++) {
377 struct symbol
*sym
= ctype
->ptr
;
378 unsigned long bit_size
= ctype
->bit_size
;
379 unsigned long alignment
= bit_size
>> 3;
381 if (alignment
> ctype
->maxalign
)
382 alignment
= ctype
->maxalign
;
383 sym
->bit_size
= bit_size
;
384 sym
->alignment
= alignment
;
385 sym
->ctype
.base_type
= ctype
->base_type
;
386 sym
->ctype
.modifiers
= ctype
->modifiers
;