Add "check" program that just evaluates the tree and does nothing
[smatch.git] / symbol.c
blobcc0f52a5a0b4a1ad6f48b0c538acc1396410bfd1
1 /*
2 * Symbol lookup and handling.
4 * Copyright (C) 2003 Transmeta Corp, all rights reserved.
5 */
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
11 #include "lib.h"
12 #include "token.h"
13 #include "parse.h"
14 #include "symbol.h"
15 #include "scope.h"
16 #include "expression.h"
18 #include "target.h"
21 * Secondary symbol list for stuff that needs to be output because it
22 * was used.
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)
41 struct symbol *sym;
43 for (sym = ident->symbols; sym; sym = sym->next_id) {
44 if (sym->namespace == ns)
45 return sym;
47 return sym;
50 struct symbol *alloc_symbol(struct position pos, int type)
52 struct symbol *sym = __alloc_symbol(0);
53 sym->type = type;
54 sym->pos = pos;
55 return sym;
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;
76 sym->offset = 0;
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;
104 bit_offset = 0;
106 sym->offset = (bit_size - bit_offset) >> 3;
107 sym->bit_offset = bit_offset;
108 info->bit_size = bit_size + sym->fieldwidth;
109 return;
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;
143 if (!base_type)
144 return;
145 examine_symbol_type(base_type);
146 bit_size = base_type->bit_size * sym->array_size;
147 if (sym->array_size < 0)
148 bit_size = -1;
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;
160 if (!base_type)
161 return;
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;
184 if (!sym)
185 return sym;
187 /* Already done? */
188 if (sym->bit_size)
189 return sym;
191 switch (sym->type) {
192 case SYM_ARRAY:
193 examine_array_type(sym);
194 return sym;
195 case SYM_STRUCT:
196 examine_struct_union_type(sym, 1);
197 return sym;
198 case SYM_UNION:
199 examine_struct_union_type(sym, 0);
200 return sym;
201 case SYM_PTR:
202 if (!sym->bit_size)
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);
207 return sym;
208 case SYM_ENUM:
209 if (!sym->bit_size)
210 sym->bit_size = BITS_IN_ENUM;
211 if (!sym->ctype.alignment)
212 sym->ctype.alignment = ENUM_ALIGNMENT;
213 return sym;
214 case SYM_BITFIELD:
215 examine_bitfield_type(sym);
216 return sym;
217 case SYM_BASETYPE:
218 /* Size and alignment had better already be set up */
219 return sym;
220 case SYM_TYPEOF: {
221 struct symbol *base = evaluate_expression(sym->initializer);
222 if (base)
223 return base;
224 break;
226 default:
227 break;
230 /* SYM_NODE - figure out what the type of the node was.. */
231 base_type = sym->ctype.base_type;
232 modifiers = sym->ctype.modifiers;
234 if (base_type) {
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;
242 } else
243 bit_size = 0;
245 if (!sym->ctype.alignment)
246 sym->ctype.alignment = alignment;
247 sym->bit_size = bit_size;
248 return sym;
251 void bind_symbol(struct symbol *sym, struct ident *ident, enum namespace ns)
253 struct scope *scope;
254 if (sym->id_list) {
255 warn(sym->pos, "internal error: symbol type already bound");
256 return;
258 sym->namespace = ns;
259 sym->next_id = ident->symbols;
260 ident->symbols = sym;
261 sym->id_list = &ident->symbols;
263 scope = block_scope;
264 if (toplevel(scope)) {
265 if (sym->ctype.modifiers & MOD_STATIC)
266 scope = file_scope;
268 if (ns == NS_LABEL)
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);
278 return sym;
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"
288 struct sym_init {
289 const char *name;
290 struct symbol *base_type;
291 unsigned int modifiers;
292 } symbol_init_table[] = {
293 /* Storage class */
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 },
321 /* Typedef.. */
322 { "typedef", NULL, MOD_TYPEDEF },
324 /* Extended types */
325 { "typeof", NULL, MOD_TYPEOF },
326 { "__typeof", NULL, MOD_TYPEOF },
327 { "__typeof__", NULL, MOD_TYPEOF },
329 #if 0
330 { "attribute", NULL, MOD_ATTRIBUTE },
331 { "__attribute", NULL, MOD_ATTRIBUTE },
332 #endif
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 },
347 { NULL, NULL, 0 }
351 * Abstract types
353 struct symbol int_type,
354 fp_type,
355 vector_type,
356 bad_type;
359 * C types (ie actual instances that the abstract types
360 * can map onto)
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 {
372 struct symbol *ptr;
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 },
398 { NULL, }
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);
407 IDENT(sizeof);
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++) {
449 struct symbol *sym;
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;