11f5207b7SJohn Levon /*
21f5207b7SJohn Levon * Symbol lookup and handling.
31f5207b7SJohn Levon *
41f5207b7SJohn Levon * Copyright (C) 2003 Transmeta Corp.
51f5207b7SJohn Levon * 2003-2004 Linus Torvalds
61f5207b7SJohn Levon *
71f5207b7SJohn Levon * Permission is hereby granted, free of charge, to any person obtaining a copy
81f5207b7SJohn Levon * of this software and associated documentation files (the "Software"), to deal
91f5207b7SJohn Levon * in the Software without restriction, including without limitation the rights
101f5207b7SJohn Levon * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
111f5207b7SJohn Levon * copies of the Software, and to permit persons to whom the Software is
121f5207b7SJohn Levon * furnished to do so, subject to the following conditions:
131f5207b7SJohn Levon *
141f5207b7SJohn Levon * The above copyright notice and this permission notice shall be included in
151f5207b7SJohn Levon * all copies or substantial portions of the Software.
161f5207b7SJohn Levon *
171f5207b7SJohn Levon * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
181f5207b7SJohn Levon * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
191f5207b7SJohn Levon * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
201f5207b7SJohn Levon * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
211f5207b7SJohn Levon * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
221f5207b7SJohn Levon * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
231f5207b7SJohn Levon * THE SOFTWARE.
241f5207b7SJohn Levon */
251f5207b7SJohn Levon #include <stdlib.h>
261f5207b7SJohn Levon #include <stdio.h>
271f5207b7SJohn Levon #include <string.h>
281f5207b7SJohn Levon
291f5207b7SJohn Levon #include "lib.h"
301f5207b7SJohn Levon #include "allocate.h"
311f5207b7SJohn Levon #include "token.h"
321f5207b7SJohn Levon #include "parse.h"
331f5207b7SJohn Levon #include "symbol.h"
341f5207b7SJohn Levon #include "scope.h"
351f5207b7SJohn Levon #include "expression.h"
36*c85f09ccSJohn Levon #include "evaluate.h"
371f5207b7SJohn Levon
381f5207b7SJohn Levon #include "target.h"
391f5207b7SJohn Levon
401f5207b7SJohn Levon /*
411f5207b7SJohn Levon * Secondary symbol list for stuff that needs to be output because it
421f5207b7SJohn Levon * was used.
431f5207b7SJohn Levon */
441f5207b7SJohn Levon struct symbol_list *translation_unit_used_list = NULL;
451f5207b7SJohn Levon
461f5207b7SJohn Levon /*
471f5207b7SJohn Levon * If the symbol is an inline symbol, add it to the list of symbols to parse
481f5207b7SJohn Levon */
access_symbol(struct symbol * sym)491f5207b7SJohn Levon void access_symbol(struct symbol *sym)
501f5207b7SJohn Levon {
511f5207b7SJohn Levon if (sym->ctype.modifiers & MOD_INLINE) {
52*c85f09ccSJohn Levon if (!sym->accessed) {
531f5207b7SJohn Levon add_symbol(&translation_unit_used_list, sym);
54*c85f09ccSJohn Levon sym->accessed = 1;
551f5207b7SJohn Levon }
561f5207b7SJohn Levon }
571f5207b7SJohn Levon }
581f5207b7SJohn Levon
lookup_symbol(struct ident * ident,enum namespace ns)591f5207b7SJohn Levon struct symbol *lookup_symbol(struct ident *ident, enum namespace ns)
601f5207b7SJohn Levon {
611f5207b7SJohn Levon struct symbol *sym;
621f5207b7SJohn Levon
631f5207b7SJohn Levon for (sym = ident->symbols; sym; sym = sym->next_id) {
641f5207b7SJohn Levon if (sym->namespace & ns) {
651f5207b7SJohn Levon sym->used = 1;
661f5207b7SJohn Levon return sym;
671f5207b7SJohn Levon }
681f5207b7SJohn Levon }
691f5207b7SJohn Levon return NULL;
701f5207b7SJohn Levon }
711f5207b7SJohn Levon
alloc_context(void)721f5207b7SJohn Levon struct context *alloc_context(void)
731f5207b7SJohn Levon {
741f5207b7SJohn Levon return __alloc_context(0);
751f5207b7SJohn Levon }
761f5207b7SJohn Levon
alloc_symbol(struct position pos,int type)771f5207b7SJohn Levon struct symbol *alloc_symbol(struct position pos, int type)
781f5207b7SJohn Levon {
791f5207b7SJohn Levon struct symbol *sym = __alloc_symbol(0);
801f5207b7SJohn Levon sym->type = type;
811f5207b7SJohn Levon sym->pos = pos;
821f5207b7SJohn Levon sym->endpos.type = 0;
831f5207b7SJohn Levon return sym;
841f5207b7SJohn Levon }
851f5207b7SJohn Levon
861f5207b7SJohn Levon struct struct_union_info {
871f5207b7SJohn Levon unsigned long max_align;
881f5207b7SJohn Levon unsigned long bit_size;
891f5207b7SJohn Levon int align_size;
901f5207b7SJohn Levon };
911f5207b7SJohn Levon
921f5207b7SJohn Levon /*
931f5207b7SJohn Levon * Unions are fairly easy to lay out ;)
941f5207b7SJohn Levon */
lay_out_union(struct symbol * sym,struct struct_union_info * info)951f5207b7SJohn Levon static void lay_out_union(struct symbol *sym, struct struct_union_info *info)
961f5207b7SJohn Levon {
971f5207b7SJohn Levon examine_symbol_type(sym);
981f5207b7SJohn Levon
991f5207b7SJohn Levon // Unnamed bitfields do not affect alignment.
1001f5207b7SJohn Levon if (sym->ident || !is_bitfield_type(sym)) {
1011f5207b7SJohn Levon if (sym->ctype.alignment > info->max_align)
1021f5207b7SJohn Levon info->max_align = sym->ctype.alignment;
1031f5207b7SJohn Levon }
1041f5207b7SJohn Levon
1051f5207b7SJohn Levon if (sym->bit_size > info->bit_size)
1061f5207b7SJohn Levon info->bit_size = sym->bit_size;
1071f5207b7SJohn Levon
1081f5207b7SJohn Levon sym->offset = 0;
1091f5207b7SJohn Levon }
1101f5207b7SJohn Levon
bitfield_base_size(struct symbol * sym)1111f5207b7SJohn Levon static int bitfield_base_size(struct symbol *sym)
1121f5207b7SJohn Levon {
1131f5207b7SJohn Levon if (sym->type == SYM_NODE)
1141f5207b7SJohn Levon sym = sym->ctype.base_type;
1151f5207b7SJohn Levon if (sym->type == SYM_BITFIELD)
1161f5207b7SJohn Levon sym = sym->ctype.base_type;
1171f5207b7SJohn Levon return sym->bit_size;
1181f5207b7SJohn Levon }
1191f5207b7SJohn Levon
1201f5207b7SJohn Levon /*
1211f5207b7SJohn Levon * Structures are a bit more interesting to lay out
1221f5207b7SJohn Levon */
lay_out_struct(struct symbol * sym,struct struct_union_info * info)1231f5207b7SJohn Levon static void lay_out_struct(struct symbol *sym, struct struct_union_info *info)
1241f5207b7SJohn Levon {
1251f5207b7SJohn Levon unsigned long bit_size, align_bit_mask;
1261f5207b7SJohn Levon int base_size;
1271f5207b7SJohn Levon
1281f5207b7SJohn Levon examine_symbol_type(sym);
1291f5207b7SJohn Levon
1301f5207b7SJohn Levon // Unnamed bitfields do not affect alignment.
1311f5207b7SJohn Levon if (sym->ident || !is_bitfield_type(sym)) {
1321f5207b7SJohn Levon if (sym->ctype.alignment > info->max_align)
1331f5207b7SJohn Levon info->max_align = sym->ctype.alignment;
1341f5207b7SJohn Levon }
1351f5207b7SJohn Levon
1361f5207b7SJohn Levon bit_size = info->bit_size;
1371f5207b7SJohn Levon base_size = sym->bit_size;
1381f5207b7SJohn Levon
1391f5207b7SJohn Levon /*
1401f5207b7SJohn Levon * Unsized arrays cause us to not align the resulting
1411f5207b7SJohn Levon * structure size
1421f5207b7SJohn Levon */
1431f5207b7SJohn Levon if (base_size < 0) {
1441f5207b7SJohn Levon info->align_size = 0;
1451f5207b7SJohn Levon base_size = 0;
1461f5207b7SJohn Levon }
1471f5207b7SJohn Levon
1481f5207b7SJohn Levon align_bit_mask = bytes_to_bits(sym->ctype.alignment) - 1;
1491f5207b7SJohn Levon
1501f5207b7SJohn Levon /*
1511f5207b7SJohn Levon * Bitfields have some very special rules..
1521f5207b7SJohn Levon */
1531f5207b7SJohn Levon if (is_bitfield_type (sym)) {
1541f5207b7SJohn Levon unsigned long bit_offset = bit_size & align_bit_mask;
1551f5207b7SJohn Levon int room = bitfield_base_size(sym) - bit_offset;
1561f5207b7SJohn Levon // Zero-width fields just fill up the unit.
1571f5207b7SJohn Levon int width = base_size ? : (bit_offset ? room : 0);
1581f5207b7SJohn Levon
1591f5207b7SJohn Levon if (width > room) {
1601f5207b7SJohn Levon bit_size = (bit_size + align_bit_mask) & ~align_bit_mask;
1611f5207b7SJohn Levon bit_offset = 0;
1621f5207b7SJohn Levon }
1631f5207b7SJohn Levon sym->offset = bits_to_bytes(bit_size - bit_offset);
1641f5207b7SJohn Levon sym->bit_offset = bit_offset;
1651f5207b7SJohn Levon sym->ctype.base_type->bit_offset = bit_offset;
1661f5207b7SJohn Levon info->bit_size = bit_size + width;
1671f5207b7SJohn Levon // warning (sym->pos, "bitfield: offset=%d:%d size=:%d", sym->offset, sym->bit_offset, width);
1681f5207b7SJohn Levon
1691f5207b7SJohn Levon return;
1701f5207b7SJohn Levon }
1711f5207b7SJohn Levon
1721f5207b7SJohn Levon /*
1731f5207b7SJohn Levon * Otherwise, just align it right and add it up..
1741f5207b7SJohn Levon */
1751f5207b7SJohn Levon bit_size = (bit_size + align_bit_mask) & ~align_bit_mask;
1761f5207b7SJohn Levon sym->offset = bits_to_bytes(bit_size);
1771f5207b7SJohn Levon
1781f5207b7SJohn Levon info->bit_size = bit_size + base_size;
1791f5207b7SJohn Levon // warning (sym->pos, "regular: offset=%d", sym->offset);
1801f5207b7SJohn Levon }
1811f5207b7SJohn Levon
examine_struct_union_type(struct symbol * sym,int advance)1821f5207b7SJohn Levon static struct symbol * examine_struct_union_type(struct symbol *sym, int advance)
1831f5207b7SJohn Levon {
1841f5207b7SJohn Levon struct struct_union_info info = {
1851f5207b7SJohn Levon .max_align = 1,
1861f5207b7SJohn Levon .bit_size = 0,
1871f5207b7SJohn Levon .align_size = 1
1881f5207b7SJohn Levon };
1891f5207b7SJohn Levon unsigned long bit_size, bit_align;
1901f5207b7SJohn Levon void (*fn)(struct symbol *, struct struct_union_info *);
1911f5207b7SJohn Levon struct symbol *member;
1921f5207b7SJohn Levon
1931f5207b7SJohn Levon fn = advance ? lay_out_struct : lay_out_union;
1941f5207b7SJohn Levon FOR_EACH_PTR(sym->symbol_list, member) {
1951f5207b7SJohn Levon fn(member, &info);
1961f5207b7SJohn Levon } END_FOR_EACH_PTR(member);
1971f5207b7SJohn Levon
1981f5207b7SJohn Levon if (!sym->ctype.alignment)
1991f5207b7SJohn Levon sym->ctype.alignment = info.max_align;
2001f5207b7SJohn Levon bit_size = info.bit_size;
2011f5207b7SJohn Levon if (info.align_size) {
2021f5207b7SJohn Levon bit_align = bytes_to_bits(sym->ctype.alignment)-1;
2031f5207b7SJohn Levon bit_size = (bit_size + bit_align) & ~bit_align;
2041f5207b7SJohn Levon }
2051f5207b7SJohn Levon sym->bit_size = bit_size;
2061f5207b7SJohn Levon return sym;
2071f5207b7SJohn Levon }
2081f5207b7SJohn Levon
examine_base_type(struct symbol * sym)2091f5207b7SJohn Levon static struct symbol *examine_base_type(struct symbol *sym)
2101f5207b7SJohn Levon {
2111f5207b7SJohn Levon struct symbol *base_type;
2121f5207b7SJohn Levon
2131f5207b7SJohn Levon /* Check the base type */
2141f5207b7SJohn Levon base_type = examine_symbol_type(sym->ctype.base_type);
2151f5207b7SJohn Levon if (!base_type || base_type->type == SYM_PTR)
2161f5207b7SJohn Levon return base_type;
217*c85f09ccSJohn Levon combine_address_space(sym->pos, &sym->ctype.as, base_type->ctype.as);
2181f5207b7SJohn Levon sym->ctype.modifiers |= base_type->ctype.modifiers & MOD_PTRINHERIT;
2191f5207b7SJohn Levon concat_ptr_list((struct ptr_list *)base_type->ctype.contexts,
2201f5207b7SJohn Levon (struct ptr_list **)&sym->ctype.contexts);
2211f5207b7SJohn Levon if (base_type->type == SYM_NODE) {
2221f5207b7SJohn Levon base_type = base_type->ctype.base_type;
2231f5207b7SJohn Levon sym->ctype.base_type = base_type;
2241f5207b7SJohn Levon }
2251f5207b7SJohn Levon return base_type;
2261f5207b7SJohn Levon }
2271f5207b7SJohn Levon
examine_array_type(struct symbol * sym)2281f5207b7SJohn Levon static struct symbol * examine_array_type(struct symbol *sym)
2291f5207b7SJohn Levon {
2301f5207b7SJohn Levon struct symbol *base_type = examine_base_type(sym);
2311f5207b7SJohn Levon unsigned long bit_size = -1, alignment;
2321f5207b7SJohn Levon struct expression *array_size = sym->array_size;
2331f5207b7SJohn Levon
2341f5207b7SJohn Levon if (!base_type)
2351f5207b7SJohn Levon return sym;
2361f5207b7SJohn Levon
2371f5207b7SJohn Levon if (array_size) {
2381f5207b7SJohn Levon bit_size = array_element_offset(base_type->bit_size,
2391f5207b7SJohn Levon get_expression_value_silent(array_size));
2401f5207b7SJohn Levon if (array_size->type != EXPR_VALUE) {
2411f5207b7SJohn Levon if (Wvla)
2421f5207b7SJohn Levon warning(array_size->pos, "Variable length array is used.");
2431f5207b7SJohn Levon bit_size = -1;
2441f5207b7SJohn Levon }
2451f5207b7SJohn Levon }
2461f5207b7SJohn Levon alignment = base_type->ctype.alignment;
2471f5207b7SJohn Levon if (!sym->ctype.alignment)
2481f5207b7SJohn Levon sym->ctype.alignment = alignment;
2491f5207b7SJohn Levon sym->bit_size = bit_size;
2501f5207b7SJohn Levon return sym;
2511f5207b7SJohn Levon }
2521f5207b7SJohn Levon
examine_bitfield_type(struct symbol * sym)2531f5207b7SJohn Levon static struct symbol *examine_bitfield_type(struct symbol *sym)
2541f5207b7SJohn Levon {
2551f5207b7SJohn Levon struct symbol *base_type = examine_base_type(sym);
2561f5207b7SJohn Levon unsigned long bit_size, alignment, modifiers;
2571f5207b7SJohn Levon
2581f5207b7SJohn Levon if (!base_type)
2591f5207b7SJohn Levon return sym;
2601f5207b7SJohn Levon bit_size = base_type->bit_size;
2611f5207b7SJohn Levon if (sym->bit_size > bit_size)
2621f5207b7SJohn Levon warning(sym->pos, "impossible field-width, %d, for this type", sym->bit_size);
2631f5207b7SJohn Levon
2641f5207b7SJohn Levon alignment = base_type->ctype.alignment;
2651f5207b7SJohn Levon if (!sym->ctype.alignment)
2661f5207b7SJohn Levon sym->ctype.alignment = alignment;
2671f5207b7SJohn Levon modifiers = base_type->ctype.modifiers;
2681f5207b7SJohn Levon
2691f5207b7SJohn Levon /* Bitfields are unsigned, unless the base type was explicitly signed */
2701f5207b7SJohn Levon if (!(modifiers & MOD_EXPLICITLY_SIGNED))
2711f5207b7SJohn Levon modifiers = (modifiers & ~MOD_SIGNED) | MOD_UNSIGNED;
2721f5207b7SJohn Levon sym->ctype.modifiers |= modifiers & MOD_SIGNEDNESS;
2731f5207b7SJohn Levon return sym;
2741f5207b7SJohn Levon }
2751f5207b7SJohn Levon
2761f5207b7SJohn Levon /*
2771f5207b7SJohn Levon * "typeof" will have to merge the types together
2781f5207b7SJohn Levon */
merge_type(struct symbol * sym,struct symbol * base_type)2791f5207b7SJohn Levon void merge_type(struct symbol *sym, struct symbol *base_type)
2801f5207b7SJohn Levon {
281*c85f09ccSJohn Levon combine_address_space(sym->pos, &sym->ctype.as, base_type->ctype.as);
2821f5207b7SJohn Levon sym->ctype.modifiers |= (base_type->ctype.modifiers & ~MOD_STORAGE);
2831f5207b7SJohn Levon concat_ptr_list((struct ptr_list *)base_type->ctype.contexts,
2841f5207b7SJohn Levon (struct ptr_list **)&sym->ctype.contexts);
2851f5207b7SJohn Levon sym->ctype.base_type = base_type->ctype.base_type;
2861f5207b7SJohn Levon if (sym->ctype.base_type->type == SYM_NODE)
2871f5207b7SJohn Levon merge_type(sym, sym->ctype.base_type);
2881f5207b7SJohn Levon }
2891f5207b7SJohn Levon
count_array_initializer(struct symbol * t,struct expression * expr)2901f5207b7SJohn Levon static int count_array_initializer(struct symbol *t, struct expression *expr)
2911f5207b7SJohn Levon {
2921f5207b7SJohn Levon int nr = 0;
2931f5207b7SJohn Levon int is_char = 0;
2941f5207b7SJohn Levon
2951f5207b7SJohn Levon /*
2961f5207b7SJohn Levon * Arrays of character types are special; they can be initialized by
2971f5207b7SJohn Levon * string literal _or_ by string literal in braces. The latter means
2981f5207b7SJohn Levon * that with T x[] = {<string literal>} number of elements in x depends
2991f5207b7SJohn Levon * on T - if it's a character type, we get the length of string literal
3001f5207b7SJohn Levon * (including NUL), otherwise we have one element here.
3011f5207b7SJohn Levon */
3021f5207b7SJohn Levon if (t->ctype.base_type == &int_type && t->ctype.modifiers & MOD_CHAR)
3031f5207b7SJohn Levon is_char = 1;
3041f5207b7SJohn Levon
3051f5207b7SJohn Levon switch (expr->type) {
3061f5207b7SJohn Levon case EXPR_INITIALIZER: {
3071f5207b7SJohn Levon struct expression *entry;
3081f5207b7SJohn Levon int count = 0;
3091f5207b7SJohn Levon int str_len = 0;
3101f5207b7SJohn Levon FOR_EACH_PTR(expr->expr_list, entry) {
3111f5207b7SJohn Levon count++;
3121f5207b7SJohn Levon switch (entry->type) {
3131f5207b7SJohn Levon case EXPR_INDEX:
3141f5207b7SJohn Levon if (entry->idx_to >= nr)
3151f5207b7SJohn Levon nr = entry->idx_to+1;
3161f5207b7SJohn Levon break;
3171f5207b7SJohn Levon case EXPR_PREOP: {
3181f5207b7SJohn Levon struct expression *e = entry;
3191f5207b7SJohn Levon if (is_char) {
3201f5207b7SJohn Levon while (e && e->type == EXPR_PREOP && e->op == '(')
3211f5207b7SJohn Levon e = e->unop;
3221f5207b7SJohn Levon if (e && e->type == EXPR_STRING) {
3231f5207b7SJohn Levon entry = e;
3241f5207b7SJohn Levon case EXPR_STRING:
3251f5207b7SJohn Levon if (is_char)
3261f5207b7SJohn Levon str_len = entry->string->length;
3271f5207b7SJohn Levon }
3281f5207b7SJohn Levon
3291f5207b7SJohn Levon
3301f5207b7SJohn Levon }
3311f5207b7SJohn Levon }
3321f5207b7SJohn Levon default:
3331f5207b7SJohn Levon nr++;
3341f5207b7SJohn Levon }
3351f5207b7SJohn Levon } END_FOR_EACH_PTR(entry);
3361f5207b7SJohn Levon if (count == 1 && str_len)
3371f5207b7SJohn Levon nr = str_len;
3381f5207b7SJohn Levon break;
3391f5207b7SJohn Levon }
3401f5207b7SJohn Levon case EXPR_PREOP:
3411f5207b7SJohn Levon if (is_char) {
3421f5207b7SJohn Levon struct expression *e = expr;
3431f5207b7SJohn Levon while (e && e->type == EXPR_PREOP && e->op == '(')
3441f5207b7SJohn Levon e = e->unop;
3451f5207b7SJohn Levon if (e && e->type == EXPR_STRING) {
3461f5207b7SJohn Levon expr = e;
3471f5207b7SJohn Levon case EXPR_STRING:
3481f5207b7SJohn Levon if (is_char)
3491f5207b7SJohn Levon nr = expr->string->length;
3501f5207b7SJohn Levon }
3511f5207b7SJohn Levon }
3521f5207b7SJohn Levon break;
3531f5207b7SJohn Levon default:
3541f5207b7SJohn Levon break;
3551f5207b7SJohn Levon }
3561f5207b7SJohn Levon return nr;
3571f5207b7SJohn Levon }
3581f5207b7SJohn Levon
get_symbol_initializer(struct symbol * sym)3591f5207b7SJohn Levon static struct expression *get_symbol_initializer(struct symbol *sym)
3601f5207b7SJohn Levon {
3611f5207b7SJohn Levon do {
3621f5207b7SJohn Levon if (sym->initializer)
3631f5207b7SJohn Levon return sym->initializer;
3641f5207b7SJohn Levon } while ((sym = sym->same_symbol) != NULL);
3651f5207b7SJohn Levon return NULL;
3661f5207b7SJohn Levon }
3671f5207b7SJohn Levon
implicit_array_size(struct symbol * node,unsigned int count)368*c85f09ccSJohn Levon static unsigned int implicit_array_size(struct symbol *node, unsigned int count)
369*c85f09ccSJohn Levon {
370*c85f09ccSJohn Levon struct symbol *arr_ori = node->ctype.base_type;
371*c85f09ccSJohn Levon struct symbol *arr_new = alloc_symbol(node->pos, SYM_ARRAY);
372*c85f09ccSJohn Levon struct symbol *elem_type = arr_ori->ctype.base_type;
373*c85f09ccSJohn Levon struct expression *size = alloc_const_expression(node->pos, count);
374*c85f09ccSJohn Levon unsigned int bit_size = array_element_offset(elem_type->bit_size, count);
375*c85f09ccSJohn Levon
376*c85f09ccSJohn Levon *arr_new = *arr_ori;
377*c85f09ccSJohn Levon arr_new->bit_size = bit_size;
378*c85f09ccSJohn Levon arr_new->array_size = size;
379*c85f09ccSJohn Levon node->array_size = size;
380*c85f09ccSJohn Levon node->ctype.base_type = arr_new;
381*c85f09ccSJohn Levon
382*c85f09ccSJohn Levon return bit_size;
383*c85f09ccSJohn Levon }
384*c85f09ccSJohn Levon
examine_node_type(struct symbol * sym)3851f5207b7SJohn Levon static struct symbol * examine_node_type(struct symbol *sym)
3861f5207b7SJohn Levon {
3871f5207b7SJohn Levon struct symbol *base_type = examine_base_type(sym);
3881f5207b7SJohn Levon int bit_size;
3891f5207b7SJohn Levon unsigned long alignment;
3901f5207b7SJohn Levon
3911f5207b7SJohn Levon /* SYM_NODE - figure out what the type of the node was.. */
3921f5207b7SJohn Levon bit_size = 0;
3931f5207b7SJohn Levon alignment = 0;
3941f5207b7SJohn Levon if (!base_type)
3951f5207b7SJohn Levon return sym;
3961f5207b7SJohn Levon
3971f5207b7SJohn Levon bit_size = base_type->bit_size;
3981f5207b7SJohn Levon alignment = base_type->ctype.alignment;
3991f5207b7SJohn Levon
4001f5207b7SJohn Levon /* Pick up signedness information into the node */
4011f5207b7SJohn Levon sym->ctype.modifiers |= (MOD_SIGNEDNESS & base_type->ctype.modifiers);
4021f5207b7SJohn Levon
4031f5207b7SJohn Levon if (!sym->ctype.alignment)
4041f5207b7SJohn Levon sym->ctype.alignment = alignment;
4051f5207b7SJohn Levon
4061f5207b7SJohn Levon /* Unsized array? The size might come from the initializer.. */
4071f5207b7SJohn Levon if (bit_size < 0 && base_type->type == SYM_ARRAY) {
4081f5207b7SJohn Levon struct expression *initializer = get_symbol_initializer(sym);
4091f5207b7SJohn Levon if (initializer) {
4101f5207b7SJohn Levon struct symbol *node_type = base_type->ctype.base_type;
4111f5207b7SJohn Levon int count = count_array_initializer(node_type, initializer);
4121f5207b7SJohn Levon
4131f5207b7SJohn Levon if (node_type && node_type->bit_size >= 0)
414*c85f09ccSJohn Levon bit_size = implicit_array_size(sym, count);
4151f5207b7SJohn Levon }
4161f5207b7SJohn Levon }
4171f5207b7SJohn Levon
4181f5207b7SJohn Levon sym->bit_size = bit_size;
4191f5207b7SJohn Levon return sym;
4201f5207b7SJohn Levon }
4211f5207b7SJohn Levon
examine_enum_type(struct symbol * sym)4221f5207b7SJohn Levon static struct symbol *examine_enum_type(struct symbol *sym)
4231f5207b7SJohn Levon {
4241f5207b7SJohn Levon struct symbol *base_type = examine_base_type(sym);
4251f5207b7SJohn Levon
4261f5207b7SJohn Levon sym->ctype.modifiers |= (base_type->ctype.modifiers & MOD_SIGNEDNESS);
4271f5207b7SJohn Levon sym->bit_size = bits_in_enum;
4281f5207b7SJohn Levon if (base_type->bit_size > sym->bit_size)
4291f5207b7SJohn Levon sym->bit_size = base_type->bit_size;
4301f5207b7SJohn Levon sym->ctype.alignment = enum_alignment;
4311f5207b7SJohn Levon if (base_type->ctype.alignment > sym->ctype.alignment)
4321f5207b7SJohn Levon sym->ctype.alignment = base_type->ctype.alignment;
4331f5207b7SJohn Levon return sym;
4341f5207b7SJohn Levon }
4351f5207b7SJohn Levon
examine_pointer_type(struct symbol * sym)4361f5207b7SJohn Levon static struct symbol *examine_pointer_type(struct symbol *sym)
4371f5207b7SJohn Levon {
4381f5207b7SJohn Levon /*
4391f5207b7SJohn Levon * We need to set the pointer size first, and
4401f5207b7SJohn Levon * examine the thing we point to only afterwards.
4411f5207b7SJohn Levon * That's because this pointer type may end up
4421f5207b7SJohn Levon * being needed for the base type size evaluation.
4431f5207b7SJohn Levon */
4441f5207b7SJohn Levon if (!sym->bit_size)
4451f5207b7SJohn Levon sym->bit_size = bits_in_pointer;
4461f5207b7SJohn Levon if (!sym->ctype.alignment)
4471f5207b7SJohn Levon sym->ctype.alignment = pointer_alignment;
4481f5207b7SJohn Levon return sym;
4491f5207b7SJohn Levon }
4501f5207b7SJohn Levon
4511f5207b7SJohn Levon /*
4521f5207b7SJohn Levon * Fill in type size and alignment information for
4531f5207b7SJohn Levon * regular SYM_TYPE things.
4541f5207b7SJohn Levon */
examine_symbol_type(struct symbol * sym)4551f5207b7SJohn Levon struct symbol *examine_symbol_type(struct symbol * sym)
4561f5207b7SJohn Levon {
4571f5207b7SJohn Levon if (!sym)
4581f5207b7SJohn Levon return sym;
4591f5207b7SJohn Levon
4601f5207b7SJohn Levon /* Already done? */
4611f5207b7SJohn Levon if (sym->examined)
4621f5207b7SJohn Levon return sym;
4631f5207b7SJohn Levon sym->examined = 1;
4641f5207b7SJohn Levon
4651f5207b7SJohn Levon switch (sym->type) {
4661f5207b7SJohn Levon case SYM_FN:
4671f5207b7SJohn Levon case SYM_NODE:
4681f5207b7SJohn Levon return examine_node_type(sym);
4691f5207b7SJohn Levon case SYM_ARRAY:
4701f5207b7SJohn Levon return examine_array_type(sym);
4711f5207b7SJohn Levon case SYM_STRUCT:
4721f5207b7SJohn Levon return examine_struct_union_type(sym, 1);
4731f5207b7SJohn Levon case SYM_UNION:
4741f5207b7SJohn Levon return examine_struct_union_type(sym, 0);
4751f5207b7SJohn Levon case SYM_PTR:
4761f5207b7SJohn Levon return examine_pointer_type(sym);
4771f5207b7SJohn Levon case SYM_ENUM:
4781f5207b7SJohn Levon return examine_enum_type(sym);
4791f5207b7SJohn Levon case SYM_BITFIELD:
4801f5207b7SJohn Levon return examine_bitfield_type(sym);
4811f5207b7SJohn Levon case SYM_BASETYPE:
4821f5207b7SJohn Levon /* Size and alignment had better already be set up */
4831f5207b7SJohn Levon return sym;
4841f5207b7SJohn Levon case SYM_TYPEOF: {
4851f5207b7SJohn Levon struct symbol *base = evaluate_expression(sym->initializer);
4861f5207b7SJohn Levon if (base) {
4871f5207b7SJohn Levon unsigned long mod = 0;
4881f5207b7SJohn Levon
4891f5207b7SJohn Levon if (is_bitfield_type(base))
4901f5207b7SJohn Levon warning(base->pos, "typeof applied to bitfield type");
4911f5207b7SJohn Levon if (base->type == SYM_NODE) {
4921f5207b7SJohn Levon mod |= base->ctype.modifiers & MOD_TYPEOF;
4931f5207b7SJohn Levon base = base->ctype.base_type;
4941f5207b7SJohn Levon }
4951f5207b7SJohn Levon sym->type = SYM_NODE;
4961f5207b7SJohn Levon sym->ctype.modifiers = mod;
4971f5207b7SJohn Levon sym->ctype.base_type = base;
4981f5207b7SJohn Levon return examine_node_type(sym);
4991f5207b7SJohn Levon }
500*c85f09ccSJohn Levon sym->type = SYM_NODE;
501*c85f09ccSJohn Levon sym->ctype.base_type = &bad_ctype;
502*c85f09ccSJohn Levon return sym;
5031f5207b7SJohn Levon }
5041f5207b7SJohn Levon case SYM_PREPROCESSOR:
5051f5207b7SJohn Levon sparse_error(sym->pos, "ctype on preprocessor command? (%s)", show_ident(sym->ident));
5061f5207b7SJohn Levon return NULL;
5071f5207b7SJohn Levon case SYM_UNINITIALIZED:
508*c85f09ccSJohn Levon // sparse_error(sym->pos, "ctype on uninitialized symbol '%s'", show_typename(sym));
5091f5207b7SJohn Levon return NULL;
5101f5207b7SJohn Levon case SYM_RESTRICT:
5111f5207b7SJohn Levon examine_base_type(sym);
5121f5207b7SJohn Levon return sym;
5131f5207b7SJohn Levon case SYM_FOULED:
5141f5207b7SJohn Levon examine_base_type(sym);
5151f5207b7SJohn Levon return sym;
5161f5207b7SJohn Levon default:
5171f5207b7SJohn Levon // sparse_error(sym->pos, "Examining unknown symbol type %d", sym->type);
5181f5207b7SJohn Levon break;
5191f5207b7SJohn Levon }
5201f5207b7SJohn Levon return sym;
5211f5207b7SJohn Levon }
5221f5207b7SJohn Levon
get_type_name(enum type type)5231f5207b7SJohn Levon const char* get_type_name(enum type type)
5241f5207b7SJohn Levon {
5251f5207b7SJohn Levon const char *type_lookup[] = {
5261f5207b7SJohn Levon [SYM_UNINITIALIZED] = "uninitialized",
5271f5207b7SJohn Levon [SYM_PREPROCESSOR] = "preprocessor",
5281f5207b7SJohn Levon [SYM_BASETYPE] = "basetype",
5291f5207b7SJohn Levon [SYM_NODE] = "node",
5301f5207b7SJohn Levon [SYM_PTR] = "pointer",
5311f5207b7SJohn Levon [SYM_FN] = "function",
5321f5207b7SJohn Levon [SYM_ARRAY] = "array",
5331f5207b7SJohn Levon [SYM_STRUCT] = "struct",
5341f5207b7SJohn Levon [SYM_UNION] = "union",
5351f5207b7SJohn Levon [SYM_ENUM] = "enum",
5361f5207b7SJohn Levon [SYM_TYPEDEF] = "typedef",
5371f5207b7SJohn Levon [SYM_TYPEOF] = "typeof",
5381f5207b7SJohn Levon [SYM_MEMBER] = "member",
5391f5207b7SJohn Levon [SYM_BITFIELD] = "bitfield",
5401f5207b7SJohn Levon [SYM_LABEL] = "label",
5411f5207b7SJohn Levon [SYM_RESTRICT] = "restrict",
5421f5207b7SJohn Levon [SYM_FOULED] = "fouled",
5431f5207b7SJohn Levon [SYM_KEYWORD] = "keyword",
5441f5207b7SJohn Levon [SYM_BAD] = "bad"};
5451f5207b7SJohn Levon
5461f5207b7SJohn Levon if (type <= SYM_BAD)
5471f5207b7SJohn Levon return type_lookup[type];
5481f5207b7SJohn Levon else
5491f5207b7SJohn Levon return NULL;
5501f5207b7SJohn Levon }
5511f5207b7SJohn Levon
examine_pointer_target(struct symbol * sym)5521f5207b7SJohn Levon struct symbol *examine_pointer_target(struct symbol *sym)
5531f5207b7SJohn Levon {
5541f5207b7SJohn Levon return examine_base_type(sym);
5551f5207b7SJohn Levon }
5561f5207b7SJohn Levon
5571f5207b7SJohn Levon static struct symbol_list *restr, *fouled;
5581f5207b7SJohn Levon
create_fouled(struct symbol * type)5591f5207b7SJohn Levon void create_fouled(struct symbol *type)
5601f5207b7SJohn Levon {
5611f5207b7SJohn Levon if (type->bit_size < bits_in_int) {
5621f5207b7SJohn Levon struct symbol *new = alloc_symbol(type->pos, type->type);
5631f5207b7SJohn Levon *new = *type;
5641f5207b7SJohn Levon new->bit_size = bits_in_int;
5651f5207b7SJohn Levon new->type = SYM_FOULED;
5661f5207b7SJohn Levon new->ctype.base_type = type;
5671f5207b7SJohn Levon add_symbol(&restr, type);
5681f5207b7SJohn Levon add_symbol(&fouled, new);
5691f5207b7SJohn Levon }
5701f5207b7SJohn Levon }
5711f5207b7SJohn Levon
befoul(struct symbol * type)5721f5207b7SJohn Levon struct symbol *befoul(struct symbol *type)
5731f5207b7SJohn Levon {
5741f5207b7SJohn Levon struct symbol *t1, *t2;
5751f5207b7SJohn Levon while (type->type == SYM_NODE)
5761f5207b7SJohn Levon type = type->ctype.base_type;
5771f5207b7SJohn Levon PREPARE_PTR_LIST(restr, t1);
5781f5207b7SJohn Levon PREPARE_PTR_LIST(fouled, t2);
5791f5207b7SJohn Levon for (;;) {
5801f5207b7SJohn Levon if (t1 == type)
5811f5207b7SJohn Levon return t2;
5821f5207b7SJohn Levon if (!t1)
5831f5207b7SJohn Levon break;
5841f5207b7SJohn Levon NEXT_PTR_LIST(t1);
5851f5207b7SJohn Levon NEXT_PTR_LIST(t2);
5861f5207b7SJohn Levon }
5871f5207b7SJohn Levon FINISH_PTR_LIST(t2);
5881f5207b7SJohn Levon FINISH_PTR_LIST(t1);
5891f5207b7SJohn Levon return NULL;
5901f5207b7SJohn Levon }
5911f5207b7SJohn Levon
check_declaration(struct symbol * sym)5921f5207b7SJohn Levon void check_declaration(struct symbol *sym)
5931f5207b7SJohn Levon {
5941f5207b7SJohn Levon int warned = 0;
5951f5207b7SJohn Levon struct symbol *next = sym;
5961f5207b7SJohn Levon
5971f5207b7SJohn Levon while ((next = next->next_id) != NULL) {
5981f5207b7SJohn Levon if (next->namespace != sym->namespace)
5991f5207b7SJohn Levon continue;
6001f5207b7SJohn Levon if (sym->scope == next->scope) {
6011f5207b7SJohn Levon sym->same_symbol = next;
6021f5207b7SJohn Levon return;
6031f5207b7SJohn Levon }
6041f5207b7SJohn Levon /* Extern in block level matches a TOPLEVEL non-static symbol */
6051f5207b7SJohn Levon if (sym->ctype.modifiers & MOD_EXTERN) {
6061f5207b7SJohn Levon if ((next->ctype.modifiers & (MOD_TOPLEVEL|MOD_STATIC)) == MOD_TOPLEVEL) {
6071f5207b7SJohn Levon sym->same_symbol = next;
6081f5207b7SJohn Levon return;
6091f5207b7SJohn Levon }
6101f5207b7SJohn Levon }
6111f5207b7SJohn Levon
6121f5207b7SJohn Levon if (!Wshadow || warned)
6131f5207b7SJohn Levon continue;
6141f5207b7SJohn Levon if (get_sym_type(next) == SYM_FN)
6151f5207b7SJohn Levon continue;
6161f5207b7SJohn Levon warned = 1;
6171f5207b7SJohn Levon warning(sym->pos, "symbol '%s' shadows an earlier one", show_ident(sym->ident));
6181f5207b7SJohn Levon info(next->pos, "originally declared here");
6191f5207b7SJohn Levon }
6201f5207b7SJohn Levon }
6211f5207b7SJohn Levon
bind_symbol(struct symbol * sym,struct ident * ident,enum namespace ns)6221f5207b7SJohn Levon void bind_symbol(struct symbol *sym, struct ident *ident, enum namespace ns)
6231f5207b7SJohn Levon {
6241f5207b7SJohn Levon struct scope *scope;
6251f5207b7SJohn Levon if (sym->bound) {
6261f5207b7SJohn Levon sparse_error(sym->pos, "internal error: symbol type already bound");
6271f5207b7SJohn Levon return;
6281f5207b7SJohn Levon }
6291f5207b7SJohn Levon if (ident->reserved && (ns & (NS_TYPEDEF | NS_STRUCT | NS_LABEL | NS_SYMBOL))) {
6301f5207b7SJohn Levon sparse_error(sym->pos, "Trying to use reserved word '%s' as identifier", show_ident(ident));
6311f5207b7SJohn Levon return;
6321f5207b7SJohn Levon }
6331f5207b7SJohn Levon sym->namespace = ns;
6341f5207b7SJohn Levon sym->next_id = ident->symbols;
6351f5207b7SJohn Levon ident->symbols = sym;
6361f5207b7SJohn Levon if (sym->ident && sym->ident != ident)
6371f5207b7SJohn Levon warning(sym->pos, "Symbol '%s' already bound", show_ident(sym->ident));
6381f5207b7SJohn Levon sym->ident = ident;
6391f5207b7SJohn Levon sym->bound = 1;
6401f5207b7SJohn Levon
6411f5207b7SJohn Levon scope = block_scope;
6421f5207b7SJohn Levon if (ns == NS_SYMBOL && toplevel(scope)) {
6431f5207b7SJohn Levon unsigned mod = MOD_ADDRESSABLE | MOD_TOPLEVEL;
6441f5207b7SJohn Levon
6451f5207b7SJohn Levon scope = global_scope;
6461f5207b7SJohn Levon if (sym->ctype.modifiers & MOD_STATIC ||
6471f5207b7SJohn Levon is_extern_inline(sym)) {
6481f5207b7SJohn Levon scope = file_scope;
6491f5207b7SJohn Levon mod = MOD_TOPLEVEL;
6501f5207b7SJohn Levon }
6511f5207b7SJohn Levon sym->ctype.modifiers |= mod;
6521f5207b7SJohn Levon }
6531f5207b7SJohn Levon if (ns == NS_MACRO)
6541f5207b7SJohn Levon scope = file_scope;
6551f5207b7SJohn Levon if (ns == NS_LABEL)
6561f5207b7SJohn Levon scope = function_scope;
6571f5207b7SJohn Levon bind_scope(sym, scope);
6581f5207b7SJohn Levon }
6591f5207b7SJohn Levon
create_symbol(int stream,const char * name,int type,int namespace)6601f5207b7SJohn Levon struct symbol *create_symbol(int stream, const char *name, int type, int namespace)
6611f5207b7SJohn Levon {
6621f5207b7SJohn Levon struct ident *ident = built_in_ident(name);
6631f5207b7SJohn Levon struct symbol *sym = lookup_symbol(ident, namespace);
6641f5207b7SJohn Levon
6651f5207b7SJohn Levon if (sym && sym->type != type)
6661f5207b7SJohn Levon die("symbol %s created with different types: %d old %d", name,
6671f5207b7SJohn Levon type, sym->type);
6681f5207b7SJohn Levon
6691f5207b7SJohn Levon if (!sym) {
6701f5207b7SJohn Levon struct token *token = built_in_token(stream, ident);
6711f5207b7SJohn Levon
6721f5207b7SJohn Levon sym = alloc_symbol(token->pos, type);
6731f5207b7SJohn Levon bind_symbol(sym, token->ident, namespace);
6741f5207b7SJohn Levon }
6751f5207b7SJohn Levon return sym;
6761f5207b7SJohn Levon }
6771f5207b7SJohn Levon
6781f5207b7SJohn Levon
6791f5207b7SJohn Levon /*
6801f5207b7SJohn Levon * Abstract types
6811f5207b7SJohn Levon */
6821f5207b7SJohn Levon struct symbol int_type,
6831f5207b7SJohn Levon fp_type;
6841f5207b7SJohn Levon
6851f5207b7SJohn Levon /*
6861f5207b7SJohn Levon * C types (i.e. actual instances that the abstract types
6871f5207b7SJohn Levon * can map onto)
6881f5207b7SJohn Levon */
6891f5207b7SJohn Levon struct symbol bool_ctype, void_ctype, type_ctype,
6901f5207b7SJohn Levon char_ctype, schar_ctype, uchar_ctype,
6911f5207b7SJohn Levon short_ctype, sshort_ctype, ushort_ctype,
6921f5207b7SJohn Levon int_ctype, sint_ctype, uint_ctype,
6931f5207b7SJohn Levon long_ctype, slong_ctype, ulong_ctype,
6941f5207b7SJohn Levon llong_ctype, sllong_ctype, ullong_ctype,
6951f5207b7SJohn Levon lllong_ctype, slllong_ctype, ulllong_ctype,
6961f5207b7SJohn Levon float_ctype, double_ctype, ldouble_ctype,
6971f5207b7SJohn Levon string_ctype, ptr_ctype, lazy_ptr_ctype,
6981f5207b7SJohn Levon incomplete_ctype, label_ctype, bad_ctype,
6991f5207b7SJohn Levon null_ctype;
700*c85f09ccSJohn Levon struct symbol int_ptr_ctype, uint_ptr_ctype;
701*c85f09ccSJohn Levon struct symbol long_ptr_ctype, ulong_ptr_ctype;
702*c85f09ccSJohn Levon struct symbol llong_ptr_ctype, ullong_ptr_ctype;
703*c85f09ccSJohn Levon struct symbol float32_ctype, float32x_ctype;
704*c85f09ccSJohn Levon struct symbol float64_ctype, float64x_ctype;
705*c85f09ccSJohn Levon struct symbol float128_ctype;
706*c85f09ccSJohn Levon struct symbol const_void_ctype, const_char_ctype;
707*c85f09ccSJohn Levon struct symbol const_ptr_ctype, const_string_ctype;
7081f5207b7SJohn Levon
7091f5207b7SJohn Levon struct symbol zero_int;
7101f5207b7SJohn Levon
7111f5207b7SJohn Levon #define __INIT_IDENT(str, res) { .len = sizeof(str)-1, .name = str, .reserved = res }
7121f5207b7SJohn Levon #define __IDENT(n,str,res) \
7131f5207b7SJohn Levon struct ident n = __INIT_IDENT(str,res)
7141f5207b7SJohn Levon
7151f5207b7SJohn Levon #include "ident-list.h"
7161f5207b7SJohn Levon
init_symbols(void)7171f5207b7SJohn Levon void init_symbols(void)
7181f5207b7SJohn Levon {
7191f5207b7SJohn Levon int stream = init_stream("builtin", -1, includepath);
7201f5207b7SJohn Levon
7211f5207b7SJohn Levon #define __IDENT(n,str,res) \
7221f5207b7SJohn Levon hash_ident(&n)
7231f5207b7SJohn Levon #include "ident-list.h"
7241f5207b7SJohn Levon
7251f5207b7SJohn Levon init_parser(stream);
7261f5207b7SJohn Levon init_builtins(stream);
7271f5207b7SJohn Levon }
7281f5207b7SJohn Levon
7291f5207b7SJohn Levon #ifdef __CHAR_UNSIGNED__
7301f5207b7SJohn Levon #define CHAR_SIGNEDNESS MOD_UNSIGNED
7311f5207b7SJohn Levon #else
7321f5207b7SJohn Levon #define CHAR_SIGNEDNESS MOD_SIGNED
7331f5207b7SJohn Levon #endif
734*c85f09ccSJohn Levon // For fix-sized types
735*c85f09ccSJohn Levon static int bits_in_type32 = 32;
736*c85f09ccSJohn Levon static int bits_in_type64 = 64;
737*c85f09ccSJohn Levon static int bits_in_type128 = 128;
7381f5207b7SJohn Levon
7391f5207b7SJohn Levon #define MOD_ESIGNED (MOD_SIGNED | MOD_EXPLICITLY_SIGNED)
7401f5207b7SJohn Levon #define MOD_LL (MOD_LONG | MOD_LONGLONG)
7411f5207b7SJohn Levon #define MOD_LLL MOD_LONGLONGLONG
7421f5207b7SJohn Levon static const struct ctype_declare {
7431f5207b7SJohn Levon struct symbol *ptr;
7441f5207b7SJohn Levon enum type type;
7451f5207b7SJohn Levon unsigned long modifiers;
7461f5207b7SJohn Levon int *bit_size;
7471f5207b7SJohn Levon int *maxalign;
7481f5207b7SJohn Levon struct symbol *base_type;
7491f5207b7SJohn Levon } ctype_declaration[] = {
7501f5207b7SJohn Levon { &bool_ctype, SYM_BASETYPE, MOD_UNSIGNED, &bits_in_bool, &max_int_alignment, &int_type },
7511f5207b7SJohn Levon { &void_ctype, SYM_BASETYPE, 0, NULL, NULL, NULL },
7521f5207b7SJohn Levon { &type_ctype, SYM_BASETYPE, MOD_TYPE, NULL, NULL, NULL },
7531f5207b7SJohn Levon { &incomplete_ctype,SYM_BASETYPE, 0, NULL, NULL, NULL },
7541f5207b7SJohn Levon { &bad_ctype, SYM_BASETYPE, 0, NULL, NULL, NULL },
7551f5207b7SJohn Levon
7561f5207b7SJohn Levon { &char_ctype, SYM_BASETYPE, CHAR_SIGNEDNESS | MOD_CHAR, &bits_in_char, &max_int_alignment, &int_type },
7571f5207b7SJohn Levon { &schar_ctype, SYM_BASETYPE, MOD_ESIGNED | MOD_CHAR, &bits_in_char, &max_int_alignment, &int_type },
7581f5207b7SJohn Levon { &uchar_ctype, SYM_BASETYPE, MOD_UNSIGNED | MOD_CHAR, &bits_in_char, &max_int_alignment, &int_type },
7591f5207b7SJohn Levon { &short_ctype, SYM_BASETYPE, MOD_SIGNED | MOD_SHORT, &bits_in_short, &max_int_alignment, &int_type },
7601f5207b7SJohn Levon { &sshort_ctype, SYM_BASETYPE, MOD_ESIGNED | MOD_SHORT, &bits_in_short, &max_int_alignment, &int_type },
7611f5207b7SJohn Levon { &ushort_ctype, SYM_BASETYPE, MOD_UNSIGNED | MOD_SHORT, &bits_in_short, &max_int_alignment, &int_type },
7621f5207b7SJohn Levon { &int_ctype, SYM_BASETYPE, MOD_SIGNED, &bits_in_int, &max_int_alignment, &int_type },
7631f5207b7SJohn Levon { &sint_ctype, SYM_BASETYPE, MOD_ESIGNED, &bits_in_int, &max_int_alignment, &int_type },
7641f5207b7SJohn Levon { &uint_ctype, SYM_BASETYPE, MOD_UNSIGNED, &bits_in_int, &max_int_alignment, &int_type },
7651f5207b7SJohn Levon { &long_ctype, SYM_BASETYPE, MOD_SIGNED | MOD_LONG, &bits_in_long, &max_int_alignment, &int_type },
7661f5207b7SJohn Levon { &slong_ctype, SYM_BASETYPE, MOD_ESIGNED | MOD_LONG, &bits_in_long, &max_int_alignment, &int_type },
7671f5207b7SJohn Levon { &ulong_ctype, SYM_BASETYPE, MOD_UNSIGNED | MOD_LONG, &bits_in_long, &max_int_alignment, &int_type },
7681f5207b7SJohn Levon { &llong_ctype, SYM_BASETYPE, MOD_SIGNED | MOD_LL, &bits_in_longlong, &max_int_alignment, &int_type },
7691f5207b7SJohn Levon { &sllong_ctype, SYM_BASETYPE, MOD_ESIGNED | MOD_LL, &bits_in_longlong, &max_int_alignment, &int_type },
7701f5207b7SJohn Levon { &ullong_ctype, SYM_BASETYPE, MOD_UNSIGNED | MOD_LL, &bits_in_longlong, &max_int_alignment, &int_type },
7711f5207b7SJohn Levon { &lllong_ctype, SYM_BASETYPE, MOD_SIGNED | MOD_LLL, &bits_in_longlonglong, &max_int_alignment, &int_type },
7721f5207b7SJohn Levon { &slllong_ctype, SYM_BASETYPE, MOD_ESIGNED | MOD_LLL, &bits_in_longlonglong, &max_int_alignment, &int_type },
7731f5207b7SJohn Levon { &ulllong_ctype, SYM_BASETYPE, MOD_UNSIGNED | MOD_LLL, &bits_in_longlonglong, &max_int_alignment, &int_type },
7741f5207b7SJohn Levon
7751f5207b7SJohn Levon { &float_ctype, SYM_BASETYPE, 0, &bits_in_float, &max_fp_alignment, &fp_type },
7761f5207b7SJohn Levon { &double_ctype, SYM_BASETYPE, MOD_LONG, &bits_in_double, &max_fp_alignment, &fp_type },
7771f5207b7SJohn Levon { &ldouble_ctype, SYM_BASETYPE, MOD_LONG | MOD_LONGLONG, &bits_in_longdouble, &max_fp_alignment, &fp_type },
7781f5207b7SJohn Levon
779*c85f09ccSJohn Levon { &float32_ctype, SYM_BASETYPE, 0, &bits_in_type32, &max_fp_alignment, &fp_type },
780*c85f09ccSJohn Levon { &float32x_ctype, SYM_BASETYPE, MOD_LONG, &bits_in_double, &max_fp_alignment, &fp_type },
781*c85f09ccSJohn Levon { &float64_ctype, SYM_BASETYPE, 0, &bits_in_type64, &max_fp_alignment, &fp_type },
782*c85f09ccSJohn Levon { &float64x_ctype, SYM_BASETYPE, MOD_LONG | MOD_LONGLONG, &bits_in_longdouble, &max_fp_alignment, &fp_type },
783*c85f09ccSJohn Levon { &float128_ctype, SYM_BASETYPE, 0, &bits_in_type128, &max_alignment, &fp_type },
784*c85f09ccSJohn Levon
7851f5207b7SJohn Levon { &string_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &char_ctype },
7861f5207b7SJohn Levon { &ptr_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &void_ctype },
7871f5207b7SJohn Levon { &null_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &void_ctype },
7881f5207b7SJohn Levon { &label_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &void_ctype },
7891f5207b7SJohn Levon { &lazy_ptr_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &void_ctype },
790*c85f09ccSJohn Levon { &int_ptr_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &int_ctype },
791*c85f09ccSJohn Levon { &uint_ptr_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &uint_ctype },
792*c85f09ccSJohn Levon { &long_ptr_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &long_ctype },
793*c85f09ccSJohn Levon { &ulong_ptr_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &ulong_ctype },
794*c85f09ccSJohn Levon { &llong_ptr_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &llong_ctype },
795*c85f09ccSJohn Levon { &ullong_ptr_ctype,SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &ullong_ctype },
796*c85f09ccSJohn Levon
797*c85f09ccSJohn Levon { &const_void_ctype, SYM_NODE, MOD_CONST, NULL, NULL, &void_ctype },
798*c85f09ccSJohn Levon { &const_char_ctype, SYM_NODE, MOD_CONST, &bits_in_char, &max_int_alignment, &char_ctype },
799*c85f09ccSJohn Levon { &const_ptr_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &const_void_ctype },
800*c85f09ccSJohn Levon { &const_string_ctype,SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &const_char_ctype },
8011f5207b7SJohn Levon { NULL, }
8021f5207b7SJohn Levon };
8031f5207b7SJohn Levon #undef MOD_LLL
8041f5207b7SJohn Levon #undef MOD_LL
8051f5207b7SJohn Levon #undef MOD_ESIGNED
8061f5207b7SJohn Levon
init_ctype(void)8071f5207b7SJohn Levon void init_ctype(void)
8081f5207b7SJohn Levon {
8091f5207b7SJohn Levon const struct ctype_declare *ctype;
8101f5207b7SJohn Levon
8111f5207b7SJohn Levon for (ctype = ctype_declaration ; ctype->ptr; ctype++) {
8121f5207b7SJohn Levon struct symbol *sym = ctype->ptr;
8131f5207b7SJohn Levon unsigned long bit_size = ctype->bit_size ? *ctype->bit_size : -1;
8141f5207b7SJohn Levon unsigned long maxalign = ctype->maxalign ? *ctype->maxalign : 0;
8151f5207b7SJohn Levon unsigned long alignment = bits_to_bytes(bit_size);
8161f5207b7SJohn Levon
8171f5207b7SJohn Levon if (alignment > maxalign)
8181f5207b7SJohn Levon alignment = maxalign;
8191f5207b7SJohn Levon sym->type = ctype->type;
8201f5207b7SJohn Levon sym->bit_size = bit_size;
8211f5207b7SJohn Levon sym->ctype.alignment = alignment;
8221f5207b7SJohn Levon sym->ctype.base_type = ctype->base_type;
8231f5207b7SJohn Levon sym->ctype.modifiers = ctype->modifiers;
8241f5207b7SJohn Levon }
825*c85f09ccSJohn Levon
826*c85f09ccSJohn Levon // and now some adjustments
827*c85f09ccSJohn Levon if (funsigned_char) {
828*c85f09ccSJohn Levon char_ctype.ctype.modifiers |= MOD_UNSIGNED;
829*c85f09ccSJohn Levon char_ctype.ctype.modifiers &= ~MOD_SIGNED;
830*c85f09ccSJohn Levon }
8311f5207b7SJohn Levon }
832