Oops. The argument symbol initializers got lost on inlining,
[smatch.git] / symbol.c
blobebe460091df228a7bff6858d257efc6f0f9ba87d
1 /*
2 * Symbol lookup and handling.
4 * Copyright (C) 2003 Transmeta Corp.
6 * Licensed under the Open Software License version 1.1
7 */
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
13 #include "lib.h"
14 #include "token.h"
15 #include "parse.h"
16 #include "symbol.h"
17 #include "scope.h"
18 #include "expression.h"
20 #include "target.h"
23 * Secondary symbol list for stuff that needs to be output because it
24 * was used.
26 struct symbol_list *used_list = NULL;
29 * If the symbol is an inline symbol, add it to the list of symbols to parse
31 void access_symbol(struct symbol *sym)
33 if (sym->ctype.modifiers & MOD_INLINE) {
34 if (!(sym->ctype.modifiers & MOD_ACCESSED)) {
35 add_symbol(&used_list, sym);
36 sym->ctype.modifiers |= MOD_ACCESSED;
41 struct symbol *lookup_symbol(struct ident *ident, enum namespace ns)
43 struct symbol *sym;
45 for (sym = ident->symbols; sym; sym = sym->next_id) {
46 if (sym->namespace == ns) {
47 sym->used = 1;
48 return sym;
51 return sym;
54 struct symbol *alloc_symbol(struct position pos, int type)
56 struct symbol *sym = __alloc_symbol(0);
57 sym->type = type;
58 sym->pos = pos;
59 return sym;
62 struct struct_union_info {
63 unsigned long max_align;
64 unsigned long bit_size;
68 * Unions are easy to lay out ;)
70 static void lay_out_union(struct symbol *sym, void *_info, int flags)
72 struct struct_union_info *info = _info;
74 examine_symbol_type(sym);
75 if (sym->ctype.alignment > info->max_align)
76 info->max_align = sym->ctype.alignment;
77 if (sym->bit_size > info->bit_size)
78 info->bit_size = sym->bit_size;
80 sym->offset = 0;
84 * Structures are a bit more interesting to lay out
86 static void lay_out_struct(struct symbol *sym, void *_info, int flags)
88 struct struct_union_info *info = _info;
89 unsigned long bit_size, base_size;
90 unsigned long align_bit_mask;
92 examine_symbol_type(sym);
93 if (sym->ctype.alignment > info->max_align)
94 info->max_align = sym->ctype.alignment;
96 bit_size = info->bit_size;
97 base_size = sym->bit_size;
98 align_bit_mask = (sym->ctype.alignment << 3) - 1;
101 * Bitfields have some very special rules..
103 if (sym->fieldwidth) {
104 unsigned long bit_offset = bit_size & align_bit_mask;
106 if (bit_offset + sym->fieldwidth > base_size) {
107 bit_size = (bit_size + align_bit_mask) & ~align_bit_mask;
108 bit_offset = 0;
110 sym->offset = (bit_size - bit_offset) >> 3;
111 sym->bit_offset = bit_offset;
112 info->bit_size = bit_size + sym->fieldwidth;
113 return;
117 * Otherwise, just align it right and add it up..
119 bit_size = (bit_size + align_bit_mask) & ~align_bit_mask;
120 sym->offset = bit_size >> 3;
122 info->bit_size = bit_size + sym->bit_size;
125 static void examine_struct_union_type(struct symbol *sym, int advance)
127 struct struct_union_info info = { 1, 0 };
128 unsigned long bit_size, bit_align;
129 void (*fn)(struct symbol *, void *, int);
131 fn = advance ? lay_out_struct : lay_out_union;
132 symbol_iterate(sym->symbol_list, fn, &info);
134 if (!sym->ctype.alignment)
135 sym->ctype.alignment = info.max_align;
136 bit_size = info.bit_size;
137 bit_align = (sym->ctype.alignment << 3)-1;
138 bit_size = (bit_size + bit_align) & ~bit_align;
139 sym->bit_size = bit_size;
142 static void examine_array_type(struct symbol *sym)
144 struct symbol *base_type = sym->ctype.base_type;
145 unsigned long bit_size, alignment;
147 if (!base_type)
148 return;
149 examine_symbol_type(base_type);
150 bit_size = base_type->bit_size * sym->array_size;
151 if (sym->array_size < 0)
152 bit_size = -1;
153 alignment = base_type->ctype.alignment;
154 if (!sym->ctype.alignment)
155 sym->ctype.alignment = alignment;
156 sym->bit_size = bit_size;
159 static void examine_bitfield_type(struct symbol *sym)
161 struct symbol *base_type = sym->ctype.base_type;
162 unsigned long bit_size, alignment;
164 if (!base_type)
165 return;
166 examine_symbol_type(base_type);
167 bit_size = base_type->bit_size;
168 if (sym->fieldwidth > bit_size) {
169 warn(sym->pos, "impossible field-width for this type");
170 sym->fieldwidth = bit_size;
172 alignment = base_type->ctype.alignment;
173 if (!sym->ctype.alignment)
174 sym->ctype.alignment = alignment;
175 sym->bit_size = bit_size;
179 * "typeof" will have to merge the types together
181 void merge_type(struct symbol *sym, struct symbol *base_type)
183 sym->ctype.as |= base_type->ctype.as;
184 sym->ctype.modifiers |= (base_type->ctype.modifiers & ~MOD_STORAGE);
185 sym->ctype.context |= base_type->ctype.context;
186 sym->ctype.contextmask |= base_type->ctype.contextmask;
187 sym->ctype.base_type = base_type->ctype.base_type;
191 * Fill in type size and alignment information for
192 * regular SYM_TYPE things.
194 struct symbol *examine_symbol_type(struct symbol * sym)
196 unsigned int bit_size, alignment;
197 struct symbol *base_type;
198 unsigned long modifiers;
200 if (!sym)
201 return sym;
203 /* Already done? */
204 if (sym->bit_size)
205 return sym;
207 switch (sym->type) {
208 case SYM_ARRAY:
209 examine_array_type(sym);
210 return sym;
211 case SYM_STRUCT:
212 examine_struct_union_type(sym, 1);
213 return sym;
214 case SYM_UNION:
215 examine_struct_union_type(sym, 0);
216 return sym;
217 case SYM_PTR:
218 if (!sym->bit_size)
219 sym->bit_size = BITS_IN_POINTER;
220 if (!sym->ctype.alignment)
221 sym->ctype.alignment = POINTER_ALIGNMENT;
222 base_type = sym->ctype.base_type;
223 base_type = examine_symbol_type(base_type);
224 if (base_type && base_type->type == SYM_NODE)
225 merge_type(sym, base_type);
226 return sym;
227 case SYM_ENUM:
228 if (!sym->bit_size)
229 sym->bit_size = BITS_IN_ENUM;
230 if (!sym->ctype.alignment)
231 sym->ctype.alignment = ENUM_ALIGNMENT;
232 return sym;
233 case SYM_BITFIELD:
234 examine_bitfield_type(sym);
235 return sym;
236 case SYM_BASETYPE:
237 /* Size and alignment had better already be set up */
238 return sym;
239 case SYM_TYPEOF: {
240 struct symbol *base = evaluate_expression(sym->initializer);
241 if (base)
242 return base;
243 break;
245 default:
246 break;
249 /* SYM_NODE - figure out what the type of the node was.. */
250 base_type = sym->ctype.base_type;
251 modifiers = sym->ctype.modifiers;
253 if (base_type) {
254 base_type = examine_symbol_type(base_type);
255 sym->ctype.base_type = base_type;
256 if (base_type && base_type->type == SYM_NODE)
257 merge_type(sym, base_type);
259 bit_size = base_type->bit_size;
260 alignment = base_type->ctype.alignment;
261 if (base_type->fieldwidth)
262 sym->fieldwidth = base_type->fieldwidth;
263 } else
264 bit_size = 0;
266 if (!sym->ctype.alignment)
267 sym->ctype.alignment = alignment;
268 sym->bit_size = bit_size;
269 return sym;
272 void check_declaration(struct symbol *sym)
274 struct symbol *next = sym;
276 while ((next = next->next_id) != NULL) {
277 if (next->namespace != sym->namespace)
278 continue;
279 if (sym->scope == next->scope) {
280 sym->same_symbol = next;
281 return;
283 if (sym->ctype.modifiers & next->ctype.modifiers & MOD_EXTERN) {
284 sym->same_symbol = next;
285 return;
287 #if 0
288 // This may make sense from a warning standpoint:
289 // consider top-level symbols to clash with everything
290 // (but the scoping rules will mean that we actually
291 // _use_ the innermost version)
292 if (toplevel(next->scope)) {
293 sym->same_symbol = next;
294 return;
296 #endif
300 void bind_symbol(struct symbol *sym, struct ident *ident, enum namespace ns)
302 struct scope *scope;
303 if (sym->id_list) {
304 warn(sym->pos, "internal error: symbol type already bound");
305 return;
307 sym->namespace = ns;
308 sym->next_id = ident->symbols;
309 ident->symbols = sym;
310 sym->id_list = &ident->symbols;
312 scope = block_scope;
313 if (ns != NS_TYPEDEF && toplevel(scope)) {
314 sym->ctype.modifiers |= MOD_TOPLEVEL;
315 if (sym->ctype.modifiers & MOD_STATIC)
316 scope = file_scope;
318 if (ns == NS_LABEL)
319 scope = function_scope;
320 bind_scope(sym, scope);
323 static struct symbol *create_symbol(int stream, const char *name, int type, int namespace)
325 struct token *token = built_in_token(stream, name);
326 struct symbol *sym = alloc_symbol(token->pos, type);
328 sym->ident = token->ident;
329 bind_symbol(sym, token->ident, namespace);
330 return sym;
333 static int evaluate_constant_p(struct expression *expr)
335 struct expression *arg;
336 struct expression_list *arglist = expr->args;
337 int value = 1;
339 FOR_EACH_PTR (arglist, arg) {
340 if (arg->type != EXPR_VALUE)
341 value = 0;
342 } END_FOR_EACH_PTR;
344 expr->ctype = &int_ctype;
345 expr->type = EXPR_VALUE;
346 expr->value = value;
347 return 1;
351 * Type and storage class keywords need to have the symbols
352 * created for them, so that the parser can have enough semantic
353 * information to do parsing.
355 * "double" == "long float", "long double" == "long long float"
357 struct sym_init {
358 const char *name;
359 struct symbol *base_type;
360 unsigned int modifiers;
361 int (*evaluate)(struct expression *);
362 } symbol_init_table[] = {
363 /* Storage class */
364 { "auto", NULL, MOD_AUTO },
365 { "register", NULL, MOD_REGISTER },
366 { "static", NULL, MOD_STATIC },
367 { "extern", NULL, MOD_EXTERN },
369 /* Type specifiers */
370 { "void", &void_ctype, 0 },
371 { "char", &int_type, MOD_CHAR },
372 { "short", &int_type, MOD_SHORT },
373 { "int", &int_type, 0 },
374 { "long", NULL, MOD_LONG },
375 { "float", &fp_type, 0 },
376 { "double", &fp_type, MOD_LONG },
377 { "signed", &int_type, MOD_SIGNED },
378 { "__signed", &int_type, MOD_SIGNED },
379 { "__signed__", &int_type, MOD_SIGNED },
380 { "unsigned", &int_type, MOD_UNSIGNED },
381 { "__label__", &label_type, MOD_LABEL | MOD_UNSIGNED },
383 /* Type qualifiers */
384 { "const", NULL, MOD_CONST },
385 { "__const", NULL, MOD_CONST },
386 { "__const__", NULL, MOD_CONST },
387 { "volatile", NULL, MOD_VOLATILE },
388 { "__volatile", NULL, MOD_VOLATILE },
389 { "__volatile__", NULL, MOD_VOLATILE },
391 /* Predeclared types */
392 { "__builtin_va_list", &int_type, 0 },
394 /* Typedef.. */
395 { "typedef", NULL, MOD_TYPEDEF },
397 /* Extended types */
398 { "typeof", NULL, MOD_TYPEOF },
399 { "__typeof", NULL, MOD_TYPEOF },
400 { "__typeof__", NULL, MOD_TYPEOF },
402 #if 0
403 { "attribute", NULL, MOD_ATTRIBUTE },
404 { "__attribute", NULL, MOD_ATTRIBUTE },
405 #endif
406 { "__attribute__", NULL, MOD_ATTRIBUTE },
408 { "struct", NULL, MOD_STRUCTOF },
409 { "union", NULL, MOD_UNIONOF },
410 { "enum", NULL, MOD_ENUMOF },
412 { "inline", NULL, MOD_INLINE },
413 { "__inline", NULL, MOD_INLINE },
414 { "__inline__", NULL, MOD_INLINE },
416 /* Ignored for now.. */
417 { "restrict", NULL, 0 },
418 { "__restrict", NULL, 0 },
420 { NULL, NULL, 0 }
424 * Builtin functions
426 struct sym_init eval_init_table[] = {
427 { "__builtin_constant_p", &int_type, MOD_TOPLEVEL, evaluate_constant_p },
429 { NULL, NULL, 0 }
434 * Abstract types
436 struct symbol int_type,
437 fp_type,
438 label_type,
439 vector_type,
440 bad_type;
443 * C types (ie actual instances that the abstract types
444 * can map onto)
446 struct symbol bool_ctype, void_ctype,
447 char_ctype, uchar_ctype,
448 short_ctype, ushort_ctype,
449 int_ctype, uint_ctype,
450 long_ctype, ulong_ctype,
451 llong_ctype, ullong_ctype,
452 float_ctype, double_ctype, ldouble_ctype,
453 string_ctype, ptr_ctype, label_ctype;
455 struct ctype_declare {
456 struct symbol *ptr;
457 unsigned long modifiers;
458 unsigned long bit_size;
459 unsigned long maxalign;
460 struct symbol *base_type;
461 } ctype_declaration[] = {
462 { &bool_ctype, 0, BITS_IN_INT, MAX_INT_ALIGNMENT, &int_type },
463 { &void_ctype, 0, -1, 0, NULL },
464 { &label_ctype, MOD_LABEL | MOD_UNSIGNED, BITS_IN_POINTER, MAX_INT_ALIGNMENT, &label_type },
466 { &char_ctype, MOD_SIGNED | MOD_CHAR, BITS_IN_CHAR, MAX_INT_ALIGNMENT, &int_type },
467 { &uchar_ctype, MOD_UNSIGNED | MOD_CHAR, BITS_IN_CHAR, MAX_INT_ALIGNMENT, &int_type },
468 { &short_ctype, MOD_SIGNED | MOD_SHORT, BITS_IN_SHORT, MAX_INT_ALIGNMENT, &int_type },
469 { &ushort_ctype, MOD_UNSIGNED | MOD_SHORT, BITS_IN_SHORT, MAX_INT_ALIGNMENT, &int_type },
470 { &int_ctype, MOD_SIGNED, BITS_IN_INT, MAX_INT_ALIGNMENT, &int_type },
471 { &uint_ctype, MOD_UNSIGNED, BITS_IN_INT, MAX_INT_ALIGNMENT, &int_type },
472 { &long_ctype, MOD_SIGNED | MOD_LONG, BITS_IN_LONG, MAX_INT_ALIGNMENT, &int_type },
473 { &ulong_ctype, MOD_UNSIGNED | MOD_LONG, BITS_IN_LONG, MAX_INT_ALIGNMENT, &int_type },
474 { &llong_ctype, MOD_SIGNED | MOD_LONG | MOD_LONGLONG, BITS_IN_LONGLONG, MAX_INT_ALIGNMENT, &int_type },
475 { &ullong_ctype, MOD_UNSIGNED | MOD_LONG | MOD_LONGLONG, BITS_IN_LONGLONG, MAX_INT_ALIGNMENT, &int_type },
477 { &float_ctype, 0, BITS_IN_FLOAT, MAX_FP_ALIGNMENT, &fp_type },
478 { &double_ctype, MOD_LONG, BITS_IN_DOUBLE, MAX_FP_ALIGNMENT, &fp_type },
479 { &ldouble_ctype,MOD_LONG | MOD_LONGLONG, BITS_IN_LONGDOUBLE,MAX_FP_ALIGNMENT, &fp_type },
481 { &string_ctype, 0, BITS_IN_POINTER, POINTER_ALIGNMENT, &char_ctype },
482 { &ptr_ctype, 0, BITS_IN_POINTER, POINTER_ALIGNMENT, &void_ctype },
483 { NULL, }
487 #define __IDENT(n,str) \
488 struct ident n ## _ident = { len: sizeof(str)-1, name: str }
489 #define IDENT(n) __IDENT(n, #n)
491 IDENT(struct); IDENT(union); IDENT(enum);
492 IDENT(sizeof);
493 IDENT(alignof); IDENT(__alignof); IDENT(__alignof__);
494 IDENT(if); IDENT(else); IDENT(return);
495 IDENT(switch); IDENT(case); IDENT(default);
496 IDENT(break); IDENT(continue);
497 IDENT(for); IDENT(while); IDENT(do); IDENT(goto);
499 IDENT(__asm__); IDENT(__asm); IDENT(asm);
500 IDENT(__volatile__); IDENT(__volatile); IDENT(volatile);
501 IDENT(__attribute__); IDENT(__attribute);
503 __IDENT(pragma, "__pragma__");
505 void init_symbols(void)
507 int stream = init_stream("builtin", -1);
508 struct sym_init *ptr;
509 struct ctype_declare *ctype;
511 hash_ident(&sizeof_ident);
512 hash_ident(&alignof_ident);
513 hash_ident(&__alignof_ident);
514 hash_ident(&__alignof___ident);
515 hash_ident(&if_ident);
516 hash_ident(&else_ident);
517 hash_ident(&return_ident);
518 hash_ident(&switch_ident);
519 hash_ident(&case_ident);
520 hash_ident(&default_ident);
521 hash_ident(&break_ident);
522 hash_ident(&continue_ident);
523 hash_ident(&for_ident);
524 hash_ident(&while_ident);
525 hash_ident(&do_ident);
526 hash_ident(&goto_ident);
527 hash_ident(&__attribute___ident);
528 hash_ident(&__attribute_ident);
529 hash_ident(&__asm___ident);
530 hash_ident(&__asm_ident);
531 hash_ident(&asm_ident);
532 hash_ident(&__volatile___ident);
533 hash_ident(&__volatile_ident);
534 hash_ident(&volatile_ident);
535 hash_ident(&pragma_ident);
536 for (ptr = symbol_init_table; ptr->name; ptr++) {
537 struct symbol *sym;
538 sym = create_symbol(stream, ptr->name, SYM_NODE, NS_TYPEDEF);
539 sym->ctype.base_type = ptr->base_type;
540 sym->ctype.modifiers = ptr->modifiers;
543 for (ptr = eval_init_table; ptr->name; ptr++) {
544 struct symbol *sym;
545 sym = create_symbol(stream, ptr->name, SYM_NODE, NS_SYMBOL);
546 sym->ctype.base_type = ptr->base_type;
547 sym->ctype.modifiers = ptr->modifiers;
548 sym->evaluate = ptr->evaluate;
551 ptr_ctype.type = SYM_PTR;
552 string_ctype.type = SYM_PTR;
553 for (ctype = ctype_declaration ; ctype->ptr; ctype++) {
554 struct symbol *sym = ctype->ptr;
555 unsigned long bit_size = ctype->bit_size;
556 unsigned long alignment = bit_size >> 3;
558 if (alignment > ctype->maxalign)
559 alignment = ctype->maxalign;
560 sym->bit_size = bit_size;
561 sym->ctype.alignment = alignment;
562 sym->ctype.base_type = ctype->base_type;
563 sym->ctype.modifiers = ctype->modifiers;