2 * Symbol lookup and handling.
4 * Copyright (C) 2003 Transmeta Corp, all rights reserved.
16 #include "expression.h"
21 * Secondary symbol list for stuff that needs to be output because it
24 struct symbol_list
*used_list
= NULL
;
27 * If the symbol is an inline symbol, add it to the list of symbols to parse
29 void access_symbol(struct symbol
*sym
)
31 if (sym
->ctype
.modifiers
& MOD_INLINE
) {
32 if (!(sym
->ctype
.modifiers
& MOD_ACCESSED
)) {
33 add_symbol(&used_list
, sym
);
34 sym
->ctype
.modifiers
|= MOD_ACCESSED
;
39 struct symbol
*lookup_symbol(struct ident
*ident
, enum namespace ns
)
43 for (sym
= ident
->symbols
; sym
; sym
= sym
->next_id
) {
44 if (sym
->namespace == ns
)
50 struct symbol
*alloc_symbol(struct position pos
, int type
)
52 struct symbol
*sym
= __alloc_symbol(0);
58 struct struct_union_info
{
59 unsigned long max_align
;
60 unsigned long bit_size
;
64 * Unions are easy to lay out ;)
66 static void lay_out_union(struct symbol
*sym
, void *_info
, int flags
)
68 struct struct_union_info
*info
= _info
;
70 examine_symbol_type(sym
);
71 if (sym
->ctype
.alignment
> info
->max_align
)
72 info
->max_align
= sym
->ctype
.alignment
;
73 if (sym
->bit_size
> info
->bit_size
)
74 info
->bit_size
= sym
->bit_size
;
80 * Structures are a bit more interesting to lay out
82 static void lay_out_struct(struct symbol
*sym
, void *_info
, int flags
)
84 struct struct_union_info
*info
= _info
;
85 unsigned long bit_size
, base_size
;
86 unsigned long align_bit_mask
;
88 examine_symbol_type(sym
);
89 if (sym
->ctype
.alignment
> info
->max_align
)
90 info
->max_align
= sym
->ctype
.alignment
;
92 bit_size
= info
->bit_size
;
93 base_size
= sym
->bit_size
;
94 align_bit_mask
= (sym
->ctype
.alignment
<< 3) - 1;
97 * Bitfields have some very special rules..
99 if (sym
->fieldwidth
) {
100 unsigned long bit_offset
= bit_size
& align_bit_mask
;
102 if (bit_offset
+ sym
->fieldwidth
> base_size
) {
103 bit_size
= (bit_size
+ align_bit_mask
) & ~align_bit_mask
;
106 sym
->offset
= (bit_size
- bit_offset
) >> 3;
107 sym
->bit_offset
= bit_offset
;
108 info
->bit_size
= bit_size
+ sym
->fieldwidth
;
113 * Otherwise, just align it right and add it up..
115 bit_size
= (bit_size
+ align_bit_mask
) & ~align_bit_mask
;
116 sym
->offset
= bit_size
>> 3;
118 info
->bit_size
= bit_size
+ sym
->bit_size
;
121 static void examine_struct_union_type(struct symbol
*sym
, int advance
)
123 struct struct_union_info info
= { 1, 0 };
124 unsigned long bit_size
, bit_align
;
125 void (*fn
)(struct symbol
*, void *, int);
127 fn
= advance
? lay_out_struct
: lay_out_union
;
128 symbol_iterate(sym
->symbol_list
, fn
, &info
);
130 if (!sym
->ctype
.alignment
)
131 sym
->ctype
.alignment
= info
.max_align
;
132 bit_size
= info
.bit_size
;
133 bit_align
= (sym
->ctype
.alignment
<< 3)-1;
134 bit_size
= (bit_size
+ bit_align
) & ~bit_align
;
135 sym
->bit_size
= bit_size
;
138 static void examine_array_type(struct symbol
*sym
)
140 struct symbol
*base_type
= sym
->ctype
.base_type
;
141 unsigned long bit_size
, alignment
;
145 examine_symbol_type(base_type
);
146 bit_size
= base_type
->bit_size
* sym
->array_size
;
147 if (sym
->array_size
< 0)
149 alignment
= base_type
->ctype
.alignment
;
150 if (!sym
->ctype
.alignment
)
151 sym
->ctype
.alignment
= alignment
;
152 sym
->bit_size
= bit_size
;
155 static void examine_bitfield_type(struct symbol
*sym
)
157 struct symbol
*base_type
= sym
->ctype
.base_type
;
158 unsigned long bit_size
, alignment
;
162 examine_symbol_type(base_type
);
163 bit_size
= base_type
->bit_size
;
164 if (sym
->fieldwidth
> bit_size
) {
165 warn(sym
->pos
, "impossible field-width for this type");
166 sym
->fieldwidth
= bit_size
;
168 alignment
= base_type
->ctype
.alignment
;
169 if (!sym
->ctype
.alignment
)
170 sym
->ctype
.alignment
= alignment
;
171 sym
->bit_size
= bit_size
;
175 * Fill in type size and alignment information for
176 * regular SYM_TYPE things.
178 struct symbol
*examine_symbol_type(struct symbol
* sym
)
180 unsigned int bit_size
, alignment
;
181 struct symbol
*base_type
;
182 unsigned long modifiers
;
193 examine_array_type(sym
);
196 examine_struct_union_type(sym
, 1);
199 examine_struct_union_type(sym
, 0);
203 sym
->bit_size
= BITS_IN_POINTER
;
204 if (!sym
->ctype
.alignment
)
205 sym
->ctype
.alignment
= POINTER_ALIGNMENT
;
206 sym
->ctype
.base_type
= examine_symbol_type(sym
->ctype
.base_type
);
210 sym
->bit_size
= BITS_IN_ENUM
;
211 if (!sym
->ctype
.alignment
)
212 sym
->ctype
.alignment
= ENUM_ALIGNMENT
;
215 examine_bitfield_type(sym
);
218 /* Size and alignment had better already be set up */
221 struct symbol
*base
= evaluate_expression(sym
->initializer
);
230 /* SYM_NODE - figure out what the type of the node was.. */
231 base_type
= sym
->ctype
.base_type
;
232 modifiers
= sym
->ctype
.modifiers
;
235 base_type
= examine_symbol_type(base_type
);
236 sym
->ctype
.base_type
= base_type
;
238 bit_size
= base_type
->bit_size
;
239 alignment
= base_type
->ctype
.alignment
;
240 if (base_type
->fieldwidth
)
241 sym
->fieldwidth
= base_type
->fieldwidth
;
245 if (!sym
->ctype
.alignment
)
246 sym
->ctype
.alignment
= alignment
;
247 sym
->bit_size
= bit_size
;
251 void bind_symbol(struct symbol
*sym
, struct ident
*ident
, enum namespace ns
)
255 warn(sym
->pos
, "internal error: symbol type already bound");
259 sym
->next_id
= ident
->symbols
;
260 ident
->symbols
= sym
;
261 sym
->id_list
= &ident
->symbols
;
264 if (toplevel(scope
)) {
265 if (sym
->ctype
.modifiers
& MOD_STATIC
)
269 scope
= function_scope
;
270 bind_scope(sym
, scope
);
273 struct symbol
*create_symbol(int stream
, const char *name
, int type
)
275 struct token
*token
= built_in_token(stream
, name
);
276 struct symbol
*sym
= alloc_symbol(token
->pos
, type
);
277 bind_symbol(sym
, token
->ident
, NS_TYPEDEF
);
282 * Type and storage class keywords need to have the symbols
283 * created for them, so that the parser can have enough semantic
284 * information to do parsing.
286 * "double" == "long float", "long double" == "long long float"
290 struct symbol
*base_type
;
291 unsigned int modifiers
;
292 } symbol_init_table
[] = {
294 { "auto", NULL
, MOD_AUTO
},
295 { "register", NULL
, MOD_REGISTER
},
296 { "static", NULL
, MOD_STATIC
},
297 { "extern", NULL
, MOD_EXTERN
},
299 /* Type specifiers */
300 { "void", &void_ctype
, 0 },
301 { "char", &int_type
, MOD_CHAR
},
302 { "short", &int_type
, MOD_SHORT
},
303 { "int", &int_type
, 0 },
304 { "long", NULL
, MOD_LONG
},
305 { "float", &fp_type
, 0 },
306 { "double", &fp_type
, MOD_LONG
},
307 { "signed", &int_type
, MOD_SIGNED
},
308 { "__signed", &int_type
, MOD_SIGNED
},
309 { "__signed__", &int_type
, MOD_SIGNED
},
310 { "unsigned", &int_type
, MOD_UNSIGNED
},
312 /* Type qualifiers */
313 { "const", NULL
, MOD_CONST
},
314 { "__const", NULL
, MOD_CONST
},
315 { "__const__", NULL
, MOD_CONST
},
316 { "volatile", NULL
, MOD_VOLATILE
},
318 /* Predeclared types */
319 { "__builtin_va_list", &int_type
, 0 },
322 { "typedef", NULL
, MOD_TYPEDEF
},
325 { "typeof", NULL
, MOD_TYPEOF
},
326 { "__typeof", NULL
, MOD_TYPEOF
},
327 { "__typeof__", NULL
, MOD_TYPEOF
},
330 { "attribute", NULL
, MOD_ATTRIBUTE
},
331 { "__attribute", NULL
, MOD_ATTRIBUTE
},
333 { "__attribute__", NULL
, MOD_ATTRIBUTE
},
335 { "struct", NULL
, MOD_STRUCTOF
},
336 { "union", NULL
, MOD_UNIONOF
},
337 { "enum", NULL
, MOD_ENUMOF
},
339 { "inline", NULL
, MOD_INLINE
},
340 { "__inline", NULL
, MOD_INLINE
},
341 { "__inline__", NULL
, MOD_INLINE
},
343 /* Ignored for now.. */
344 { "restrict", NULL
, 0 },
345 { "__restrict", NULL
, 0 },
353 struct symbol int_type
,
359 * C types (ie actual instances that the abstract types
362 struct symbol bool_ctype
, void_ctype
,
363 char_ctype
, uchar_ctype
,
364 short_ctype
, ushort_ctype
,
365 int_ctype
, uint_ctype
,
366 long_ctype
, ulong_ctype
,
367 llong_ctype
, ullong_ctype
,
368 float_ctype
, double_ctype
, ldouble_ctype
,
369 string_ctype
, ptr_ctype
;
371 struct ctype_declare
{
373 unsigned long modifiers
;
374 unsigned long bit_size
;
375 unsigned long maxalign
;
376 struct symbol
*base_type
;
377 } ctype_declaration
[] = {
378 { &bool_ctype
, 0, BITS_IN_INT
, MAX_INT_ALIGNMENT
, &int_type
},
379 { &void_ctype
, 0, -1, 0, &void_ctype
},
381 { &char_ctype
, MOD_SIGNED
| MOD_CHAR
, BITS_IN_CHAR
, MAX_INT_ALIGNMENT
, &int_type
},
382 { &uchar_ctype
, MOD_UNSIGNED
| MOD_CHAR
, BITS_IN_CHAR
, MAX_INT_ALIGNMENT
, &int_type
},
383 { &short_ctype
, MOD_SIGNED
| MOD_SHORT
, BITS_IN_SHORT
, MAX_INT_ALIGNMENT
, &int_type
},
384 { &ushort_ctype
, MOD_UNSIGNED
| MOD_SHORT
, BITS_IN_SHORT
, MAX_INT_ALIGNMENT
, &int_type
},
385 { &int_ctype
, MOD_SIGNED
, BITS_IN_INT
, MAX_INT_ALIGNMENT
, &int_type
},
386 { &uint_ctype
, MOD_UNSIGNED
, BITS_IN_INT
, MAX_INT_ALIGNMENT
, &int_type
},
387 { &long_ctype
, MOD_SIGNED
| MOD_LONG
, BITS_IN_LONG
, MAX_INT_ALIGNMENT
, &int_type
},
388 { &ulong_ctype
, MOD_UNSIGNED
| MOD_LONG
, BITS_IN_LONG
, MAX_INT_ALIGNMENT
, &int_type
},
389 { &llong_ctype
, MOD_SIGNED
| MOD_LONG
| MOD_LONGLONG
, BITS_IN_LONGLONG
, MAX_INT_ALIGNMENT
, &int_type
},
390 { &ullong_ctype
, MOD_UNSIGNED
| MOD_LONG
| MOD_LONGLONG
, BITS_IN_LONGLONG
, MAX_INT_ALIGNMENT
, &int_type
},
392 { &float_ctype
, 0, BITS_IN_FLOAT
, MAX_FP_ALIGNMENT
, &fp_type
},
393 { &double_ctype
, MOD_LONG
, BITS_IN_DOUBLE
, MAX_FP_ALIGNMENT
, &fp_type
},
394 { &ldouble_ctype
,MOD_LONG
| MOD_LONGLONG
, BITS_IN_LONGDOUBLE
,MAX_FP_ALIGNMENT
, &fp_type
},
396 { &string_ctype
, 0, BITS_IN_POINTER
, POINTER_ALIGNMENT
, &char_ctype
},
397 { &ptr_ctype
, 0, BITS_IN_POINTER
, POINTER_ALIGNMENT
, &void_ctype
},
402 #define __IDENT(n,str) \
403 struct ident n ## _ident = { len: sizeof(str)-1, name: str }
404 #define IDENT(n) __IDENT(n, #n)
406 IDENT(struct); IDENT(union); IDENT(enum);
408 IDENT(alignof
); IDENT(__alignof
); IDENT(__alignof__
);
409 IDENT(if); IDENT(else); IDENT(return);
410 IDENT(switch); IDENT(case); IDENT(default);
411 IDENT(break); IDENT(continue);
412 IDENT(for); IDENT(while); IDENT(do); IDENT(goto);
414 IDENT(__asm__
); IDENT(__asm
); IDENT(asm);
415 IDENT(__volatile__
); IDENT(__volatile
); IDENT(volatile);
416 IDENT(__attribute__
); IDENT(__attribute
);
418 void init_symbols(void)
420 int stream
= init_stream("builtin", -1);
421 struct sym_init
*ptr
;
422 struct ctype_declare
*ctype
;
424 hash_ident(&sizeof_ident
);
425 hash_ident(&alignof_ident
);
426 hash_ident(&__alignof_ident
);
427 hash_ident(&__alignof___ident
);
428 hash_ident(&if_ident
);
429 hash_ident(&else_ident
);
430 hash_ident(&return_ident
);
431 hash_ident(&switch_ident
);
432 hash_ident(&case_ident
);
433 hash_ident(&default_ident
);
434 hash_ident(&break_ident
);
435 hash_ident(&continue_ident
);
436 hash_ident(&for_ident
);
437 hash_ident(&while_ident
);
438 hash_ident(&do_ident
);
439 hash_ident(&goto_ident
);
440 hash_ident(&__attribute___ident
);
441 hash_ident(&__attribute_ident
);
442 hash_ident(&__asm___ident
);
443 hash_ident(&__asm_ident
);
444 hash_ident(&asm_ident
);
445 hash_ident(&__volatile___ident
);
446 hash_ident(&__volatile_ident
);
447 hash_ident(&volatile_ident
);
448 for (ptr
= symbol_init_table
; ptr
->name
; ptr
++) {
450 sym
= create_symbol(stream
, ptr
->name
, SYM_NODE
);
451 sym
->ctype
.base_type
= ptr
->base_type
;
452 sym
->ctype
.modifiers
= ptr
->modifiers
;
455 ptr_ctype
.type
= SYM_PTR
;
456 string_ctype
.type
= SYM_PTR
;
457 for (ctype
= ctype_declaration
; ctype
->ptr
; ctype
++) {
458 struct symbol
*sym
= ctype
->ptr
;
459 unsigned long bit_size
= ctype
->bit_size
;
460 unsigned long alignment
= bit_size
>> 3;
462 if (alignment
> ctype
->maxalign
)
463 alignment
= ctype
->maxalign
;
464 sym
->bit_size
= bit_size
;
465 sym
->ctype
.alignment
= alignment
;
466 sym
->ctype
.base_type
= ctype
->base_type
;
467 sym
->ctype
.modifiers
= ctype
->modifiers
;