1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci * Symbol lookup and handling.
3f08c3bdfSopenharmony_ci *
4f08c3bdfSopenharmony_ci * Copyright (C) 2003 Transmeta Corp.
5f08c3bdfSopenharmony_ci *               2003-2004 Linus Torvalds
6f08c3bdfSopenharmony_ci *
7f08c3bdfSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
8f08c3bdfSopenharmony_ci * of this software and associated documentation files (the "Software"), to deal
9f08c3bdfSopenharmony_ci * in the Software without restriction, including without limitation the rights
10f08c3bdfSopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11f08c3bdfSopenharmony_ci * copies of the Software, and to permit persons to whom the Software is
12f08c3bdfSopenharmony_ci * furnished to do so, subject to the following conditions:
13f08c3bdfSopenharmony_ci *
14f08c3bdfSopenharmony_ci * The above copyright notice and this permission notice shall be included in
15f08c3bdfSopenharmony_ci * all copies or substantial portions of the Software.
16f08c3bdfSopenharmony_ci *
17f08c3bdfSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18f08c3bdfSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19f08c3bdfSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20f08c3bdfSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21f08c3bdfSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22f08c3bdfSopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23f08c3bdfSopenharmony_ci * THE SOFTWARE.
24f08c3bdfSopenharmony_ci */
25f08c3bdfSopenharmony_ci#include <stdlib.h>
26f08c3bdfSopenharmony_ci#include <stdio.h>
27f08c3bdfSopenharmony_ci#include <string.h>
28f08c3bdfSopenharmony_ci#include <assert.h>
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_ci#include "lib.h"
31f08c3bdfSopenharmony_ci#include "allocate.h"
32f08c3bdfSopenharmony_ci#include "token.h"
33f08c3bdfSopenharmony_ci#include "parse.h"
34f08c3bdfSopenharmony_ci#include "symbol.h"
35f08c3bdfSopenharmony_ci#include "scope.h"
36f08c3bdfSopenharmony_ci#include "expression.h"
37f08c3bdfSopenharmony_ci#include "evaluate.h"
38f08c3bdfSopenharmony_ci
39f08c3bdfSopenharmony_ci#include "target.h"
40f08c3bdfSopenharmony_ci
41f08c3bdfSopenharmony_ci/*
42f08c3bdfSopenharmony_ci * Secondary symbol list for stuff that needs to be output because it
43f08c3bdfSopenharmony_ci * was used.
44f08c3bdfSopenharmony_ci */
45f08c3bdfSopenharmony_cistruct symbol_list *translation_unit_used_list = NULL;
46f08c3bdfSopenharmony_ci
47f08c3bdfSopenharmony_ci/*
48f08c3bdfSopenharmony_ci * If the symbol is an inline symbol, add it to the list of symbols to parse
49f08c3bdfSopenharmony_ci */
50f08c3bdfSopenharmony_civoid access_symbol(struct symbol *sym)
51f08c3bdfSopenharmony_ci{
52f08c3bdfSopenharmony_ci	if (sym->ctype.modifiers & MOD_INLINE) {
53f08c3bdfSopenharmony_ci		if (!sym->accessed) {
54f08c3bdfSopenharmony_ci			add_symbol(&translation_unit_used_list, sym);
55f08c3bdfSopenharmony_ci			sym->accessed = 1;
56f08c3bdfSopenharmony_ci		}
57f08c3bdfSopenharmony_ci	}
58f08c3bdfSopenharmony_ci}
59f08c3bdfSopenharmony_ci
60f08c3bdfSopenharmony_cistruct symbol *lookup_symbol(struct ident *ident, enum namespace ns)
61f08c3bdfSopenharmony_ci{
62f08c3bdfSopenharmony_ci	struct symbol *sym;
63f08c3bdfSopenharmony_ci
64f08c3bdfSopenharmony_ci	for (sym = ident->symbols; sym; sym = sym->next_id) {
65f08c3bdfSopenharmony_ci		if (sym->namespace & ns) {
66f08c3bdfSopenharmony_ci			sym->used = 1;
67f08c3bdfSopenharmony_ci			return sym;
68f08c3bdfSopenharmony_ci		}
69f08c3bdfSopenharmony_ci	}
70f08c3bdfSopenharmony_ci	return NULL;
71f08c3bdfSopenharmony_ci}
72f08c3bdfSopenharmony_ci
73f08c3bdfSopenharmony_cistruct context *alloc_context(void)
74f08c3bdfSopenharmony_ci{
75f08c3bdfSopenharmony_ci	return __alloc_context(0);
76f08c3bdfSopenharmony_ci}
77f08c3bdfSopenharmony_ci
78f08c3bdfSopenharmony_cistruct symbol *alloc_symbol(struct position pos, int type)
79f08c3bdfSopenharmony_ci{
80f08c3bdfSopenharmony_ci	struct symbol *sym = __alloc_symbol(0);
81f08c3bdfSopenharmony_ci	sym->type = type;
82f08c3bdfSopenharmony_ci	sym->pos = pos;
83f08c3bdfSopenharmony_ci	sym->endpos.type = 0;
84f08c3bdfSopenharmony_ci	return sym;
85f08c3bdfSopenharmony_ci}
86f08c3bdfSopenharmony_ci
87f08c3bdfSopenharmony_cistruct struct_union_info {
88f08c3bdfSopenharmony_ci	unsigned long max_align;
89f08c3bdfSopenharmony_ci	unsigned long bit_size;
90f08c3bdfSopenharmony_ci	int align_size;
91f08c3bdfSopenharmony_ci	char has_flex_array;
92f08c3bdfSopenharmony_ci	bool packed;
93f08c3bdfSopenharmony_ci	struct symbol *flex_array;
94f08c3bdfSopenharmony_ci};
95f08c3bdfSopenharmony_ci
96f08c3bdfSopenharmony_ci/*
97f08c3bdfSopenharmony_ci * Unions are fairly easy to lay out ;)
98f08c3bdfSopenharmony_ci */
99f08c3bdfSopenharmony_cistatic void lay_out_union(struct symbol *sym, struct struct_union_info *info)
100f08c3bdfSopenharmony_ci{
101f08c3bdfSopenharmony_ci	if (sym->bit_size < 0 && is_array_type(sym))
102f08c3bdfSopenharmony_ci		sparse_error(sym->pos, "flexible array member '%s' in a union", show_ident(sym->ident));
103f08c3bdfSopenharmony_ci
104f08c3bdfSopenharmony_ci	if (sym->bit_size > info->bit_size)
105f08c3bdfSopenharmony_ci		info->bit_size = sym->bit_size;
106f08c3bdfSopenharmony_ci
107f08c3bdfSopenharmony_ci	sym->offset = 0;
108f08c3bdfSopenharmony_ci}
109f08c3bdfSopenharmony_ci
110f08c3bdfSopenharmony_cistatic int bitfield_base_size(struct symbol *sym)
111f08c3bdfSopenharmony_ci{
112f08c3bdfSopenharmony_ci	if (sym->type == SYM_NODE)
113f08c3bdfSopenharmony_ci		sym = sym->ctype.base_type;
114f08c3bdfSopenharmony_ci	if (sym->type == SYM_BITFIELD)
115f08c3bdfSopenharmony_ci		sym = sym->ctype.base_type;
116f08c3bdfSopenharmony_ci	return sym->bit_size;
117f08c3bdfSopenharmony_ci}
118f08c3bdfSopenharmony_ci
119f08c3bdfSopenharmony_ci/*
120f08c3bdfSopenharmony_ci * Structures are a bit more interesting to lay out
121f08c3bdfSopenharmony_ci */
122f08c3bdfSopenharmony_cistatic void lay_out_struct(struct symbol *sym, struct struct_union_info *info)
123f08c3bdfSopenharmony_ci{
124f08c3bdfSopenharmony_ci	unsigned long bit_size, align_bit_mask;
125f08c3bdfSopenharmony_ci	unsigned long alignment;
126f08c3bdfSopenharmony_ci	int base_size;
127f08c3bdfSopenharmony_ci
128f08c3bdfSopenharmony_ci	bit_size = info->bit_size;
129f08c3bdfSopenharmony_ci	base_size = sym->bit_size;
130f08c3bdfSopenharmony_ci
131f08c3bdfSopenharmony_ci	/*
132f08c3bdfSopenharmony_ci	 * If the member is unsized, either it's a flexible array or
133f08c3bdfSopenharmony_ci	 * it's invalid and a warning has already been issued.
134f08c3bdfSopenharmony_ci	 */
135f08c3bdfSopenharmony_ci	if (base_size < 0) {
136f08c3bdfSopenharmony_ci		if (!is_array_type(sym))
137f08c3bdfSopenharmony_ci			return;
138f08c3bdfSopenharmony_ci		base_size = 0;
139f08c3bdfSopenharmony_ci		info->flex_array = sym;
140f08c3bdfSopenharmony_ci	}
141f08c3bdfSopenharmony_ci
142f08c3bdfSopenharmony_ci	alignment = info->packed ? 1 : sym->ctype.alignment;
143f08c3bdfSopenharmony_ci	align_bit_mask = bytes_to_bits(alignment) - 1;
144f08c3bdfSopenharmony_ci
145f08c3bdfSopenharmony_ci	/*
146f08c3bdfSopenharmony_ci	 * Bitfields have some very special rules..
147f08c3bdfSopenharmony_ci	 */
148f08c3bdfSopenharmony_ci	if (is_bitfield_type (sym)) {
149f08c3bdfSopenharmony_ci		unsigned long bit_offset = bit_size & align_bit_mask;
150f08c3bdfSopenharmony_ci		int room = bitfield_base_size(sym) - bit_offset;
151f08c3bdfSopenharmony_ci		// Zero-width fields just fill up the unit.
152f08c3bdfSopenharmony_ci		int width = base_size ? : (bit_offset ? room : 0);
153f08c3bdfSopenharmony_ci
154f08c3bdfSopenharmony_ci		if (width > room && !info->packed) {
155f08c3bdfSopenharmony_ci			bit_size = (bit_size + align_bit_mask) & ~align_bit_mask;
156f08c3bdfSopenharmony_ci			bit_offset = 0;
157f08c3bdfSopenharmony_ci		}
158f08c3bdfSopenharmony_ci		sym->offset = bits_to_bytes(bit_size - bit_offset);
159f08c3bdfSopenharmony_ci		sym->bit_offset = bit_offset;
160f08c3bdfSopenharmony_ci		sym->ctype.base_type->bit_offset = bit_offset;
161f08c3bdfSopenharmony_ci		info->bit_size = bit_size + width;
162f08c3bdfSopenharmony_ci		// warning (sym->pos, "bitfield: offset=%d:%d  size=:%d", sym->offset, sym->bit_offset, width);
163f08c3bdfSopenharmony_ci
164f08c3bdfSopenharmony_ci		if (info->packed && sym->type == SYM_NODE)
165f08c3bdfSopenharmony_ci			sym->packed = 1;
166f08c3bdfSopenharmony_ci		return;
167f08c3bdfSopenharmony_ci	}
168f08c3bdfSopenharmony_ci
169f08c3bdfSopenharmony_ci	/*
170f08c3bdfSopenharmony_ci	 * Otherwise, just align it right and add it up..
171f08c3bdfSopenharmony_ci	 */
172f08c3bdfSopenharmony_ci	bit_size = (bit_size + align_bit_mask) & ~align_bit_mask;
173f08c3bdfSopenharmony_ci	sym->offset = bits_to_bytes(bit_size);
174f08c3bdfSopenharmony_ci
175f08c3bdfSopenharmony_ci	info->bit_size = bit_size + base_size;
176f08c3bdfSopenharmony_ci	// warning (sym->pos, "regular: offset=%d", sym->offset);
177f08c3bdfSopenharmony_ci}
178f08c3bdfSopenharmony_ci
179f08c3bdfSopenharmony_ci///
180f08c3bdfSopenharmony_ci// propagate properties of anonymous structs or unions into their members.
181f08c3bdfSopenharmony_ci//
182f08c3bdfSopenharmony_ci// :note: GCC seems to only propagate the qualifiers.
183f08c3bdfSopenharmony_ci// :note: clang doesn't propagate anything at all.
184f08c3bdfSopenharmony_cistatic void examine_anonymous_member(struct symbol *sym)
185f08c3bdfSopenharmony_ci{
186f08c3bdfSopenharmony_ci	unsigned long mod = sym->ctype.modifiers & MOD_QUALIFIER;
187f08c3bdfSopenharmony_ci	struct symbol *sub;
188f08c3bdfSopenharmony_ci
189f08c3bdfSopenharmony_ci	if (sym->type == SYM_NODE)
190f08c3bdfSopenharmony_ci		sym = sym->ctype.base_type;
191f08c3bdfSopenharmony_ci	if (sym->type != SYM_STRUCT && sym->type != SYM_UNION)
192f08c3bdfSopenharmony_ci		return;
193f08c3bdfSopenharmony_ci
194f08c3bdfSopenharmony_ci	FOR_EACH_PTR(sym->symbol_list, sub) {
195f08c3bdfSopenharmony_ci		assert(sub->type == SYM_NODE);
196f08c3bdfSopenharmony_ci		sub->ctype.modifiers |= mod;
197f08c3bdfSopenharmony_ci
198f08c3bdfSopenharmony_ci		// if nested, propagate all the way down
199f08c3bdfSopenharmony_ci		if (!sub->ident)
200f08c3bdfSopenharmony_ci			examine_anonymous_member(sub);
201f08c3bdfSopenharmony_ci	} END_FOR_EACH_PTR(sub);
202f08c3bdfSopenharmony_ci}
203f08c3bdfSopenharmony_ci
204f08c3bdfSopenharmony_cistatic struct symbol * examine_struct_union_type(struct symbol *sym, int advance)
205f08c3bdfSopenharmony_ci{
206f08c3bdfSopenharmony_ci	struct struct_union_info info = {
207f08c3bdfSopenharmony_ci		.packed = sym->packed,
208f08c3bdfSopenharmony_ci		.max_align = 1,
209f08c3bdfSopenharmony_ci		.bit_size = 0,
210f08c3bdfSopenharmony_ci		.align_size = 1
211f08c3bdfSopenharmony_ci	};
212f08c3bdfSopenharmony_ci	unsigned long bit_size, bit_align;
213f08c3bdfSopenharmony_ci	void (*fn)(struct symbol *, struct struct_union_info *);
214f08c3bdfSopenharmony_ci	struct symbol *member;
215f08c3bdfSopenharmony_ci
216f08c3bdfSopenharmony_ci	fn = advance ? lay_out_struct : lay_out_union;
217f08c3bdfSopenharmony_ci	FOR_EACH_PTR(sym->symbol_list, member) {
218f08c3bdfSopenharmony_ci		if (member->ctype.base_type == &autotype_ctype) {
219f08c3bdfSopenharmony_ci			sparse_error(member->pos, "member '%s' has __auto_type", show_ident(member->ident));
220f08c3bdfSopenharmony_ci			member->ctype.base_type = &incomplete_ctype;
221f08c3bdfSopenharmony_ci		}
222f08c3bdfSopenharmony_ci		if (info.flex_array)
223f08c3bdfSopenharmony_ci			sparse_error(info.flex_array->pos, "flexible array member '%s' is not last", show_ident(info.flex_array->ident));
224f08c3bdfSopenharmony_ci		examine_symbol_type(member);
225f08c3bdfSopenharmony_ci		if (!member->ident)
226f08c3bdfSopenharmony_ci			examine_anonymous_member(member);
227f08c3bdfSopenharmony_ci
228f08c3bdfSopenharmony_ci		if (member->ctype.alignment > info.max_align && !sym->packed) {
229f08c3bdfSopenharmony_ci			// Unnamed bitfields do not affect alignment.
230f08c3bdfSopenharmony_ci			if (member->ident || !is_bitfield_type(member))
231f08c3bdfSopenharmony_ci				info.max_align = member->ctype.alignment;
232f08c3bdfSopenharmony_ci		}
233f08c3bdfSopenharmony_ci
234f08c3bdfSopenharmony_ci		if (has_flexible_array(member))
235f08c3bdfSopenharmony_ci			info.has_flex_array = 1;
236f08c3bdfSopenharmony_ci		if (has_flexible_array(member) && Wflexible_array_nested)
237f08c3bdfSopenharmony_ci			warning(member->pos, "nested flexible array");
238f08c3bdfSopenharmony_ci		fn(member, &info);
239f08c3bdfSopenharmony_ci	} END_FOR_EACH_PTR(member);
240f08c3bdfSopenharmony_ci
241f08c3bdfSopenharmony_ci	if (!sym->ctype.alignment)
242f08c3bdfSopenharmony_ci		sym->ctype.alignment = info.max_align;
243f08c3bdfSopenharmony_ci	bit_size = info.bit_size;
244f08c3bdfSopenharmony_ci	if (info.align_size) {
245f08c3bdfSopenharmony_ci		bit_align = bytes_to_bits(sym->ctype.alignment)-1;
246f08c3bdfSopenharmony_ci		bit_size = (bit_size + bit_align) & ~bit_align;
247f08c3bdfSopenharmony_ci	}
248f08c3bdfSopenharmony_ci	if (info.flex_array) {
249f08c3bdfSopenharmony_ci		info.has_flex_array = 1;
250f08c3bdfSopenharmony_ci	}
251f08c3bdfSopenharmony_ci	if (info.has_flex_array && (!is_union_type(sym) || Wflexible_array_union))
252f08c3bdfSopenharmony_ci		sym->has_flex_array = 1;
253f08c3bdfSopenharmony_ci	sym->bit_size = bit_size;
254f08c3bdfSopenharmony_ci	return sym;
255f08c3bdfSopenharmony_ci}
256f08c3bdfSopenharmony_ci
257f08c3bdfSopenharmony_cistatic struct symbol *examine_base_type(struct symbol *sym)
258f08c3bdfSopenharmony_ci{
259f08c3bdfSopenharmony_ci	struct symbol *base_type;
260f08c3bdfSopenharmony_ci
261f08c3bdfSopenharmony_ci	if (sym->ctype.base_type == &autotype_ctype) {
262f08c3bdfSopenharmony_ci		struct symbol *type = evaluate_expression(sym->initializer);
263f08c3bdfSopenharmony_ci		if (!type)
264f08c3bdfSopenharmony_ci			type = &bad_ctype;
265f08c3bdfSopenharmony_ci		if (is_bitfield_type(type)) {
266f08c3bdfSopenharmony_ci			warning(sym->pos, "__auto_type on bitfield");
267f08c3bdfSopenharmony_ci			if (type->type == SYM_NODE)
268f08c3bdfSopenharmony_ci				type = type->ctype.base_type;
269f08c3bdfSopenharmony_ci			type = type->ctype.base_type;
270f08c3bdfSopenharmony_ci		}
271f08c3bdfSopenharmony_ci		sym->ctype.base_type = type;
272f08c3bdfSopenharmony_ci	}
273f08c3bdfSopenharmony_ci
274f08c3bdfSopenharmony_ci	/* Check the base type */
275f08c3bdfSopenharmony_ci	base_type = examine_symbol_type(sym->ctype.base_type);
276f08c3bdfSopenharmony_ci	if (!base_type || base_type->type == SYM_PTR)
277f08c3bdfSopenharmony_ci		return base_type;
278f08c3bdfSopenharmony_ci	combine_address_space(sym->pos, &sym->ctype.as, base_type->ctype.as);
279f08c3bdfSopenharmony_ci	sym->ctype.modifiers |= base_type->ctype.modifiers & MOD_PTRINHERIT;
280f08c3bdfSopenharmony_ci	concat_ptr_list((struct ptr_list *)base_type->ctype.contexts,
281f08c3bdfSopenharmony_ci			(struct ptr_list **)&sym->ctype.contexts);
282f08c3bdfSopenharmony_ci	if (base_type->type == SYM_NODE) {
283f08c3bdfSopenharmony_ci		base_type = base_type->ctype.base_type;
284f08c3bdfSopenharmony_ci		sym->ctype.base_type = base_type;
285f08c3bdfSopenharmony_ci		sym->rank = base_type->rank;
286f08c3bdfSopenharmony_ci	}
287f08c3bdfSopenharmony_ci	return base_type;
288f08c3bdfSopenharmony_ci}
289f08c3bdfSopenharmony_ci
290f08c3bdfSopenharmony_cistatic struct symbol * examine_array_type(struct symbol *sym)
291f08c3bdfSopenharmony_ci{
292f08c3bdfSopenharmony_ci	struct symbol *base_type = examine_base_type(sym);
293f08c3bdfSopenharmony_ci	unsigned long bit_size = -1, alignment;
294f08c3bdfSopenharmony_ci	struct expression *array_size = sym->array_size;
295f08c3bdfSopenharmony_ci
296f08c3bdfSopenharmony_ci	if (!base_type)
297f08c3bdfSopenharmony_ci		return sym;
298f08c3bdfSopenharmony_ci
299f08c3bdfSopenharmony_ci	if (array_size) {
300f08c3bdfSopenharmony_ci		bit_size = array_element_offset(base_type->bit_size,
301f08c3bdfSopenharmony_ci						get_expression_value_silent(array_size));
302f08c3bdfSopenharmony_ci		if (array_size->type != EXPR_VALUE) {
303f08c3bdfSopenharmony_ci			if (Wvla)
304f08c3bdfSopenharmony_ci				warning(array_size->pos, "Variable length array is used.");
305f08c3bdfSopenharmony_ci			bit_size = -1;
306f08c3bdfSopenharmony_ci		}
307f08c3bdfSopenharmony_ci	}
308f08c3bdfSopenharmony_ci	if (has_flexible_array(base_type) && Wflexible_array_array)
309f08c3bdfSopenharmony_ci		warning(sym->pos, "array of flexible structures");
310f08c3bdfSopenharmony_ci	alignment = base_type->ctype.alignment;
311f08c3bdfSopenharmony_ci	if (!sym->ctype.alignment)
312f08c3bdfSopenharmony_ci		sym->ctype.alignment = alignment;
313f08c3bdfSopenharmony_ci	sym->bit_size = bit_size;
314f08c3bdfSopenharmony_ci	return sym;
315f08c3bdfSopenharmony_ci}
316f08c3bdfSopenharmony_ci
317f08c3bdfSopenharmony_cistatic struct symbol *examine_bitfield_type(struct symbol *sym)
318f08c3bdfSopenharmony_ci{
319f08c3bdfSopenharmony_ci	struct symbol *base_type = examine_base_type(sym);
320f08c3bdfSopenharmony_ci	unsigned long alignment, modifiers;
321f08c3bdfSopenharmony_ci
322f08c3bdfSopenharmony_ci	if (!base_type)
323f08c3bdfSopenharmony_ci		return sym;
324f08c3bdfSopenharmony_ci	if (sym->bit_size > base_type->bit_size) {
325f08c3bdfSopenharmony_ci		sparse_error(sym->pos, "bitfield '%s' is wider (%d) than its type (%s)",
326f08c3bdfSopenharmony_ci			show_ident(sym->ident), sym->bit_size, show_typename(base_type));
327f08c3bdfSopenharmony_ci		sym->bit_size = -1;
328f08c3bdfSopenharmony_ci	}
329f08c3bdfSopenharmony_ci
330f08c3bdfSopenharmony_ci	alignment = base_type->ctype.alignment;
331f08c3bdfSopenharmony_ci	if (!sym->ctype.alignment)
332f08c3bdfSopenharmony_ci		sym->ctype.alignment = alignment;
333f08c3bdfSopenharmony_ci	modifiers = base_type->ctype.modifiers;
334f08c3bdfSopenharmony_ci
335f08c3bdfSopenharmony_ci	/* use -funsigned-bitfields to determine the sign if not explicit */
336f08c3bdfSopenharmony_ci	if (!(modifiers & MOD_EXPLICITLY_SIGNED) && funsigned_bitfields)
337f08c3bdfSopenharmony_ci		modifiers = (modifiers & ~MOD_SIGNED) | MOD_UNSIGNED;
338f08c3bdfSopenharmony_ci	sym->ctype.modifiers |= modifiers & MOD_SIGNEDNESS;
339f08c3bdfSopenharmony_ci	return sym;
340f08c3bdfSopenharmony_ci}
341f08c3bdfSopenharmony_ci
342f08c3bdfSopenharmony_ci/*
343f08c3bdfSopenharmony_ci * "typeof" will have to merge the types together
344f08c3bdfSopenharmony_ci */
345f08c3bdfSopenharmony_civoid merge_type(struct symbol *sym, struct symbol *base_type)
346f08c3bdfSopenharmony_ci{
347f08c3bdfSopenharmony_ci	combine_address_space(sym->pos, &sym->ctype.as, base_type->ctype.as);
348f08c3bdfSopenharmony_ci	sym->ctype.modifiers |= (base_type->ctype.modifiers & ~MOD_STORAGE);
349f08c3bdfSopenharmony_ci	concat_ptr_list((struct ptr_list *)base_type->ctype.contexts,
350f08c3bdfSopenharmony_ci	                (struct ptr_list **)&sym->ctype.contexts);
351f08c3bdfSopenharmony_ci	sym->ctype.base_type = base_type->ctype.base_type;
352f08c3bdfSopenharmony_ci	if (sym->ctype.base_type->type == SYM_NODE)
353f08c3bdfSopenharmony_ci		merge_type(sym, sym->ctype.base_type);
354f08c3bdfSopenharmony_ci}
355f08c3bdfSopenharmony_ci
356f08c3bdfSopenharmony_cistatic bool is_wstring_expr(struct expression *expr)
357f08c3bdfSopenharmony_ci{
358f08c3bdfSopenharmony_ci	while (expr) {
359f08c3bdfSopenharmony_ci		switch (expr->type) {
360f08c3bdfSopenharmony_ci		case EXPR_STRING:
361f08c3bdfSopenharmony_ci			return 1;
362f08c3bdfSopenharmony_ci		case EXPR_INITIALIZER:
363f08c3bdfSopenharmony_ci			if (expression_list_size(expr->expr_list) != 1)
364f08c3bdfSopenharmony_ci				return 0;
365f08c3bdfSopenharmony_ci			expr = first_expression(expr->expr_list);
366f08c3bdfSopenharmony_ci			break;
367f08c3bdfSopenharmony_ci		case EXPR_PREOP:
368f08c3bdfSopenharmony_ci			if (expr->op == '(') {
369f08c3bdfSopenharmony_ci				expr = expr->unop;
370f08c3bdfSopenharmony_ci				break;
371f08c3bdfSopenharmony_ci			}
372f08c3bdfSopenharmony_ci		default:
373f08c3bdfSopenharmony_ci			return 0;
374f08c3bdfSopenharmony_ci		}
375f08c3bdfSopenharmony_ci	}
376f08c3bdfSopenharmony_ci	return 0;
377f08c3bdfSopenharmony_ci}
378f08c3bdfSopenharmony_ci
379f08c3bdfSopenharmony_cistatic int count_array_initializer(struct symbol *t, struct expression *expr)
380f08c3bdfSopenharmony_ci{
381f08c3bdfSopenharmony_ci	int nr = 0;
382f08c3bdfSopenharmony_ci	int is_char = 0;
383f08c3bdfSopenharmony_ci
384f08c3bdfSopenharmony_ci	/*
385f08c3bdfSopenharmony_ci	 * Arrays of character types are special; they can be initialized by
386f08c3bdfSopenharmony_ci	 * string literal _or_ by string literal in braces.  The latter means
387f08c3bdfSopenharmony_ci	 * that with T x[] = {<string literal>} number of elements in x depends
388f08c3bdfSopenharmony_ci	 * on T - if it's a character type, we get the length of string literal
389f08c3bdfSopenharmony_ci	 * (including NUL), otherwise we have one element here.
390f08c3bdfSopenharmony_ci	 */
391f08c3bdfSopenharmony_ci	if (t->ctype.base_type == &int_type && t->rank == -2)
392f08c3bdfSopenharmony_ci		is_char = 1;
393f08c3bdfSopenharmony_ci	else if (t == wchar_ctype && is_wstring_expr(expr))
394f08c3bdfSopenharmony_ci		is_char = 1;
395f08c3bdfSopenharmony_ci
396f08c3bdfSopenharmony_ci	switch (expr->type) {
397f08c3bdfSopenharmony_ci	case EXPR_INITIALIZER: {
398f08c3bdfSopenharmony_ci		struct expression *entry;
399f08c3bdfSopenharmony_ci		int count = 0;
400f08c3bdfSopenharmony_ci		int str_len = 0;
401f08c3bdfSopenharmony_ci		FOR_EACH_PTR(expr->expr_list, entry) {
402f08c3bdfSopenharmony_ci			count++;
403f08c3bdfSopenharmony_ci			switch (entry->type) {
404f08c3bdfSopenharmony_ci			case EXPR_INDEX:
405f08c3bdfSopenharmony_ci				if (entry->idx_to >= nr)
406f08c3bdfSopenharmony_ci					nr = entry->idx_to+1;
407f08c3bdfSopenharmony_ci				break;
408f08c3bdfSopenharmony_ci			case EXPR_PREOP: {
409f08c3bdfSopenharmony_ci				struct expression *e = entry;
410f08c3bdfSopenharmony_ci				if (is_char) {
411f08c3bdfSopenharmony_ci					while (e && e->type == EXPR_PREOP && e->op == '(')
412f08c3bdfSopenharmony_ci						e = e->unop;
413f08c3bdfSopenharmony_ci					if (e && e->type == EXPR_STRING) {
414f08c3bdfSopenharmony_ci						entry = e;
415f08c3bdfSopenharmony_ci			case EXPR_STRING:
416f08c3bdfSopenharmony_ci						if (is_char)
417f08c3bdfSopenharmony_ci							str_len = entry->string->length;
418f08c3bdfSopenharmony_ci					}
419f08c3bdfSopenharmony_ci
420f08c3bdfSopenharmony_ci
421f08c3bdfSopenharmony_ci				}
422f08c3bdfSopenharmony_ci			}
423f08c3bdfSopenharmony_ci			default:
424f08c3bdfSopenharmony_ci				nr++;
425f08c3bdfSopenharmony_ci			}
426f08c3bdfSopenharmony_ci		} END_FOR_EACH_PTR(entry);
427f08c3bdfSopenharmony_ci		if (count == 1 && str_len)
428f08c3bdfSopenharmony_ci			nr = str_len;
429f08c3bdfSopenharmony_ci		break;
430f08c3bdfSopenharmony_ci	}
431f08c3bdfSopenharmony_ci	case EXPR_PREOP:
432f08c3bdfSopenharmony_ci		if (is_char) {
433f08c3bdfSopenharmony_ci			struct expression *e = expr;
434f08c3bdfSopenharmony_ci			while (e && e->type == EXPR_PREOP && e->op == '(')
435f08c3bdfSopenharmony_ci				e = e->unop;
436f08c3bdfSopenharmony_ci			if (e && e->type == EXPR_STRING) {
437f08c3bdfSopenharmony_ci				expr = e;
438f08c3bdfSopenharmony_ci	case EXPR_STRING:
439f08c3bdfSopenharmony_ci				if (is_char)
440f08c3bdfSopenharmony_ci					nr = expr->string->length;
441f08c3bdfSopenharmony_ci			}
442f08c3bdfSopenharmony_ci		}
443f08c3bdfSopenharmony_ci		break;
444f08c3bdfSopenharmony_ci	default:
445f08c3bdfSopenharmony_ci		break;
446f08c3bdfSopenharmony_ci	}
447f08c3bdfSopenharmony_ci	return nr;
448f08c3bdfSopenharmony_ci}
449f08c3bdfSopenharmony_ci
450f08c3bdfSopenharmony_cistatic struct expression *get_symbol_initializer(struct symbol *sym)
451f08c3bdfSopenharmony_ci{
452f08c3bdfSopenharmony_ci	do {
453f08c3bdfSopenharmony_ci		if (sym->initializer)
454f08c3bdfSopenharmony_ci			return sym->initializer;
455f08c3bdfSopenharmony_ci	} while ((sym = sym->same_symbol) != NULL);
456f08c3bdfSopenharmony_ci	return NULL;
457f08c3bdfSopenharmony_ci}
458f08c3bdfSopenharmony_ci
459f08c3bdfSopenharmony_cistatic unsigned int implicit_array_size(struct symbol *node, unsigned int count)
460f08c3bdfSopenharmony_ci{
461f08c3bdfSopenharmony_ci	struct symbol *arr_ori = node->ctype.base_type;
462f08c3bdfSopenharmony_ci	struct symbol *arr_new = alloc_symbol(node->pos, SYM_ARRAY);
463f08c3bdfSopenharmony_ci	struct symbol *elem_type = arr_ori->ctype.base_type;
464f08c3bdfSopenharmony_ci	struct expression *size = alloc_const_expression(node->pos, count);
465f08c3bdfSopenharmony_ci	unsigned int bit_size = array_element_offset(elem_type->bit_size, count);
466f08c3bdfSopenharmony_ci
467f08c3bdfSopenharmony_ci	*arr_new = *arr_ori;
468f08c3bdfSopenharmony_ci	arr_new->bit_size = bit_size;
469f08c3bdfSopenharmony_ci	arr_new->array_size = size;
470f08c3bdfSopenharmony_ci	node->array_size = size;
471f08c3bdfSopenharmony_ci	node->ctype.base_type = arr_new;
472f08c3bdfSopenharmony_ci
473f08c3bdfSopenharmony_ci	return bit_size;
474f08c3bdfSopenharmony_ci}
475f08c3bdfSopenharmony_ci
476f08c3bdfSopenharmony_cistatic struct symbol * examine_node_type(struct symbol *sym)
477f08c3bdfSopenharmony_ci{
478f08c3bdfSopenharmony_ci	struct symbol *base_type = examine_base_type(sym);
479f08c3bdfSopenharmony_ci	int bit_size;
480f08c3bdfSopenharmony_ci	unsigned long alignment;
481f08c3bdfSopenharmony_ci
482f08c3bdfSopenharmony_ci	/* SYM_NODE - figure out what the type of the node was.. */
483f08c3bdfSopenharmony_ci	bit_size = 0;
484f08c3bdfSopenharmony_ci	alignment = 0;
485f08c3bdfSopenharmony_ci	if (!base_type)
486f08c3bdfSopenharmony_ci		return sym;
487f08c3bdfSopenharmony_ci
488f08c3bdfSopenharmony_ci	bit_size = base_type->bit_size;
489f08c3bdfSopenharmony_ci	alignment = base_type->ctype.alignment;
490f08c3bdfSopenharmony_ci
491f08c3bdfSopenharmony_ci	/* Pick up signedness information into the node */
492f08c3bdfSopenharmony_ci	sym->ctype.modifiers |= (MOD_SIGNEDNESS & base_type->ctype.modifiers);
493f08c3bdfSopenharmony_ci
494f08c3bdfSopenharmony_ci	if (!sym->ctype.alignment)
495f08c3bdfSopenharmony_ci		sym->ctype.alignment = alignment;
496f08c3bdfSopenharmony_ci
497f08c3bdfSopenharmony_ci	/* Unsized array? The size might come from the initializer.. */
498f08c3bdfSopenharmony_ci	if (bit_size < 0 && base_type->type == SYM_ARRAY) {
499f08c3bdfSopenharmony_ci		struct expression *initializer = get_symbol_initializer(sym);
500f08c3bdfSopenharmony_ci		if (initializer) {
501f08c3bdfSopenharmony_ci			struct symbol *node_type = base_type->ctype.base_type;
502f08c3bdfSopenharmony_ci			int count = count_array_initializer(node_type, initializer);
503f08c3bdfSopenharmony_ci
504f08c3bdfSopenharmony_ci			if (node_type && node_type->bit_size >= 0)
505f08c3bdfSopenharmony_ci				bit_size = implicit_array_size(sym, count);
506f08c3bdfSopenharmony_ci		}
507f08c3bdfSopenharmony_ci	}
508f08c3bdfSopenharmony_ci
509f08c3bdfSopenharmony_ci	sym->bit_size = bit_size;
510f08c3bdfSopenharmony_ci	sym->rank = base_type->rank;
511f08c3bdfSopenharmony_ci	return sym;
512f08c3bdfSopenharmony_ci}
513f08c3bdfSopenharmony_ci
514f08c3bdfSopenharmony_cistatic struct symbol *examine_enum_type(struct symbol *sym)
515f08c3bdfSopenharmony_ci{
516f08c3bdfSopenharmony_ci	struct symbol *base_type = examine_base_type(sym);
517f08c3bdfSopenharmony_ci
518f08c3bdfSopenharmony_ci	sym->ctype.modifiers |= (base_type->ctype.modifiers & MOD_SIGNEDNESS);
519f08c3bdfSopenharmony_ci	sym->bit_size = bits_in_enum;
520f08c3bdfSopenharmony_ci	if (base_type->bit_size > sym->bit_size)
521f08c3bdfSopenharmony_ci		sym->bit_size = base_type->bit_size;
522f08c3bdfSopenharmony_ci	sym->ctype.alignment = enum_alignment;
523f08c3bdfSopenharmony_ci	if (base_type->ctype.alignment > sym->ctype.alignment)
524f08c3bdfSopenharmony_ci		sym->ctype.alignment = base_type->ctype.alignment;
525f08c3bdfSopenharmony_ci	return sym;
526f08c3bdfSopenharmony_ci}
527f08c3bdfSopenharmony_ci
528f08c3bdfSopenharmony_cistatic struct symbol *examine_pointer_type(struct symbol *sym)
529f08c3bdfSopenharmony_ci{
530f08c3bdfSopenharmony_ci	/*
531f08c3bdfSopenharmony_ci	 * Since pointers to incomplete types can be used,
532f08c3bdfSopenharmony_ci	 * for example in a struct-declaration-list,
533f08c3bdfSopenharmony_ci	 * the base type must *not* be examined here.
534f08c3bdfSopenharmony_ci	 * It thus means that it needs to be done later,
535f08c3bdfSopenharmony_ci	 * when the base type of the pointer is looked at.
536f08c3bdfSopenharmony_ci	 */
537f08c3bdfSopenharmony_ci	if (!sym->bit_size)
538f08c3bdfSopenharmony_ci		sym->bit_size = bits_in_pointer;
539f08c3bdfSopenharmony_ci	if (!sym->ctype.alignment)
540f08c3bdfSopenharmony_ci		sym->ctype.alignment = pointer_alignment;
541f08c3bdfSopenharmony_ci	return sym;
542f08c3bdfSopenharmony_ci}
543f08c3bdfSopenharmony_ci
544f08c3bdfSopenharmony_cistatic struct symbol *examine_typeof(struct symbol *sym)
545f08c3bdfSopenharmony_ci{
546f08c3bdfSopenharmony_ci	struct symbol *base = evaluate_expression(sym->initializer);
547f08c3bdfSopenharmony_ci	unsigned long mod = 0;
548f08c3bdfSopenharmony_ci
549f08c3bdfSopenharmony_ci	if (!base)
550f08c3bdfSopenharmony_ci		base = &bad_ctype;
551f08c3bdfSopenharmony_ci	if (base->type == SYM_NODE) {
552f08c3bdfSopenharmony_ci		mod |= base->ctype.modifiers & MOD_TYPEOF;
553f08c3bdfSopenharmony_ci		base = base->ctype.base_type;
554f08c3bdfSopenharmony_ci	}
555f08c3bdfSopenharmony_ci	if (base->type == SYM_BITFIELD)
556f08c3bdfSopenharmony_ci		warning(base->pos, "typeof applied to bitfield type");
557f08c3bdfSopenharmony_ci	sym->type = SYM_NODE;
558f08c3bdfSopenharmony_ci	sym->ctype.modifiers = mod;
559f08c3bdfSopenharmony_ci	sym->ctype.base_type = base;
560f08c3bdfSopenharmony_ci	return examine_node_type(sym);
561f08c3bdfSopenharmony_ci}
562f08c3bdfSopenharmony_ci
563f08c3bdfSopenharmony_ci/*
564f08c3bdfSopenharmony_ci * Fill in type size and alignment information for
565f08c3bdfSopenharmony_ci * regular SYM_TYPE things.
566f08c3bdfSopenharmony_ci */
567f08c3bdfSopenharmony_cistruct symbol *examine_symbol_type(struct symbol * sym)
568f08c3bdfSopenharmony_ci{
569f08c3bdfSopenharmony_ci	if (!sym)
570f08c3bdfSopenharmony_ci		return sym;
571f08c3bdfSopenharmony_ci
572f08c3bdfSopenharmony_ci	/* Already done? */
573f08c3bdfSopenharmony_ci	if (sym->examined)
574f08c3bdfSopenharmony_ci		return sym;
575f08c3bdfSopenharmony_ci	sym->examined = 1;
576f08c3bdfSopenharmony_ci
577f08c3bdfSopenharmony_ci	switch (sym->type) {
578f08c3bdfSopenharmony_ci	case SYM_FN:
579f08c3bdfSopenharmony_ci	case SYM_NODE:
580f08c3bdfSopenharmony_ci		return examine_node_type(sym);
581f08c3bdfSopenharmony_ci	case SYM_ARRAY:
582f08c3bdfSopenharmony_ci		return examine_array_type(sym);
583f08c3bdfSopenharmony_ci	case SYM_STRUCT:
584f08c3bdfSopenharmony_ci		return examine_struct_union_type(sym, 1);
585f08c3bdfSopenharmony_ci	case SYM_UNION:
586f08c3bdfSopenharmony_ci		return examine_struct_union_type(sym, 0);
587f08c3bdfSopenharmony_ci	case SYM_PTR:
588f08c3bdfSopenharmony_ci		return examine_pointer_type(sym);
589f08c3bdfSopenharmony_ci	case SYM_ENUM:
590f08c3bdfSopenharmony_ci		return examine_enum_type(sym);
591f08c3bdfSopenharmony_ci	case SYM_BITFIELD:
592f08c3bdfSopenharmony_ci		return examine_bitfield_type(sym);
593f08c3bdfSopenharmony_ci	case SYM_BASETYPE:
594f08c3bdfSopenharmony_ci		/* Size and alignment had better already be set up */
595f08c3bdfSopenharmony_ci		return sym;
596f08c3bdfSopenharmony_ci	case SYM_TYPEOF:
597f08c3bdfSopenharmony_ci		return examine_typeof(sym);
598f08c3bdfSopenharmony_ci	case SYM_PREPROCESSOR:
599f08c3bdfSopenharmony_ci		sparse_error(sym->pos, "ctype on preprocessor command? (%s)", show_ident(sym->ident));
600f08c3bdfSopenharmony_ci		return NULL;
601f08c3bdfSopenharmony_ci	case SYM_UNINITIALIZED:
602f08c3bdfSopenharmony_ci		sparse_error(sym->pos, "ctype on uninitialized symbol '%s'", show_typename(sym));
603f08c3bdfSopenharmony_ci		return NULL;
604f08c3bdfSopenharmony_ci	case SYM_RESTRICT:
605f08c3bdfSopenharmony_ci		examine_base_type(sym);
606f08c3bdfSopenharmony_ci		return sym;
607f08c3bdfSopenharmony_ci	case SYM_FOULED:
608f08c3bdfSopenharmony_ci		examine_base_type(sym);
609f08c3bdfSopenharmony_ci		return sym;
610f08c3bdfSopenharmony_ci	default:
611f08c3bdfSopenharmony_ci		sparse_error(sym->pos, "Examining unknown symbol type %d", sym->type);
612f08c3bdfSopenharmony_ci		break;
613f08c3bdfSopenharmony_ci	}
614f08c3bdfSopenharmony_ci	return sym;
615f08c3bdfSopenharmony_ci}
616f08c3bdfSopenharmony_ci
617f08c3bdfSopenharmony_ciconst char* get_type_name(enum type type)
618f08c3bdfSopenharmony_ci{
619f08c3bdfSopenharmony_ci	const char *type_lookup[] = {
620f08c3bdfSopenharmony_ci	[SYM_UNINITIALIZED] = "uninitialized",
621f08c3bdfSopenharmony_ci	[SYM_PREPROCESSOR] = "preprocessor",
622f08c3bdfSopenharmony_ci	[SYM_BASETYPE] = "basetype",
623f08c3bdfSopenharmony_ci	[SYM_NODE] = "node",
624f08c3bdfSopenharmony_ci	[SYM_PTR] = "pointer",
625f08c3bdfSopenharmony_ci	[SYM_FN] = "function",
626f08c3bdfSopenharmony_ci	[SYM_ARRAY] = "array",
627f08c3bdfSopenharmony_ci	[SYM_STRUCT] = "struct",
628f08c3bdfSopenharmony_ci	[SYM_UNION] = "union",
629f08c3bdfSopenharmony_ci	[SYM_ENUM] = "enum",
630f08c3bdfSopenharmony_ci	[SYM_TYPEOF] = "typeof",
631f08c3bdfSopenharmony_ci	[SYM_BITFIELD] = "bitfield",
632f08c3bdfSopenharmony_ci	[SYM_LABEL] = "label",
633f08c3bdfSopenharmony_ci	[SYM_RESTRICT] = "restrict",
634f08c3bdfSopenharmony_ci	[SYM_FOULED] = "fouled",
635f08c3bdfSopenharmony_ci	[SYM_KEYWORD] = "keyword",
636f08c3bdfSopenharmony_ci	[SYM_BAD] = "bad"};
637f08c3bdfSopenharmony_ci
638f08c3bdfSopenharmony_ci	if (type <= SYM_BAD)
639f08c3bdfSopenharmony_ci		return type_lookup[type];
640f08c3bdfSopenharmony_ci	else
641f08c3bdfSopenharmony_ci		return NULL;
642f08c3bdfSopenharmony_ci}
643f08c3bdfSopenharmony_ci
644f08c3bdfSopenharmony_cistruct symbol *examine_pointer_target(struct symbol *sym)
645f08c3bdfSopenharmony_ci{
646f08c3bdfSopenharmony_ci	return examine_base_type(sym);
647f08c3bdfSopenharmony_ci}
648f08c3bdfSopenharmony_ci
649f08c3bdfSopenharmony_cistatic struct symbol_list *restr, *fouled;
650f08c3bdfSopenharmony_ci
651f08c3bdfSopenharmony_civoid create_fouled(struct symbol *type)
652f08c3bdfSopenharmony_ci{
653f08c3bdfSopenharmony_ci	if (type->bit_size < bits_in_int) {
654f08c3bdfSopenharmony_ci		struct symbol *new = alloc_symbol(type->pos, type->type);
655f08c3bdfSopenharmony_ci		*new = *type;
656f08c3bdfSopenharmony_ci		new->bit_size = bits_in_int;
657f08c3bdfSopenharmony_ci		new->rank = 0;
658f08c3bdfSopenharmony_ci		new->type = SYM_FOULED;
659f08c3bdfSopenharmony_ci		new->ctype.base_type = type;
660f08c3bdfSopenharmony_ci		add_symbol(&restr, type);
661f08c3bdfSopenharmony_ci		add_symbol(&fouled, new);
662f08c3bdfSopenharmony_ci	}
663f08c3bdfSopenharmony_ci}
664f08c3bdfSopenharmony_ci
665f08c3bdfSopenharmony_cistruct symbol *befoul(struct symbol *type)
666f08c3bdfSopenharmony_ci{
667f08c3bdfSopenharmony_ci	struct symbol *t1, *t2;
668f08c3bdfSopenharmony_ci	while (type->type == SYM_NODE)
669f08c3bdfSopenharmony_ci		type = type->ctype.base_type;
670f08c3bdfSopenharmony_ci	PREPARE_PTR_LIST(restr, t1);
671f08c3bdfSopenharmony_ci	PREPARE_PTR_LIST(fouled, t2);
672f08c3bdfSopenharmony_ci	for (;;) {
673f08c3bdfSopenharmony_ci		if (t1 == type)
674f08c3bdfSopenharmony_ci			return t2;
675f08c3bdfSopenharmony_ci		if (!t1)
676f08c3bdfSopenharmony_ci			break;
677f08c3bdfSopenharmony_ci		NEXT_PTR_LIST(t1);
678f08c3bdfSopenharmony_ci		NEXT_PTR_LIST(t2);
679f08c3bdfSopenharmony_ci	}
680f08c3bdfSopenharmony_ci	FINISH_PTR_LIST(t2);
681f08c3bdfSopenharmony_ci	FINISH_PTR_LIST(t1);
682f08c3bdfSopenharmony_ci	return NULL;
683f08c3bdfSopenharmony_ci}
684f08c3bdfSopenharmony_ci
685f08c3bdfSopenharmony_cistatic void inherit_declaration(struct symbol *sym, struct symbol *prev)
686f08c3bdfSopenharmony_ci{
687f08c3bdfSopenharmony_ci	unsigned long mods = prev->ctype.modifiers;
688f08c3bdfSopenharmony_ci
689f08c3bdfSopenharmony_ci	// inherit function attributes
690f08c3bdfSopenharmony_ci	sym->ctype.modifiers |= mods & MOD_FUN_ATTR;
691f08c3bdfSopenharmony_ci}
692f08c3bdfSopenharmony_ci
693f08c3bdfSopenharmony_civoid check_declaration(struct symbol *sym)
694f08c3bdfSopenharmony_ci{
695f08c3bdfSopenharmony_ci	int warned = 0;
696f08c3bdfSopenharmony_ci	struct symbol *next = sym;
697f08c3bdfSopenharmony_ci
698f08c3bdfSopenharmony_ci	while ((next = next->next_id) != NULL) {
699f08c3bdfSopenharmony_ci		if (next->namespace != sym->namespace)
700f08c3bdfSopenharmony_ci			continue;
701f08c3bdfSopenharmony_ci		if (sym->scope == next->scope) {
702f08c3bdfSopenharmony_ci			sym->same_symbol = next;
703f08c3bdfSopenharmony_ci			inherit_declaration(sym, next);
704f08c3bdfSopenharmony_ci			return;
705f08c3bdfSopenharmony_ci		}
706f08c3bdfSopenharmony_ci		/* Extern in block level matches a TOPLEVEL non-static symbol */
707f08c3bdfSopenharmony_ci		if (sym->ctype.modifiers & MOD_EXTERN) {
708f08c3bdfSopenharmony_ci			if ((next->ctype.modifiers & (MOD_TOPLEVEL|MOD_STATIC)) == MOD_TOPLEVEL) {
709f08c3bdfSopenharmony_ci				sym->same_symbol = next;
710f08c3bdfSopenharmony_ci				return;
711f08c3bdfSopenharmony_ci			}
712f08c3bdfSopenharmony_ci		}
713f08c3bdfSopenharmony_ci
714f08c3bdfSopenharmony_ci		if (!Wshadow || warned)
715f08c3bdfSopenharmony_ci			continue;
716f08c3bdfSopenharmony_ci		if (get_sym_type(next) == SYM_FN)
717f08c3bdfSopenharmony_ci			continue;
718f08c3bdfSopenharmony_ci		warned = 1;
719f08c3bdfSopenharmony_ci		warning(sym->pos, "symbol '%s' shadows an earlier one", show_ident(sym->ident));
720f08c3bdfSopenharmony_ci		info(next->pos, "originally declared here");
721f08c3bdfSopenharmony_ci	}
722f08c3bdfSopenharmony_ci}
723f08c3bdfSopenharmony_ci
724f08c3bdfSopenharmony_cistatic void inherit_static(struct symbol *sym)
725f08c3bdfSopenharmony_ci{
726f08c3bdfSopenharmony_ci	struct symbol *prev;
727f08c3bdfSopenharmony_ci
728f08c3bdfSopenharmony_ci	// only 'plain' symbols are concerned
729f08c3bdfSopenharmony_ci	if (sym->ctype.modifiers & (MOD_STATIC|MOD_EXTERN))
730f08c3bdfSopenharmony_ci		return;
731f08c3bdfSopenharmony_ci
732f08c3bdfSopenharmony_ci	for (prev = sym->next_id; prev; prev = prev->next_id) {
733f08c3bdfSopenharmony_ci		if (prev->namespace != NS_SYMBOL)
734f08c3bdfSopenharmony_ci			continue;
735f08c3bdfSopenharmony_ci		if (prev->scope != file_scope)
736f08c3bdfSopenharmony_ci			continue;
737f08c3bdfSopenharmony_ci
738f08c3bdfSopenharmony_ci		sym->ctype.modifiers |= prev->ctype.modifiers & MOD_STATIC;
739f08c3bdfSopenharmony_ci
740f08c3bdfSopenharmony_ci		// previous declarations are already converted
741f08c3bdfSopenharmony_ci		return;
742f08c3bdfSopenharmony_ci	}
743f08c3bdfSopenharmony_ci}
744f08c3bdfSopenharmony_ci
745f08c3bdfSopenharmony_civoid bind_symbol_with_scope(struct symbol *sym, struct ident *ident, enum namespace ns, struct scope *scope)
746f08c3bdfSopenharmony_ci{
747f08c3bdfSopenharmony_ci	if (sym->bound) {
748f08c3bdfSopenharmony_ci		sparse_error(sym->pos, "internal error: symbol type already bound");
749f08c3bdfSopenharmony_ci		return;
750f08c3bdfSopenharmony_ci	}
751f08c3bdfSopenharmony_ci	if (ident->reserved && (ns & (NS_TYPEDEF | NS_STRUCT | NS_LABEL | NS_SYMBOL))) {
752f08c3bdfSopenharmony_ci		sparse_error(sym->pos, "Trying to use reserved word '%s' as identifier", show_ident(ident));
753f08c3bdfSopenharmony_ci		return;
754f08c3bdfSopenharmony_ci	}
755f08c3bdfSopenharmony_ci	sym->namespace = ns;
756f08c3bdfSopenharmony_ci	sym->next_id = ident->symbols;
757f08c3bdfSopenharmony_ci	ident->symbols = sym;
758f08c3bdfSopenharmony_ci	if (sym->ident && sym->ident != ident)
759f08c3bdfSopenharmony_ci		warning(sym->pos, "Symbol '%s' already bound", show_ident(sym->ident));
760f08c3bdfSopenharmony_ci	sym->ident = ident;
761f08c3bdfSopenharmony_ci	sym->bound = 1;
762f08c3bdfSopenharmony_ci
763f08c3bdfSopenharmony_ci	if (ns == NS_SYMBOL && toplevel(scope)) {
764f08c3bdfSopenharmony_ci		unsigned mod = MOD_ADDRESSABLE | MOD_TOPLEVEL;
765f08c3bdfSopenharmony_ci
766f08c3bdfSopenharmony_ci		inherit_static(sym);
767f08c3bdfSopenharmony_ci
768f08c3bdfSopenharmony_ci		scope = global_scope;
769f08c3bdfSopenharmony_ci		if (sym->ctype.modifiers & MOD_STATIC ||
770f08c3bdfSopenharmony_ci		    is_extern_inline(sym)) {
771f08c3bdfSopenharmony_ci			scope = file_scope;
772f08c3bdfSopenharmony_ci			mod = MOD_TOPLEVEL;
773f08c3bdfSopenharmony_ci		}
774f08c3bdfSopenharmony_ci		sym->ctype.modifiers |= mod;
775f08c3bdfSopenharmony_ci	}
776f08c3bdfSopenharmony_ci	bind_scope(sym, scope);
777f08c3bdfSopenharmony_ci}
778f08c3bdfSopenharmony_ci
779f08c3bdfSopenharmony_civoid bind_symbol(struct symbol *sym, struct ident *ident, enum namespace ns)
780f08c3bdfSopenharmony_ci{
781f08c3bdfSopenharmony_ci	struct scope *scope = block_scope;;
782f08c3bdfSopenharmony_ci
783f08c3bdfSopenharmony_ci	if (ns == NS_MACRO)
784f08c3bdfSopenharmony_ci		scope = file_scope;
785f08c3bdfSopenharmony_ci	if (ns == NS_LABEL)
786f08c3bdfSopenharmony_ci		scope = function_scope;
787f08c3bdfSopenharmony_ci	bind_symbol_with_scope(sym, ident, ns, scope);
788f08c3bdfSopenharmony_ci}
789f08c3bdfSopenharmony_ci
790f08c3bdfSopenharmony_cistruct symbol *create_symbol(int stream, const char *name, int type, int namespace)
791f08c3bdfSopenharmony_ci{
792f08c3bdfSopenharmony_ci	struct ident *ident = built_in_ident(name);
793f08c3bdfSopenharmony_ci	struct symbol *sym = lookup_symbol(ident, namespace);
794f08c3bdfSopenharmony_ci
795f08c3bdfSopenharmony_ci	if (sym && sym->type != type)
796f08c3bdfSopenharmony_ci		die("symbol %s created with different types: %d old %d", name,
797f08c3bdfSopenharmony_ci				type, sym->type);
798f08c3bdfSopenharmony_ci
799f08c3bdfSopenharmony_ci	if (!sym) {
800f08c3bdfSopenharmony_ci		struct token *token = built_in_token(stream, ident);
801f08c3bdfSopenharmony_ci
802f08c3bdfSopenharmony_ci		sym = alloc_symbol(token->pos, type);
803f08c3bdfSopenharmony_ci		bind_symbol(sym, token->ident, namespace);
804f08c3bdfSopenharmony_ci	}
805f08c3bdfSopenharmony_ci	return sym;
806f08c3bdfSopenharmony_ci}
807f08c3bdfSopenharmony_ci
808f08c3bdfSopenharmony_ci
809f08c3bdfSopenharmony_ci/*
810f08c3bdfSopenharmony_ci * Abstract types
811f08c3bdfSopenharmony_ci */
812f08c3bdfSopenharmony_cistruct symbol	int_type,
813f08c3bdfSopenharmony_ci		fp_type;
814f08c3bdfSopenharmony_ci
815f08c3bdfSopenharmony_ci/*
816f08c3bdfSopenharmony_ci * C types (i.e. actual instances that the abstract types
817f08c3bdfSopenharmony_ci * can map onto)
818f08c3bdfSopenharmony_ci */
819f08c3bdfSopenharmony_cistruct symbol	bool_ctype, void_ctype, type_ctype,
820f08c3bdfSopenharmony_ci		char_ctype, schar_ctype, uchar_ctype,
821f08c3bdfSopenharmony_ci		short_ctype, sshort_ctype, ushort_ctype,
822f08c3bdfSopenharmony_ci		int_ctype, sint_ctype, uint_ctype,
823f08c3bdfSopenharmony_ci		long_ctype, slong_ctype, ulong_ctype,
824f08c3bdfSopenharmony_ci		llong_ctype, sllong_ctype, ullong_ctype,
825f08c3bdfSopenharmony_ci		int128_ctype, sint128_ctype, uint128_ctype,
826f08c3bdfSopenharmony_ci		float_ctype, double_ctype, ldouble_ctype,
827f08c3bdfSopenharmony_ci		string_ctype, ptr_ctype, lazy_ptr_ctype,
828f08c3bdfSopenharmony_ci		incomplete_ctype, label_ctype, bad_ctype,
829f08c3bdfSopenharmony_ci		null_ctype;
830f08c3bdfSopenharmony_cistruct symbol	autotype_ctype;
831f08c3bdfSopenharmony_cistruct symbol	schar_ptr_ctype, short_ptr_ctype;
832f08c3bdfSopenharmony_cistruct symbol	int_ptr_ctype, uint_ptr_ctype;
833f08c3bdfSopenharmony_cistruct symbol	long_ptr_ctype, ulong_ptr_ctype;
834f08c3bdfSopenharmony_cistruct symbol	llong_ptr_ctype, ullong_ptr_ctype;
835f08c3bdfSopenharmony_cistruct symbol	size_t_ptr_ctype, intmax_ptr_ctype, ptrdiff_ptr_ctype;
836f08c3bdfSopenharmony_cistruct symbol	float32_ctype, float32x_ctype;
837f08c3bdfSopenharmony_cistruct symbol	float64_ctype, float64x_ctype;
838f08c3bdfSopenharmony_cistruct symbol	float128_ctype;
839f08c3bdfSopenharmony_cistruct symbol	const_void_ctype, const_char_ctype;
840f08c3bdfSopenharmony_cistruct symbol	const_ptr_ctype, const_string_ctype;
841f08c3bdfSopenharmony_cistruct symbol	const_wchar_ctype, const_wstring_ctype;
842f08c3bdfSopenharmony_cistruct symbol	volatile_void_ctype, volatile_ptr_ctype;
843f08c3bdfSopenharmony_cistruct symbol	volatile_bool_ctype, volatile_bool_ptr_ctype;
844f08c3bdfSopenharmony_ci
845f08c3bdfSopenharmony_cistruct symbol	zero_int;
846f08c3bdfSopenharmony_ci
847f08c3bdfSopenharmony_ci#define __INIT_IDENT(str, res) { .len = sizeof(str)-1, .name = str, .reserved = res }
848f08c3bdfSopenharmony_ci#define __IDENT(n,str,res) \
849f08c3bdfSopenharmony_ci	struct ident n  = __INIT_IDENT(str,res)
850f08c3bdfSopenharmony_ci
851f08c3bdfSopenharmony_ci#include "ident-list.h"
852f08c3bdfSopenharmony_ci
853f08c3bdfSopenharmony_civoid init_symbols(void)
854f08c3bdfSopenharmony_ci{
855f08c3bdfSopenharmony_ci	int stream = init_stream(NULL, "builtin", -1, includepath);
856f08c3bdfSopenharmony_ci
857f08c3bdfSopenharmony_ci#define __IDENT(n,str,res) \
858f08c3bdfSopenharmony_ci	hash_ident(&n)
859f08c3bdfSopenharmony_ci#include "ident-list.h"
860f08c3bdfSopenharmony_ci
861f08c3bdfSopenharmony_ci	init_parser(stream);
862f08c3bdfSopenharmony_ci}
863f08c3bdfSopenharmony_ci
864f08c3bdfSopenharmony_ci// For fix-sized types
865f08c3bdfSopenharmony_cistatic int bits_in_type32 = 32;
866f08c3bdfSopenharmony_cistatic int bits_in_type64 = 64;
867f08c3bdfSopenharmony_cistatic int bits_in_type128 = 128;
868f08c3bdfSopenharmony_ci
869f08c3bdfSopenharmony_ci#define T_BASETYPE      SYM_BASETYPE, 0, 0, NULL, NULL, NULL
870f08c3bdfSopenharmony_ci#define T_INT(R, S, M)  SYM_BASETYPE, M, R, &bits_in_##S, &max_int_alignment, &int_type
871f08c3bdfSopenharmony_ci#define T__INT(R, S)    T_INT(R, S, MOD_SIGNED)
872f08c3bdfSopenharmony_ci#define T_SINT(R, S)    T_INT(R, S, MOD_ESIGNED)
873f08c3bdfSopenharmony_ci#define T_UINT(R,S)     T_INT(R, S, MOD_UNSIGNED)
874f08c3bdfSopenharmony_ci#define T_FLOAT_(R,S,A) SYM_BASETYPE, 0, R, &bits_in_##S, A, &fp_type
875f08c3bdfSopenharmony_ci#define T_FLOAT(R, S)   T_FLOAT_(R, S, &max_fp_alignment)
876f08c3bdfSopenharmony_ci#define T_PTR(B)        SYM_PTR, 0, 0, &bits_in_pointer, &pointer_alignment, B
877f08c3bdfSopenharmony_ci#define T_NODE(M,B,S,A) SYM_NODE, M, 0, S, A, B
878f08c3bdfSopenharmony_ci#define T_CONST(B,S,A)  T_NODE(MOD_CONST, B, S, A)
879f08c3bdfSopenharmony_ci
880f08c3bdfSopenharmony_cistatic const struct ctype_declare {
881f08c3bdfSopenharmony_ci	struct symbol *ptr;
882f08c3bdfSopenharmony_ci	enum type type;
883f08c3bdfSopenharmony_ci	unsigned long modifiers;
884f08c3bdfSopenharmony_ci	int rank;
885f08c3bdfSopenharmony_ci	int *bit_size;
886f08c3bdfSopenharmony_ci	int *maxalign;
887f08c3bdfSopenharmony_ci	struct symbol *base_type;
888f08c3bdfSopenharmony_ci} ctype_declaration[] = {
889f08c3bdfSopenharmony_ci	{ &bool_ctype,         T_INT(-3, bool, MOD_UNSIGNED) },
890f08c3bdfSopenharmony_ci	{ &void_ctype,         T_BASETYPE },
891f08c3bdfSopenharmony_ci	{ &type_ctype,         T_BASETYPE },
892f08c3bdfSopenharmony_ci	{ &incomplete_ctype,   T_BASETYPE },
893f08c3bdfSopenharmony_ci	{ &autotype_ctype,     T_BASETYPE },
894f08c3bdfSopenharmony_ci	{ &bad_ctype,          T_BASETYPE },
895f08c3bdfSopenharmony_ci
896f08c3bdfSopenharmony_ci	{ &char_ctype,         T__INT(-2, char) },
897f08c3bdfSopenharmony_ci	{ &schar_ctype,        T_SINT(-2, char) },
898f08c3bdfSopenharmony_ci	{ &uchar_ctype,        T_UINT(-2, char) },
899f08c3bdfSopenharmony_ci	{ &short_ctype,        T__INT(-1, short) },
900f08c3bdfSopenharmony_ci	{ &sshort_ctype,       T_SINT(-1, short) },
901f08c3bdfSopenharmony_ci	{ &ushort_ctype,       T_UINT(-1, short) },
902f08c3bdfSopenharmony_ci	{ &int_ctype,          T__INT( 0, int) },
903f08c3bdfSopenharmony_ci	{ &sint_ctype,         T_SINT( 0, int) },
904f08c3bdfSopenharmony_ci	{ &uint_ctype,         T_UINT( 0, int) },
905f08c3bdfSopenharmony_ci	{ &long_ctype,         T__INT( 1, long) },
906f08c3bdfSopenharmony_ci	{ &slong_ctype,        T_SINT( 1, long) },
907f08c3bdfSopenharmony_ci	{ &ulong_ctype,        T_UINT( 1, long) },
908f08c3bdfSopenharmony_ci	{ &llong_ctype,        T__INT( 2, longlong) },
909f08c3bdfSopenharmony_ci	{ &sllong_ctype,       T_SINT( 2, longlong) },
910f08c3bdfSopenharmony_ci	{ &ullong_ctype,       T_UINT( 2, longlong) },
911f08c3bdfSopenharmony_ci	{ &int128_ctype,       T__INT( 3, type128) },
912f08c3bdfSopenharmony_ci	{ &sint128_ctype,      T_SINT( 3, type128) },
913f08c3bdfSopenharmony_ci	{ &uint128_ctype,      T_UINT( 3, type128) },
914f08c3bdfSopenharmony_ci
915f08c3bdfSopenharmony_ci	{ &float_ctype,        T_FLOAT(-1, float) },
916f08c3bdfSopenharmony_ci	{ &double_ctype,       T_FLOAT( 0, double) },
917f08c3bdfSopenharmony_ci	{ &ldouble_ctype,      T_FLOAT( 1, longdouble) },
918f08c3bdfSopenharmony_ci
919f08c3bdfSopenharmony_ci	{ &float32_ctype,      T_FLOAT(-1, type32) },
920f08c3bdfSopenharmony_ci	{ &float32x_ctype,     T_FLOAT(-1, double) },
921f08c3bdfSopenharmony_ci	{ &float64_ctype,      T_FLOAT( 0, type64) },
922f08c3bdfSopenharmony_ci	{ &float64x_ctype,     T_FLOAT( 1, longdouble) },
923f08c3bdfSopenharmony_ci	{ &float128_ctype,     T_FLOAT_(2, type128, &max_alignment) },
924f08c3bdfSopenharmony_ci
925f08c3bdfSopenharmony_ci	{ &string_ctype,       T_PTR(&char_ctype) },
926f08c3bdfSopenharmony_ci	{ &ptr_ctype,          T_PTR(&void_ctype) },
927f08c3bdfSopenharmony_ci	{ &null_ctype,         T_PTR(&void_ctype) },
928f08c3bdfSopenharmony_ci	{ &label_ctype,        T_PTR(&void_ctype) },
929f08c3bdfSopenharmony_ci	{ &lazy_ptr_ctype,     T_PTR(&void_ctype) },
930f08c3bdfSopenharmony_ci	{ &schar_ptr_ctype,    T_PTR(&schar_ctype) },
931f08c3bdfSopenharmony_ci	{ &short_ptr_ctype,    T_PTR(&short_ctype) },
932f08c3bdfSopenharmony_ci	{ &int_ptr_ctype,      T_PTR(&int_ctype) },
933f08c3bdfSopenharmony_ci	{ &uint_ptr_ctype,     T_PTR(&uint_ctype) },
934f08c3bdfSopenharmony_ci	{ &long_ptr_ctype,     T_PTR(&long_ctype) },
935f08c3bdfSopenharmony_ci	{ &ulong_ptr_ctype,    T_PTR(&ulong_ctype) },
936f08c3bdfSopenharmony_ci	{ &llong_ptr_ctype,    T_PTR(&llong_ctype) },
937f08c3bdfSopenharmony_ci	{ &ullong_ptr_ctype,   T_PTR(&ullong_ctype) },
938f08c3bdfSopenharmony_ci	{ &size_t_ptr_ctype,   T_PTR(&void_ctype) },	// will be adjusted
939f08c3bdfSopenharmony_ci	{ &intmax_ptr_ctype,   T_PTR(&void_ctype) },	// will be adjusted
940f08c3bdfSopenharmony_ci	{ &ptrdiff_ptr_ctype,  T_PTR(&void_ctype) },	// will be adjusted
941f08c3bdfSopenharmony_ci	{ &const_ptr_ctype,    T_PTR(&const_void_ctype) },
942f08c3bdfSopenharmony_ci	{ &const_string_ctype, T_PTR(&const_char_ctype) },
943f08c3bdfSopenharmony_ci	{ &const_wstring_ctype,T_PTR(&const_wchar_ctype) },
944f08c3bdfSopenharmony_ci
945f08c3bdfSopenharmony_ci	{ &const_void_ctype,   T_CONST(&void_ctype, NULL, NULL) },
946f08c3bdfSopenharmony_ci	{ &const_char_ctype,   T_CONST(&char_ctype, &bits_in_char, &max_int_alignment)},
947f08c3bdfSopenharmony_ci	{ &const_wchar_ctype,  T_CONST(&int_ctype, NULL, NULL) },
948f08c3bdfSopenharmony_ci	{ &volatile_void_ctype,T_NODE(MOD_VOLATILE, &void_ctype, NULL, NULL) },
949f08c3bdfSopenharmony_ci	{ &volatile_ptr_ctype, T_PTR(&volatile_void_ctype) },
950f08c3bdfSopenharmony_ci	{ &volatile_bool_ctype,T_NODE(MOD_VOLATILE, &bool_ctype, NULL, NULL) },
951f08c3bdfSopenharmony_ci	{ &volatile_bool_ptr_ctype, T_PTR(&volatile_bool_ctype) },
952f08c3bdfSopenharmony_ci	{ NULL, }
953f08c3bdfSopenharmony_ci};
954f08c3bdfSopenharmony_ci
955f08c3bdfSopenharmony_civoid init_ctype(void)
956f08c3bdfSopenharmony_ci{
957f08c3bdfSopenharmony_ci	const struct ctype_declare *ctype;
958f08c3bdfSopenharmony_ci
959f08c3bdfSopenharmony_ci	for (ctype = ctype_declaration ; ctype->ptr; ctype++) {
960f08c3bdfSopenharmony_ci		struct symbol *sym = ctype->ptr;
961f08c3bdfSopenharmony_ci		unsigned long bit_size = ctype->bit_size ? *ctype->bit_size : -1;
962f08c3bdfSopenharmony_ci		unsigned long maxalign = ctype->maxalign ? *ctype->maxalign : 0;
963f08c3bdfSopenharmony_ci		unsigned long alignment = bits_to_bytes(bit_size);
964f08c3bdfSopenharmony_ci
965f08c3bdfSopenharmony_ci		if (alignment > maxalign)
966f08c3bdfSopenharmony_ci			alignment = maxalign;
967f08c3bdfSopenharmony_ci		sym->type = ctype->type;
968f08c3bdfSopenharmony_ci		sym->rank = ctype->rank;
969f08c3bdfSopenharmony_ci		sym->bit_size = bit_size;
970f08c3bdfSopenharmony_ci		sym->ctype.alignment = alignment;
971f08c3bdfSopenharmony_ci		sym->ctype.base_type = ctype->base_type;
972f08c3bdfSopenharmony_ci		sym->ctype.modifiers = ctype->modifiers;
973f08c3bdfSopenharmony_ci
974f08c3bdfSopenharmony_ci		if (sym->type == SYM_NODE) {
975f08c3bdfSopenharmony_ci			struct symbol *base = sym->ctype.base_type;
976f08c3bdfSopenharmony_ci			sym->rank = base->rank;
977f08c3bdfSopenharmony_ci			if (!ctype->bit_size)
978f08c3bdfSopenharmony_ci				sym->bit_size = base->bit_size;
979f08c3bdfSopenharmony_ci			if (!ctype->maxalign)
980f08c3bdfSopenharmony_ci				sym->ctype.alignment = base->ctype.alignment;
981f08c3bdfSopenharmony_ci		}
982f08c3bdfSopenharmony_ci	}
983f08c3bdfSopenharmony_ci
984f08c3bdfSopenharmony_ci	// and now some adjustments
985f08c3bdfSopenharmony_ci	if (funsigned_char) {
986f08c3bdfSopenharmony_ci		char_ctype.ctype.modifiers |= MOD_UNSIGNED;
987f08c3bdfSopenharmony_ci		char_ctype.ctype.modifiers &= ~MOD_SIGNED;
988f08c3bdfSopenharmony_ci	}
989f08c3bdfSopenharmony_ci
990f08c3bdfSopenharmony_ci	if (!ptrdiff_ctype)
991f08c3bdfSopenharmony_ci		ptrdiff_ctype = ssize_t_ctype;
992f08c3bdfSopenharmony_ci	if (!intptr_ctype)
993f08c3bdfSopenharmony_ci		intptr_ctype = ssize_t_ctype;
994f08c3bdfSopenharmony_ci	if (!uintptr_ctype)
995f08c3bdfSopenharmony_ci		uintptr_ctype = size_t_ctype;
996f08c3bdfSopenharmony_ci
997f08c3bdfSopenharmony_ci	size_t_ptr_ctype.ctype.base_type = size_t_ctype;
998f08c3bdfSopenharmony_ci	intmax_ptr_ctype.ctype.base_type = intmax_ctype;
999f08c3bdfSopenharmony_ci	ptrdiff_ptr_ctype.ctype.base_type = ptrdiff_ctype;
1000f08c3bdfSopenharmony_ci
1001f08c3bdfSopenharmony_ci	const_wchar_ctype.ctype.base_type = wchar_ctype;
1002f08c3bdfSopenharmony_ci	const_wchar_ctype.rank = wchar_ctype->rank;
1003f08c3bdfSopenharmony_ci	const_wchar_ctype.ctype.alignment = wchar_ctype->ctype.alignment;
1004f08c3bdfSopenharmony_ci	const_wchar_ctype.bit_size = wchar_ctype->bit_size;
1005f08c3bdfSopenharmony_ci}
1006