Make 'show_type()' just show the type, while 'show_symbol()'
[smatch.git] / symbol.c
blob2670ed947f50e1989022092687ec719490c1010c
1 /*
2 * Symbol lookup and handling.
4 * Copyright (C) 2003 Linus Torvalds, 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"
17 #include "target.h"
19 struct symbol *lookup_symbol(struct ident *ident, enum namespace ns)
21 struct symbol *sym;
23 for (sym = ident->symbols; sym; sym = sym->next_id) {
24 if (sym->namespace == ns)
25 return sym;
27 return sym;
30 struct symbol *alloc_symbol(struct token *token, int type)
32 struct symbol *sym = __alloc_symbol(0);
33 sym->type = type;
34 sym->token = token;
35 return sym;
38 struct struct_union_info {
39 int advance;
40 unsigned long max_align;
41 unsigned long bit_size;
42 unsigned long offset;
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;
55 if (info->advance) {
56 offset += sym->alignment-1;
57 offset &= ~(sym->alignment-1);
58 sym->offset = offset;
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;
95 if (!sym)
96 return;
98 /* Already done? */
99 if (sym->bit_size)
100 return;
102 switch (sym->type) {
103 case SYM_STRUCT:
104 examine_struct_union_type(sym, 1);
105 return;
106 case SYM_UNION:
107 examine_struct_union_type(sym, 0);
108 return;
109 case SYM_PTR:
110 if (!sym->bit_size)
111 sym->bit_size = BITS_IN_POINTER;
112 if (!sym->alignment)
113 sym->alignment = POINTER_ALIGNMENT;
114 examine_symbol_type(sym->ctype.base_type);
115 return;
116 case SYM_ENUM:
117 if (!sym->bit_size)
118 sym->bit_size = BITS_IN_ENUM;
119 if (!sym->alignment)
120 sym->alignment = ENUM_ALIGNMENT;
121 return;
123 default:
124 break;
127 base_type = sym->ctype.base_type;
128 modifiers = sym->ctype.modifiers;
130 if (base_type == &void_type) {
131 sym->bit_size = -1;
132 return;
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;
164 } else
165 bit_size = 0;
167 if (!bit_size) {
168 warn(sym->token, "unknown type %d", sym->type);
169 return;
172 if (sym->type == SYM_ARRAY) {
173 int array_size = sym->array_size;
174 bit_size *= sym->array_size;
175 if (array_size == -1)
176 bit_size = -1;
179 if (!sym->alignment)
180 sym->alignment = alignment;
181 sym->bit_size = bit_size;
184 void bind_symbol(struct symbol *sym, struct ident *ident, enum namespace ns)
186 if (sym->id_list) {
187 warn(sym->token, "internal error: symbol type already bound");
188 return;
190 sym->namespace = ns;
191 sym->next_id = ident->symbols;
192 ident->symbols = sym;
193 sym->id_list = &ident->symbols;
194 bind_scope(sym);
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);
202 return sym;
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"
212 struct sym_init {
213 const char *name;
214 struct symbol *base_type;
215 unsigned int modifiers;
216 } symbol_init_table[] = {
217 /* Storage class */
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 },
245 /* Typedef.. */
246 { "typedef", NULL, MOD_TYPEDEF },
248 /* Extended types */
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 },
268 { NULL, NULL, 0 }
272 * Abstract types
274 struct symbol void_type,
275 int_type,
276 fp_type,
277 vector_type,
278 bad_type;
281 * C types (ie actual instances that the abstract types
282 * can map onto)
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,
291 string_ctype;
293 struct ctype_declare {
294 struct symbol *ptr;
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 },
318 { NULL, }
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);
327 IDENT(sizeof);
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++) {
369 struct symbol *sym;
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;