1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci * sparse/show-parse.c
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 * Print out results of parsing for debugging and testing.
26f08c3bdfSopenharmony_ci */
27f08c3bdfSopenharmony_ci#include <stdarg.h>
28f08c3bdfSopenharmony_ci#include <stdlib.h>
29f08c3bdfSopenharmony_ci#include <stdio.h>
30f08c3bdfSopenharmony_ci#include <string.h>
31f08c3bdfSopenharmony_ci#include <ctype.h>
32f08c3bdfSopenharmony_ci#include <unistd.h>
33f08c3bdfSopenharmony_ci#include <fcntl.h>
34f08c3bdfSopenharmony_ci
35f08c3bdfSopenharmony_ci#include "lib.h"
36f08c3bdfSopenharmony_ci#include "allocate.h"
37f08c3bdfSopenharmony_ci#include "token.h"
38f08c3bdfSopenharmony_ci#include "parse.h"
39f08c3bdfSopenharmony_ci#include "symbol.h"
40f08c3bdfSopenharmony_ci#include "scope.h"
41f08c3bdfSopenharmony_ci#include "expression.h"
42f08c3bdfSopenharmony_ci#include "target.h"
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_cistatic int show_symbol_expr(struct symbol *sym);
45f08c3bdfSopenharmony_cistatic int show_string_expr(struct expression *expr);
46f08c3bdfSopenharmony_ci
47f08c3bdfSopenharmony_cistatic void do_debug_symbol(struct symbol *sym, int indent)
48f08c3bdfSopenharmony_ci{
49f08c3bdfSopenharmony_ci	static const char indent_string[] = "                                  ";
50f08c3bdfSopenharmony_ci	static const char *typestr[] = {
51f08c3bdfSopenharmony_ci		[SYM_UNINITIALIZED] = "none",
52f08c3bdfSopenharmony_ci		[SYM_PREPROCESSOR] = "cpp.",
53f08c3bdfSopenharmony_ci		[SYM_BASETYPE] = "base",
54f08c3bdfSopenharmony_ci		[SYM_NODE] = "node",
55f08c3bdfSopenharmony_ci		[SYM_PTR] = "ptr.",
56f08c3bdfSopenharmony_ci		[SYM_FN] = "fn..",
57f08c3bdfSopenharmony_ci		[SYM_ARRAY] = "arry",
58f08c3bdfSopenharmony_ci		[SYM_STRUCT] = "strt",
59f08c3bdfSopenharmony_ci		[SYM_UNION] = "unin",
60f08c3bdfSopenharmony_ci		[SYM_ENUM] = "enum",
61f08c3bdfSopenharmony_ci		[SYM_TYPEOF] = "tpof",
62f08c3bdfSopenharmony_ci		[SYM_BITFIELD] = "bitf",
63f08c3bdfSopenharmony_ci		[SYM_LABEL] = "labl",
64f08c3bdfSopenharmony_ci		[SYM_RESTRICT] = "rstr",
65f08c3bdfSopenharmony_ci		[SYM_FOULED] = "foul",
66f08c3bdfSopenharmony_ci		[SYM_BAD] = "bad.",
67f08c3bdfSopenharmony_ci	};
68f08c3bdfSopenharmony_ci	struct context *context;
69f08c3bdfSopenharmony_ci	int i;
70f08c3bdfSopenharmony_ci
71f08c3bdfSopenharmony_ci	if (!sym)
72f08c3bdfSopenharmony_ci		return;
73f08c3bdfSopenharmony_ci	fprintf(stderr, "%.*s%s%3d:%lu %s%s (as: %s) %p (%s:%d:%d) %s\n",
74f08c3bdfSopenharmony_ci		indent, indent_string, typestr[sym->type],
75f08c3bdfSopenharmony_ci		sym->bit_size, sym->ctype.alignment,
76f08c3bdfSopenharmony_ci		modifier_string(sym->ctype.modifiers), show_ident(sym->ident),
77f08c3bdfSopenharmony_ci		show_as(sym->ctype.as),
78f08c3bdfSopenharmony_ci		sym, stream_name(sym->pos.stream), sym->pos.line, sym->pos.pos,
79f08c3bdfSopenharmony_ci		builtin_typename(sym) ?: "");
80f08c3bdfSopenharmony_ci	i = 0;
81f08c3bdfSopenharmony_ci	FOR_EACH_PTR(sym->ctype.contexts, context) {
82f08c3bdfSopenharmony_ci		/* FIXME: should print context expression */
83f08c3bdfSopenharmony_ci		fprintf(stderr, "< context%d: in=%d, out=%d\n",
84f08c3bdfSopenharmony_ci			i, context->in, context->out);
85f08c3bdfSopenharmony_ci		fprintf(stderr, "  end context%d >\n", i);
86f08c3bdfSopenharmony_ci		i++;
87f08c3bdfSopenharmony_ci	} END_FOR_EACH_PTR(context);
88f08c3bdfSopenharmony_ci	if (sym->type == SYM_FN) {
89f08c3bdfSopenharmony_ci		struct symbol *arg;
90f08c3bdfSopenharmony_ci		i = 0;
91f08c3bdfSopenharmony_ci		FOR_EACH_PTR(sym->arguments, arg) {
92f08c3bdfSopenharmony_ci			fprintf(stderr, "< arg%d:\n", i);
93f08c3bdfSopenharmony_ci			do_debug_symbol(arg, 0);
94f08c3bdfSopenharmony_ci			fprintf(stderr, "  end arg%d >\n", i);
95f08c3bdfSopenharmony_ci			i++;
96f08c3bdfSopenharmony_ci		} END_FOR_EACH_PTR(arg);
97f08c3bdfSopenharmony_ci	}
98f08c3bdfSopenharmony_ci	do_debug_symbol(sym->ctype.base_type, indent+2);
99f08c3bdfSopenharmony_ci}
100f08c3bdfSopenharmony_ci
101f08c3bdfSopenharmony_civoid debug_symbol(struct symbol *sym)
102f08c3bdfSopenharmony_ci{
103f08c3bdfSopenharmony_ci	do_debug_symbol(sym, 0);
104f08c3bdfSopenharmony_ci}
105f08c3bdfSopenharmony_ci
106f08c3bdfSopenharmony_ci/*
107f08c3bdfSopenharmony_ci * Symbol type printout. The type system is by far the most
108f08c3bdfSopenharmony_ci * complicated part of C - everything else is trivial.
109f08c3bdfSopenharmony_ci */
110f08c3bdfSopenharmony_cistatic const char *show_modifiers(unsigned long mod, int term)
111f08c3bdfSopenharmony_ci{
112f08c3bdfSopenharmony_ci	static char buffer[100];
113f08c3bdfSopenharmony_ci	int len = 0;
114f08c3bdfSopenharmony_ci	int i;
115f08c3bdfSopenharmony_ci	struct mod_name {
116f08c3bdfSopenharmony_ci		unsigned long mod;
117f08c3bdfSopenharmony_ci		const char *name;
118f08c3bdfSopenharmony_ci	} *m;
119f08c3bdfSopenharmony_ci
120f08c3bdfSopenharmony_ci	static struct mod_name mod_names[] = {
121f08c3bdfSopenharmony_ci		{MOD_AUTO,		"auto"},
122f08c3bdfSopenharmony_ci		{MOD_EXTERN,		"extern"},
123f08c3bdfSopenharmony_ci		{MOD_REGISTER,		"register"},
124f08c3bdfSopenharmony_ci		{MOD_STATIC,		"static"},
125f08c3bdfSopenharmony_ci		{MOD_INLINE,		"inline"},
126f08c3bdfSopenharmony_ci		{MOD_CONST,		"const"},
127f08c3bdfSopenharmony_ci		{MOD_RESTRICT,		"restrict"},
128f08c3bdfSopenharmony_ci		{MOD_VOLATILE,		"volatile"},
129f08c3bdfSopenharmony_ci		{MOD_ADDRESSABLE,	"[addressable]"},
130f08c3bdfSopenharmony_ci		{MOD_ASSIGNED,		"[assigned]"},
131f08c3bdfSopenharmony_ci		{MOD_ATOMIC,		"[atomic]"},
132f08c3bdfSopenharmony_ci		{MOD_BITWISE,		"[bitwise]"},
133f08c3bdfSopenharmony_ci		{MOD_EXPLICITLY_SIGNED,	"[explicitly-signed]"},
134f08c3bdfSopenharmony_ci		{MOD_GNU_INLINE,	"[gnu_inline]"},
135f08c3bdfSopenharmony_ci		{MOD_NOCAST,		"[nocast]"},
136f08c3bdfSopenharmony_ci		{MOD_NODEREF,		"[noderef]"},
137f08c3bdfSopenharmony_ci		{MOD_NORETURN,		"[noreturn]"},
138f08c3bdfSopenharmony_ci		{MOD_PURE,		"[pure]"},
139f08c3bdfSopenharmony_ci		{MOD_SAFE,		"[safe]"},
140f08c3bdfSopenharmony_ci		{MOD_SIGNED,		"[signed]"},
141f08c3bdfSopenharmony_ci		{MOD_TLS,		"[tls]"},
142f08c3bdfSopenharmony_ci		{MOD_TOPLEVEL,		"[toplevel]"},
143f08c3bdfSopenharmony_ci		{MOD_UNSIGNED,		"[unsigned]"},
144f08c3bdfSopenharmony_ci		{MOD_UNUSED,		"[unused]"},
145f08c3bdfSopenharmony_ci		{MOD_USERTYPE,		"[usertype]"},
146f08c3bdfSopenharmony_ci	};
147f08c3bdfSopenharmony_ci
148f08c3bdfSopenharmony_ci	for (i = 0; i < ARRAY_SIZE(mod_names); i++) {
149f08c3bdfSopenharmony_ci		m = mod_names + i;
150f08c3bdfSopenharmony_ci		if (mod & m->mod) {
151f08c3bdfSopenharmony_ci			char c;
152f08c3bdfSopenharmony_ci			const char *name = m->name;
153f08c3bdfSopenharmony_ci			while ((c = *name++) != '\0' && len + 2 < sizeof buffer)
154f08c3bdfSopenharmony_ci				buffer[len++] = c;
155f08c3bdfSopenharmony_ci			buffer[len++] = ' ';
156f08c3bdfSopenharmony_ci		}
157f08c3bdfSopenharmony_ci	}
158f08c3bdfSopenharmony_ci	if (len && !term)		// strip the trailing space
159f08c3bdfSopenharmony_ci		--len;
160f08c3bdfSopenharmony_ci	buffer[len] = 0;
161f08c3bdfSopenharmony_ci	return buffer;
162f08c3bdfSopenharmony_ci}
163f08c3bdfSopenharmony_ci
164f08c3bdfSopenharmony_ci///
165f08c3bdfSopenharmony_ci// show the modifiers, terminated by a space if not empty
166f08c3bdfSopenharmony_ciconst char *modifier_string(unsigned long mod)
167f08c3bdfSopenharmony_ci{
168f08c3bdfSopenharmony_ci	return show_modifiers(mod, 1);
169f08c3bdfSopenharmony_ci}
170f08c3bdfSopenharmony_ci
171f08c3bdfSopenharmony_ci///
172f08c3bdfSopenharmony_ci// show the modifiers, without an ending space
173f08c3bdfSopenharmony_ciconst char *modifier_name(unsigned long mod)
174f08c3bdfSopenharmony_ci{
175f08c3bdfSopenharmony_ci	return show_modifiers(mod, 0);
176f08c3bdfSopenharmony_ci}
177f08c3bdfSopenharmony_ci
178f08c3bdfSopenharmony_cistatic void show_struct_member(struct symbol *sym)
179f08c3bdfSopenharmony_ci{
180f08c3bdfSopenharmony_ci	printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset, sym->bit_offset);
181f08c3bdfSopenharmony_ci	printf("\n");
182f08c3bdfSopenharmony_ci}
183f08c3bdfSopenharmony_ci
184f08c3bdfSopenharmony_civoid show_symbol_list(struct symbol_list *list)
185f08c3bdfSopenharmony_ci{
186f08c3bdfSopenharmony_ci	struct symbol *sym;
187f08c3bdfSopenharmony_ci	const char *prepend = "";
188f08c3bdfSopenharmony_ci
189f08c3bdfSopenharmony_ci	FOR_EACH_PTR(list, sym) {
190f08c3bdfSopenharmony_ci		puts(prepend);
191f08c3bdfSopenharmony_ci		prepend = ", ";
192f08c3bdfSopenharmony_ci		show_symbol(sym);
193f08c3bdfSopenharmony_ci	} END_FOR_EACH_PTR(sym);
194f08c3bdfSopenharmony_ci}
195f08c3bdfSopenharmony_ci
196f08c3bdfSopenharmony_ciconst char *show_as(struct ident *as)
197f08c3bdfSopenharmony_ci{
198f08c3bdfSopenharmony_ci	if (!as)
199f08c3bdfSopenharmony_ci		return "";
200f08c3bdfSopenharmony_ci	return show_ident(as);
201f08c3bdfSopenharmony_ci}
202f08c3bdfSopenharmony_ci
203f08c3bdfSopenharmony_cistruct type_name {
204f08c3bdfSopenharmony_ci	char *start;
205f08c3bdfSopenharmony_ci	char *end;
206f08c3bdfSopenharmony_ci};
207f08c3bdfSopenharmony_ci
208f08c3bdfSopenharmony_cistatic void FORMAT_ATTR(2) prepend(struct type_name *name, const char *fmt, ...)
209f08c3bdfSopenharmony_ci{
210f08c3bdfSopenharmony_ci	static char buffer[512];
211f08c3bdfSopenharmony_ci	int n;
212f08c3bdfSopenharmony_ci
213f08c3bdfSopenharmony_ci	va_list args;
214f08c3bdfSopenharmony_ci	va_start(args, fmt);
215f08c3bdfSopenharmony_ci	n = vsprintf(buffer, fmt, args);
216f08c3bdfSopenharmony_ci	va_end(args);
217f08c3bdfSopenharmony_ci
218f08c3bdfSopenharmony_ci	name->start -= n;
219f08c3bdfSopenharmony_ci	memcpy(name->start, buffer, n);
220f08c3bdfSopenharmony_ci}
221f08c3bdfSopenharmony_ci
222f08c3bdfSopenharmony_cistatic void FORMAT_ATTR(2) append(struct type_name *name, const char *fmt, ...)
223f08c3bdfSopenharmony_ci{
224f08c3bdfSopenharmony_ci	static char buffer[512];
225f08c3bdfSopenharmony_ci	int n;
226f08c3bdfSopenharmony_ci
227f08c3bdfSopenharmony_ci	va_list args;
228f08c3bdfSopenharmony_ci	va_start(args, fmt);
229f08c3bdfSopenharmony_ci	n = vsprintf(buffer, fmt, args);
230f08c3bdfSopenharmony_ci	va_end(args);
231f08c3bdfSopenharmony_ci
232f08c3bdfSopenharmony_ci	memcpy(name->end, buffer, n);
233f08c3bdfSopenharmony_ci	name->end += n;
234f08c3bdfSopenharmony_ci}
235f08c3bdfSopenharmony_ci
236f08c3bdfSopenharmony_cistatic struct ctype_name {
237f08c3bdfSopenharmony_ci	struct symbol *sym;
238f08c3bdfSopenharmony_ci	const char *name;
239f08c3bdfSopenharmony_ci	const char *suffix;
240f08c3bdfSopenharmony_ci} typenames[] = {
241f08c3bdfSopenharmony_ci	{ & char_ctype,  "char", "" },
242f08c3bdfSopenharmony_ci	{ &schar_ctype,  "signed char", "" },
243f08c3bdfSopenharmony_ci	{ &uchar_ctype,  "unsigned char", "" },
244f08c3bdfSopenharmony_ci	{ & short_ctype, "short", "" },
245f08c3bdfSopenharmony_ci	{ &sshort_ctype, "signed short", "" },
246f08c3bdfSopenharmony_ci	{ &ushort_ctype, "unsigned short", "" },
247f08c3bdfSopenharmony_ci	{ & int_ctype,   "int", "" },
248f08c3bdfSopenharmony_ci	{ &sint_ctype,   "signed int", "" },
249f08c3bdfSopenharmony_ci	{ &uint_ctype,   "unsigned int", "U" },
250f08c3bdfSopenharmony_ci	{ & long_ctype,  "long", "L" },
251f08c3bdfSopenharmony_ci	{ &slong_ctype,  "signed long", "L" },
252f08c3bdfSopenharmony_ci	{ &ulong_ctype,  "unsigned long", "UL" },
253f08c3bdfSopenharmony_ci	{ & llong_ctype, "long long", "LL" },
254f08c3bdfSopenharmony_ci	{ &sllong_ctype, "signed long long", "LL" },
255f08c3bdfSopenharmony_ci	{ &ullong_ctype, "unsigned long long", "ULL" },
256f08c3bdfSopenharmony_ci	{ & int128_ctype, "__int128", "" },
257f08c3bdfSopenharmony_ci	{ &sint128_ctype, "signed __int128", "" },
258f08c3bdfSopenharmony_ci	{ &uint128_ctype, "unsigned __int128", "" },
259f08c3bdfSopenharmony_ci
260f08c3bdfSopenharmony_ci	{ &void_ctype,   "void", "" },
261f08c3bdfSopenharmony_ci	{ &bool_ctype,   "bool", "" },
262f08c3bdfSopenharmony_ci
263f08c3bdfSopenharmony_ci	{ &float_ctype,  "float", "F" },
264f08c3bdfSopenharmony_ci	{ &double_ctype, "double", "" },
265f08c3bdfSopenharmony_ci	{ &ldouble_ctype,"long double", "L" },
266f08c3bdfSopenharmony_ci	{ &incomplete_ctype, "incomplete type", "" },
267f08c3bdfSopenharmony_ci	{ &int_type, "abstract int", "" },
268f08c3bdfSopenharmony_ci	{ &fp_type, "abstract fp", "" },
269f08c3bdfSopenharmony_ci	{ &label_ctype, "label type", "" },
270f08c3bdfSopenharmony_ci	{ &bad_ctype, "bad type", "" },
271f08c3bdfSopenharmony_ci};
272f08c3bdfSopenharmony_ci
273f08c3bdfSopenharmony_ciconst char *builtin_typename(struct symbol *sym)
274f08c3bdfSopenharmony_ci{
275f08c3bdfSopenharmony_ci	int i;
276f08c3bdfSopenharmony_ci
277f08c3bdfSopenharmony_ci	for (i = 0; i < ARRAY_SIZE(typenames); i++)
278f08c3bdfSopenharmony_ci		if (typenames[i].sym == sym)
279f08c3bdfSopenharmony_ci			return typenames[i].name;
280f08c3bdfSopenharmony_ci	return NULL;
281f08c3bdfSopenharmony_ci}
282f08c3bdfSopenharmony_ci
283f08c3bdfSopenharmony_ciconst char *builtin_type_suffix(struct symbol *sym)
284f08c3bdfSopenharmony_ci{
285f08c3bdfSopenharmony_ci	int i;
286f08c3bdfSopenharmony_ci
287f08c3bdfSopenharmony_ci	for (i = 0; i < ARRAY_SIZE(typenames); i++)
288f08c3bdfSopenharmony_ci		if (typenames[i].sym == sym)
289f08c3bdfSopenharmony_ci			return typenames[i].suffix;
290f08c3bdfSopenharmony_ci	return NULL;
291f08c3bdfSopenharmony_ci}
292f08c3bdfSopenharmony_ci
293f08c3bdfSopenharmony_ciconst char *builtin_ctypename(struct ctype *ctype)
294f08c3bdfSopenharmony_ci{
295f08c3bdfSopenharmony_ci	int i;
296f08c3bdfSopenharmony_ci
297f08c3bdfSopenharmony_ci	for (i = 0; i < ARRAY_SIZE(typenames); i++)
298f08c3bdfSopenharmony_ci		if (&typenames[i].sym->ctype == ctype)
299f08c3bdfSopenharmony_ci			return typenames[i].name;
300f08c3bdfSopenharmony_ci	return NULL;
301f08c3bdfSopenharmony_ci}
302f08c3bdfSopenharmony_ci
303f08c3bdfSopenharmony_cistatic void do_show_type(struct symbol *sym, struct type_name *name)
304f08c3bdfSopenharmony_ci{
305f08c3bdfSopenharmony_ci	const char *typename;
306f08c3bdfSopenharmony_ci	unsigned long mod = 0;
307f08c3bdfSopenharmony_ci	struct ident *as = NULL;
308f08c3bdfSopenharmony_ci	int was_ptr = 0;
309f08c3bdfSopenharmony_ci	int restr = 0;
310f08c3bdfSopenharmony_ci	int fouled = 0;
311f08c3bdfSopenharmony_ci
312f08c3bdfSopenharmony_cideeper:
313f08c3bdfSopenharmony_ci	if (sym && (sym->type != SYM_NODE && sym->type != SYM_ARRAY &&
314f08c3bdfSopenharmony_ci		     sym->type != SYM_BITFIELD)) {
315f08c3bdfSopenharmony_ci		const char *s;
316f08c3bdfSopenharmony_ci		size_t len;
317f08c3bdfSopenharmony_ci
318f08c3bdfSopenharmony_ci		if (as)
319f08c3bdfSopenharmony_ci			prepend(name, "%s ", show_as(as));
320f08c3bdfSopenharmony_ci
321f08c3bdfSopenharmony_ci		if (sym && (sym->type == SYM_BASETYPE || sym->type == SYM_ENUM))
322f08c3bdfSopenharmony_ci			mod &= ~MOD_SPECIFIER;
323f08c3bdfSopenharmony_ci		s = modifier_string(mod);
324f08c3bdfSopenharmony_ci		len = strlen(s);
325f08c3bdfSopenharmony_ci		name->start -= len;
326f08c3bdfSopenharmony_ci		memcpy(name->start, s, len);
327f08c3bdfSopenharmony_ci		mod = 0;
328f08c3bdfSopenharmony_ci		as = NULL;
329f08c3bdfSopenharmony_ci	}
330f08c3bdfSopenharmony_ci
331f08c3bdfSopenharmony_ci	if (!sym)
332f08c3bdfSopenharmony_ci		goto out;
333f08c3bdfSopenharmony_ci
334f08c3bdfSopenharmony_ci	if ((typename = builtin_typename(sym))) {
335f08c3bdfSopenharmony_ci		int len = strlen(typename);
336f08c3bdfSopenharmony_ci		if (name->start != name->end)
337f08c3bdfSopenharmony_ci			*--name->start = ' ';
338f08c3bdfSopenharmony_ci		name->start -= len;
339f08c3bdfSopenharmony_ci		memcpy(name->start, typename, len);
340f08c3bdfSopenharmony_ci		goto out;
341f08c3bdfSopenharmony_ci	}
342f08c3bdfSopenharmony_ci
343f08c3bdfSopenharmony_ci	/* Prepend */
344f08c3bdfSopenharmony_ci	switch (sym->type) {
345f08c3bdfSopenharmony_ci	case SYM_PTR:
346f08c3bdfSopenharmony_ci		prepend(name, "*");
347f08c3bdfSopenharmony_ci		mod = sym->ctype.modifiers;
348f08c3bdfSopenharmony_ci		as = sym->ctype.as;
349f08c3bdfSopenharmony_ci		was_ptr = 1;
350f08c3bdfSopenharmony_ci		examine_pointer_target(sym);
351f08c3bdfSopenharmony_ci		break;
352f08c3bdfSopenharmony_ci
353f08c3bdfSopenharmony_ci	case SYM_FN:
354f08c3bdfSopenharmony_ci		if (was_ptr) {
355f08c3bdfSopenharmony_ci			prepend(name, "( ");
356f08c3bdfSopenharmony_ci			append(name, " )");
357f08c3bdfSopenharmony_ci			was_ptr = 0;
358f08c3bdfSopenharmony_ci		}
359f08c3bdfSopenharmony_ci		append(name, "( ... )");
360f08c3bdfSopenharmony_ci		break;
361f08c3bdfSopenharmony_ci
362f08c3bdfSopenharmony_ci	case SYM_STRUCT:
363f08c3bdfSopenharmony_ci		if (name->start != name->end)
364f08c3bdfSopenharmony_ci			*--name->start = ' ';
365f08c3bdfSopenharmony_ci		prepend(name, "struct %s", show_ident(sym->ident));
366f08c3bdfSopenharmony_ci		goto out;
367f08c3bdfSopenharmony_ci
368f08c3bdfSopenharmony_ci	case SYM_UNION:
369f08c3bdfSopenharmony_ci		if (name->start != name->end)
370f08c3bdfSopenharmony_ci			*--name->start = ' ';
371f08c3bdfSopenharmony_ci		prepend(name, "union %s", show_ident(sym->ident));
372f08c3bdfSopenharmony_ci		goto out;
373f08c3bdfSopenharmony_ci
374f08c3bdfSopenharmony_ci	case SYM_ENUM:
375f08c3bdfSopenharmony_ci		prepend(name, "enum %s ", show_ident(sym->ident));
376f08c3bdfSopenharmony_ci		break;
377f08c3bdfSopenharmony_ci
378f08c3bdfSopenharmony_ci	case SYM_NODE:
379f08c3bdfSopenharmony_ci		if (sym->ident)
380f08c3bdfSopenharmony_ci			append(name, "%s", show_ident(sym->ident));
381f08c3bdfSopenharmony_ci		mod |= sym->ctype.modifiers;
382f08c3bdfSopenharmony_ci		combine_address_space(sym->pos, &as, sym->ctype.as);
383f08c3bdfSopenharmony_ci		break;
384f08c3bdfSopenharmony_ci
385f08c3bdfSopenharmony_ci	case SYM_BITFIELD:
386f08c3bdfSopenharmony_ci		mod |= sym->ctype.modifiers;
387f08c3bdfSopenharmony_ci		combine_address_space(sym->pos, &as, sym->ctype.as);
388f08c3bdfSopenharmony_ci		append(name, ":%d", sym->bit_size);
389f08c3bdfSopenharmony_ci		break;
390f08c3bdfSopenharmony_ci
391f08c3bdfSopenharmony_ci	case SYM_LABEL:
392f08c3bdfSopenharmony_ci		append(name, "label(%s:%p)", show_ident(sym->ident), sym);
393f08c3bdfSopenharmony_ci		return;
394f08c3bdfSopenharmony_ci
395f08c3bdfSopenharmony_ci	case SYM_ARRAY:
396f08c3bdfSopenharmony_ci		mod |= sym->ctype.modifiers;
397f08c3bdfSopenharmony_ci		combine_address_space(sym->pos, &as, sym->ctype.as);
398f08c3bdfSopenharmony_ci		if (was_ptr) {
399f08c3bdfSopenharmony_ci			prepend(name, "( ");
400f08c3bdfSopenharmony_ci			append(name, " )");
401f08c3bdfSopenharmony_ci			was_ptr = 0;
402f08c3bdfSopenharmony_ci		}
403f08c3bdfSopenharmony_ci		append(name, "[%lld]", get_expression_value(sym->array_size));
404f08c3bdfSopenharmony_ci		break;
405f08c3bdfSopenharmony_ci
406f08c3bdfSopenharmony_ci	case SYM_RESTRICT:
407f08c3bdfSopenharmony_ci		if (!sym->ident) {
408f08c3bdfSopenharmony_ci			restr = 1;
409f08c3bdfSopenharmony_ci			break;
410f08c3bdfSopenharmony_ci		}
411f08c3bdfSopenharmony_ci		if (name->start != name->end)
412f08c3bdfSopenharmony_ci			*--name->start = ' ';
413f08c3bdfSopenharmony_ci		prepend(name, "restricted %s", show_ident(sym->ident));
414f08c3bdfSopenharmony_ci		goto out;
415f08c3bdfSopenharmony_ci
416f08c3bdfSopenharmony_ci	case SYM_FOULED:
417f08c3bdfSopenharmony_ci		fouled = 1;
418f08c3bdfSopenharmony_ci		break;
419f08c3bdfSopenharmony_ci
420f08c3bdfSopenharmony_ci	default:
421f08c3bdfSopenharmony_ci		if (name->start != name->end)
422f08c3bdfSopenharmony_ci			*--name->start = ' ';
423f08c3bdfSopenharmony_ci		prepend(name, "unknown type %d", sym->type);
424f08c3bdfSopenharmony_ci		goto out;
425f08c3bdfSopenharmony_ci	}
426f08c3bdfSopenharmony_ci
427f08c3bdfSopenharmony_ci	sym = sym->ctype.base_type;
428f08c3bdfSopenharmony_ci	goto deeper;
429f08c3bdfSopenharmony_ci
430f08c3bdfSopenharmony_ciout:
431f08c3bdfSopenharmony_ci	if (restr)
432f08c3bdfSopenharmony_ci		prepend(name, "restricted ");
433f08c3bdfSopenharmony_ci	if (fouled)
434f08c3bdfSopenharmony_ci		prepend(name, "fouled ");
435f08c3bdfSopenharmony_ci
436f08c3bdfSopenharmony_ci	// strip trailing space
437f08c3bdfSopenharmony_ci	if (name->end > name->start && name->end[-1] == ' ')
438f08c3bdfSopenharmony_ci		name->end--;
439f08c3bdfSopenharmony_ci}
440f08c3bdfSopenharmony_ci
441f08c3bdfSopenharmony_civoid show_type(struct symbol *sym)
442f08c3bdfSopenharmony_ci{
443f08c3bdfSopenharmony_ci	char array[200];
444f08c3bdfSopenharmony_ci	struct type_name name;
445f08c3bdfSopenharmony_ci
446f08c3bdfSopenharmony_ci	name.start = name.end = array+100;
447f08c3bdfSopenharmony_ci	do_show_type(sym, &name);
448f08c3bdfSopenharmony_ci	*name.end = 0;
449f08c3bdfSopenharmony_ci	printf("%s", name.start);
450f08c3bdfSopenharmony_ci}
451f08c3bdfSopenharmony_ci
452f08c3bdfSopenharmony_ciconst char *show_typename(struct symbol *sym)
453f08c3bdfSopenharmony_ci{
454f08c3bdfSopenharmony_ci	static char array[200];
455f08c3bdfSopenharmony_ci	struct type_name name;
456f08c3bdfSopenharmony_ci
457f08c3bdfSopenharmony_ci	name.start = name.end = array+100;
458f08c3bdfSopenharmony_ci	do_show_type(sym, &name);
459f08c3bdfSopenharmony_ci	*name.end = 0;
460f08c3bdfSopenharmony_ci	return name.start;
461f08c3bdfSopenharmony_ci}
462f08c3bdfSopenharmony_ci
463f08c3bdfSopenharmony_civoid show_symbol(struct symbol *sym)
464f08c3bdfSopenharmony_ci{
465f08c3bdfSopenharmony_ci	struct symbol *type;
466f08c3bdfSopenharmony_ci
467f08c3bdfSopenharmony_ci	if (!sym)
468f08c3bdfSopenharmony_ci		return;
469f08c3bdfSopenharmony_ci
470f08c3bdfSopenharmony_ci	if (sym->ctype.alignment)
471f08c3bdfSopenharmony_ci		printf(".align %ld\n", sym->ctype.alignment);
472f08c3bdfSopenharmony_ci
473f08c3bdfSopenharmony_ci	show_type(sym);
474f08c3bdfSopenharmony_ci	type = sym->ctype.base_type;
475f08c3bdfSopenharmony_ci	if (!type) {
476f08c3bdfSopenharmony_ci		printf("\n");
477f08c3bdfSopenharmony_ci		return;
478f08c3bdfSopenharmony_ci	}
479f08c3bdfSopenharmony_ci
480f08c3bdfSopenharmony_ci	/*
481f08c3bdfSopenharmony_ci	 * Show actual implementation information
482f08c3bdfSopenharmony_ci	 */
483f08c3bdfSopenharmony_ci	switch (type->type) {
484f08c3bdfSopenharmony_ci		struct symbol *member;
485f08c3bdfSopenharmony_ci
486f08c3bdfSopenharmony_ci	case SYM_STRUCT:
487f08c3bdfSopenharmony_ci	case SYM_UNION:
488f08c3bdfSopenharmony_ci		printf(" {\n");
489f08c3bdfSopenharmony_ci		FOR_EACH_PTR(type->symbol_list, member) {
490f08c3bdfSopenharmony_ci			show_struct_member(member);
491f08c3bdfSopenharmony_ci		} END_FOR_EACH_PTR(member);
492f08c3bdfSopenharmony_ci		printf("}\n");
493f08c3bdfSopenharmony_ci		break;
494f08c3bdfSopenharmony_ci
495f08c3bdfSopenharmony_ci	case SYM_FN: {
496f08c3bdfSopenharmony_ci		struct statement *stmt = type->stmt;
497f08c3bdfSopenharmony_ci		printf("\n");
498f08c3bdfSopenharmony_ci		if (stmt) {
499f08c3bdfSopenharmony_ci			int val;
500f08c3bdfSopenharmony_ci			val = show_statement(stmt);
501f08c3bdfSopenharmony_ci			if (val)
502f08c3bdfSopenharmony_ci				printf("\tmov.%d\t\tretval,%d\n", stmt->ret->bit_size, val);
503f08c3bdfSopenharmony_ci			printf("\tret\n");
504f08c3bdfSopenharmony_ci		}
505f08c3bdfSopenharmony_ci		break;
506f08c3bdfSopenharmony_ci	}
507f08c3bdfSopenharmony_ci
508f08c3bdfSopenharmony_ci	default:
509f08c3bdfSopenharmony_ci		printf("\n");
510f08c3bdfSopenharmony_ci		break;
511f08c3bdfSopenharmony_ci	}
512f08c3bdfSopenharmony_ci
513f08c3bdfSopenharmony_ci	if (sym->initializer) {
514f08c3bdfSopenharmony_ci		printf(" = \n");
515f08c3bdfSopenharmony_ci		show_expression(sym->initializer);
516f08c3bdfSopenharmony_ci	}
517f08c3bdfSopenharmony_ci}
518f08c3bdfSopenharmony_ci
519f08c3bdfSopenharmony_cistatic int show_symbol_init(struct symbol *sym);
520f08c3bdfSopenharmony_ci
521f08c3bdfSopenharmony_cistatic int new_pseudo(void)
522f08c3bdfSopenharmony_ci{
523f08c3bdfSopenharmony_ci	static int nr = 0;
524f08c3bdfSopenharmony_ci	return ++nr;
525f08c3bdfSopenharmony_ci}
526f08c3bdfSopenharmony_ci
527f08c3bdfSopenharmony_cistatic int new_label(void)
528f08c3bdfSopenharmony_ci{
529f08c3bdfSopenharmony_ci	static int label = 0;
530f08c3bdfSopenharmony_ci	return ++label;
531f08c3bdfSopenharmony_ci}
532f08c3bdfSopenharmony_ci
533f08c3bdfSopenharmony_cistatic void show_switch_statement(struct statement *stmt)
534f08c3bdfSopenharmony_ci{
535f08c3bdfSopenharmony_ci	int val = show_expression(stmt->switch_expression);
536f08c3bdfSopenharmony_ci	struct symbol *sym;
537f08c3bdfSopenharmony_ci	printf("\tswitch v%d\n", val);
538f08c3bdfSopenharmony_ci
539f08c3bdfSopenharmony_ci	/*
540f08c3bdfSopenharmony_ci	 * Debugging only: Check that the case list is correct
541f08c3bdfSopenharmony_ci	 * by printing it out.
542f08c3bdfSopenharmony_ci	 *
543f08c3bdfSopenharmony_ci	 * This is where a _real_ back-end would go through the
544f08c3bdfSopenharmony_ci	 * cases to decide whether to use a lookup table or a
545f08c3bdfSopenharmony_ci	 * series of comparisons etc
546f08c3bdfSopenharmony_ci	 */
547f08c3bdfSopenharmony_ci	printf("# case table:\n");
548f08c3bdfSopenharmony_ci	FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
549f08c3bdfSopenharmony_ci		struct statement *case_stmt = sym->stmt;
550f08c3bdfSopenharmony_ci		struct expression *expr = case_stmt->case_expression;
551f08c3bdfSopenharmony_ci		struct expression *to = case_stmt->case_to;
552f08c3bdfSopenharmony_ci
553f08c3bdfSopenharmony_ci		if (!expr) {
554f08c3bdfSopenharmony_ci			printf("    default");
555f08c3bdfSopenharmony_ci		} else {
556f08c3bdfSopenharmony_ci			if (expr->type == EXPR_VALUE) {
557f08c3bdfSopenharmony_ci				printf("    case %lld", expr->value);
558f08c3bdfSopenharmony_ci				if (to) {
559f08c3bdfSopenharmony_ci					if (to->type == EXPR_VALUE) {
560f08c3bdfSopenharmony_ci						printf(" .. %lld", to->value);
561f08c3bdfSopenharmony_ci					} else {
562f08c3bdfSopenharmony_ci						printf(" .. what?");
563f08c3bdfSopenharmony_ci					}
564f08c3bdfSopenharmony_ci				}
565f08c3bdfSopenharmony_ci			} else
566f08c3bdfSopenharmony_ci				printf("    what?");
567f08c3bdfSopenharmony_ci		}
568f08c3bdfSopenharmony_ci		printf(": .L%p\n", sym);
569f08c3bdfSopenharmony_ci	} END_FOR_EACH_PTR(sym);
570f08c3bdfSopenharmony_ci	printf("# end case table\n");
571f08c3bdfSopenharmony_ci
572f08c3bdfSopenharmony_ci	show_statement(stmt->switch_statement);
573f08c3bdfSopenharmony_ci
574f08c3bdfSopenharmony_ci	if (stmt->switch_break->used)
575f08c3bdfSopenharmony_ci		printf(".L%p:\n", stmt->switch_break);
576f08c3bdfSopenharmony_ci}
577f08c3bdfSopenharmony_ci
578f08c3bdfSopenharmony_cistatic void show_symbol_decl(struct symbol_list *syms)
579f08c3bdfSopenharmony_ci{
580f08c3bdfSopenharmony_ci	struct symbol *sym;
581f08c3bdfSopenharmony_ci	FOR_EACH_PTR(syms, sym) {
582f08c3bdfSopenharmony_ci		show_symbol_init(sym);
583f08c3bdfSopenharmony_ci	} END_FOR_EACH_PTR(sym);
584f08c3bdfSopenharmony_ci}
585f08c3bdfSopenharmony_ci
586f08c3bdfSopenharmony_cistatic int show_return_stmt(struct statement *stmt);
587f08c3bdfSopenharmony_ci
588f08c3bdfSopenharmony_ci/*
589f08c3bdfSopenharmony_ci * Print out a statement
590f08c3bdfSopenharmony_ci */
591f08c3bdfSopenharmony_ciint show_statement(struct statement *stmt)
592f08c3bdfSopenharmony_ci{
593f08c3bdfSopenharmony_ci	if (!stmt)
594f08c3bdfSopenharmony_ci		return 0;
595f08c3bdfSopenharmony_ci	switch (stmt->type) {
596f08c3bdfSopenharmony_ci	case STMT_DECLARATION:
597f08c3bdfSopenharmony_ci		show_symbol_decl(stmt->declaration);
598f08c3bdfSopenharmony_ci		return 0;
599f08c3bdfSopenharmony_ci	case STMT_RETURN:
600f08c3bdfSopenharmony_ci		return show_return_stmt(stmt);
601f08c3bdfSopenharmony_ci	case STMT_COMPOUND: {
602f08c3bdfSopenharmony_ci		struct statement *s;
603f08c3bdfSopenharmony_ci		int last = 0;
604f08c3bdfSopenharmony_ci
605f08c3bdfSopenharmony_ci		if (stmt->inline_fn) {
606f08c3bdfSopenharmony_ci			show_statement(stmt->args);
607f08c3bdfSopenharmony_ci			printf("\tbegin_inline \t%s\n", show_ident(stmt->inline_fn->ident));
608f08c3bdfSopenharmony_ci		}
609f08c3bdfSopenharmony_ci		FOR_EACH_PTR(stmt->stmts, s) {
610f08c3bdfSopenharmony_ci			last = show_statement(s);
611f08c3bdfSopenharmony_ci		} END_FOR_EACH_PTR(s);
612f08c3bdfSopenharmony_ci		if (stmt->ret) {
613f08c3bdfSopenharmony_ci			int addr, bits;
614f08c3bdfSopenharmony_ci			printf(".L%p:\n", stmt->ret);
615f08c3bdfSopenharmony_ci			addr = show_symbol_expr(stmt->ret);
616f08c3bdfSopenharmony_ci			bits = stmt->ret->bit_size;
617f08c3bdfSopenharmony_ci			last = new_pseudo();
618f08c3bdfSopenharmony_ci			printf("\tld.%d\t\tv%d,[v%d]\n", bits, last, addr);
619f08c3bdfSopenharmony_ci		}
620f08c3bdfSopenharmony_ci		if (stmt->inline_fn)
621f08c3bdfSopenharmony_ci			printf("\tend_inlined\t%s\n", show_ident(stmt->inline_fn->ident));
622f08c3bdfSopenharmony_ci		return last;
623f08c3bdfSopenharmony_ci	}
624f08c3bdfSopenharmony_ci
625f08c3bdfSopenharmony_ci	case STMT_EXPRESSION:
626f08c3bdfSopenharmony_ci		return show_expression(stmt->expression);
627f08c3bdfSopenharmony_ci	case STMT_IF: {
628f08c3bdfSopenharmony_ci		int val, target;
629f08c3bdfSopenharmony_ci		struct expression *cond = stmt->if_conditional;
630f08c3bdfSopenharmony_ci
631f08c3bdfSopenharmony_ci/* This is only valid if nobody can jump into the "dead" statement */
632f08c3bdfSopenharmony_ci#if 0
633f08c3bdfSopenharmony_ci		if (cond->type == EXPR_VALUE) {
634f08c3bdfSopenharmony_ci			struct statement *s = stmt->if_true;
635f08c3bdfSopenharmony_ci			if (!cond->value)
636f08c3bdfSopenharmony_ci				s = stmt->if_false;
637f08c3bdfSopenharmony_ci			show_statement(s);
638f08c3bdfSopenharmony_ci			break;
639f08c3bdfSopenharmony_ci		}
640f08c3bdfSopenharmony_ci#endif
641f08c3bdfSopenharmony_ci		val = show_expression(cond);
642f08c3bdfSopenharmony_ci		target = new_label();
643f08c3bdfSopenharmony_ci		printf("\tje\t\tv%d,.L%d\n", val, target);
644f08c3bdfSopenharmony_ci		show_statement(stmt->if_true);
645f08c3bdfSopenharmony_ci		if (stmt->if_false) {
646f08c3bdfSopenharmony_ci			int last = new_label();
647f08c3bdfSopenharmony_ci			printf("\tjmp\t\t.L%d\n", last);
648f08c3bdfSopenharmony_ci			printf(".L%d:\n", target);
649f08c3bdfSopenharmony_ci			target = last;
650f08c3bdfSopenharmony_ci			show_statement(stmt->if_false);
651f08c3bdfSopenharmony_ci		}
652f08c3bdfSopenharmony_ci		printf(".L%d:\n", target);
653f08c3bdfSopenharmony_ci		break;
654f08c3bdfSopenharmony_ci	}
655f08c3bdfSopenharmony_ci	case STMT_SWITCH:
656f08c3bdfSopenharmony_ci		show_switch_statement(stmt);
657f08c3bdfSopenharmony_ci		break;
658f08c3bdfSopenharmony_ci
659f08c3bdfSopenharmony_ci	case STMT_CASE:
660f08c3bdfSopenharmony_ci		printf(".L%p:\n", stmt->case_label);
661f08c3bdfSopenharmony_ci		show_statement(stmt->case_statement);
662f08c3bdfSopenharmony_ci		break;
663f08c3bdfSopenharmony_ci
664f08c3bdfSopenharmony_ci	case STMT_ITERATOR: {
665f08c3bdfSopenharmony_ci		struct statement  *pre_statement = stmt->iterator_pre_statement;
666f08c3bdfSopenharmony_ci		struct expression *pre_condition = stmt->iterator_pre_condition;
667f08c3bdfSopenharmony_ci		struct statement  *statement = stmt->iterator_statement;
668f08c3bdfSopenharmony_ci		struct statement  *post_statement = stmt->iterator_post_statement;
669f08c3bdfSopenharmony_ci		struct expression *post_condition = stmt->iterator_post_condition;
670f08c3bdfSopenharmony_ci		int val, loop_top = 0, loop_bottom = 0;
671f08c3bdfSopenharmony_ci
672f08c3bdfSopenharmony_ci		show_symbol_decl(stmt->iterator_syms);
673f08c3bdfSopenharmony_ci		show_statement(pre_statement);
674f08c3bdfSopenharmony_ci		if (pre_condition) {
675f08c3bdfSopenharmony_ci			if (pre_condition->type == EXPR_VALUE) {
676f08c3bdfSopenharmony_ci				if (!pre_condition->value) {
677f08c3bdfSopenharmony_ci					loop_bottom = new_label();
678f08c3bdfSopenharmony_ci					printf("\tjmp\t\t.L%d\n", loop_bottom);
679f08c3bdfSopenharmony_ci				}
680f08c3bdfSopenharmony_ci			} else {
681f08c3bdfSopenharmony_ci				loop_bottom = new_label();
682f08c3bdfSopenharmony_ci				val = show_expression(pre_condition);
683f08c3bdfSopenharmony_ci				printf("\tje\t\tv%d, .L%d\n", val, loop_bottom);
684f08c3bdfSopenharmony_ci			}
685f08c3bdfSopenharmony_ci		}
686f08c3bdfSopenharmony_ci		if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) {
687f08c3bdfSopenharmony_ci			loop_top = new_label();
688f08c3bdfSopenharmony_ci			printf(".L%d:\n", loop_top);
689f08c3bdfSopenharmony_ci		}
690f08c3bdfSopenharmony_ci		show_statement(statement);
691f08c3bdfSopenharmony_ci		if (stmt->iterator_continue->used)
692f08c3bdfSopenharmony_ci			printf(".L%p:\n", stmt->iterator_continue);
693f08c3bdfSopenharmony_ci		show_statement(post_statement);
694f08c3bdfSopenharmony_ci		if (!post_condition) {
695f08c3bdfSopenharmony_ci			printf("\tjmp\t\t.L%d\n", loop_top);
696f08c3bdfSopenharmony_ci		} else if (post_condition->type == EXPR_VALUE) {
697f08c3bdfSopenharmony_ci			if (post_condition->value)
698f08c3bdfSopenharmony_ci				printf("\tjmp\t\t.L%d\n", loop_top);
699f08c3bdfSopenharmony_ci		} else {
700f08c3bdfSopenharmony_ci			val = show_expression(post_condition);
701f08c3bdfSopenharmony_ci			printf("\tjne\t\tv%d, .L%d\n", val, loop_top);
702f08c3bdfSopenharmony_ci		}
703f08c3bdfSopenharmony_ci		if (stmt->iterator_break->used)
704f08c3bdfSopenharmony_ci			printf(".L%p:\n", stmt->iterator_break);
705f08c3bdfSopenharmony_ci		if (loop_bottom)
706f08c3bdfSopenharmony_ci			printf(".L%d:\n", loop_bottom);
707f08c3bdfSopenharmony_ci		break;
708f08c3bdfSopenharmony_ci	}
709f08c3bdfSopenharmony_ci	case STMT_NONE:
710f08c3bdfSopenharmony_ci		break;
711f08c3bdfSopenharmony_ci
712f08c3bdfSopenharmony_ci	case STMT_LABEL:
713f08c3bdfSopenharmony_ci		printf(".L%p:\n", stmt->label_identifier);
714f08c3bdfSopenharmony_ci		show_statement(stmt->label_statement);
715f08c3bdfSopenharmony_ci		break;
716f08c3bdfSopenharmony_ci
717f08c3bdfSopenharmony_ci	case STMT_GOTO:
718f08c3bdfSopenharmony_ci		if (stmt->goto_expression) {
719f08c3bdfSopenharmony_ci			int val = show_expression(stmt->goto_expression);
720f08c3bdfSopenharmony_ci			printf("\tgoto\t\t*v%d\n", val);
721f08c3bdfSopenharmony_ci		} else {
722f08c3bdfSopenharmony_ci			printf("\tgoto\t\t.L%p\n", stmt->goto_label);
723f08c3bdfSopenharmony_ci		}
724f08c3bdfSopenharmony_ci		break;
725f08c3bdfSopenharmony_ci	case STMT_ASM:
726f08c3bdfSopenharmony_ci		printf("\tasm( .... )\n");
727f08c3bdfSopenharmony_ci		break;
728f08c3bdfSopenharmony_ci	case STMT_CONTEXT: {
729f08c3bdfSopenharmony_ci		int val = show_expression(stmt->expression);
730f08c3bdfSopenharmony_ci		printf("\tcontext( %d )\n", val);
731f08c3bdfSopenharmony_ci		break;
732f08c3bdfSopenharmony_ci	}
733f08c3bdfSopenharmony_ci	case STMT_RANGE: {
734f08c3bdfSopenharmony_ci		int val = show_expression(stmt->range_expression);
735f08c3bdfSopenharmony_ci		int low = show_expression(stmt->range_low);
736f08c3bdfSopenharmony_ci		int high = show_expression(stmt->range_high);
737f08c3bdfSopenharmony_ci		printf("\trange( %d %d-%d)\n", val, low, high);
738f08c3bdfSopenharmony_ci		break;
739f08c3bdfSopenharmony_ci	}
740f08c3bdfSopenharmony_ci	}
741f08c3bdfSopenharmony_ci	return 0;
742f08c3bdfSopenharmony_ci}
743f08c3bdfSopenharmony_ci
744f08c3bdfSopenharmony_cistatic int show_call_expression(struct expression *expr)
745f08c3bdfSopenharmony_ci{
746f08c3bdfSopenharmony_ci	struct symbol *direct;
747f08c3bdfSopenharmony_ci	struct expression *arg, *fn;
748f08c3bdfSopenharmony_ci	int fncall, retval;
749f08c3bdfSopenharmony_ci	int framesize;
750f08c3bdfSopenharmony_ci
751f08c3bdfSopenharmony_ci	if (!expr->ctype) {
752f08c3bdfSopenharmony_ci		warning(expr->pos, "\tcall with no type!");
753f08c3bdfSopenharmony_ci		return 0;
754f08c3bdfSopenharmony_ci	}
755f08c3bdfSopenharmony_ci
756f08c3bdfSopenharmony_ci	framesize = 0;
757f08c3bdfSopenharmony_ci	FOR_EACH_PTR_REVERSE(expr->args, arg) {
758f08c3bdfSopenharmony_ci		int new = show_expression(arg);
759f08c3bdfSopenharmony_ci		int size = arg->ctype->bit_size;
760f08c3bdfSopenharmony_ci		printf("\tpush.%d\t\tv%d\n", size, new);
761f08c3bdfSopenharmony_ci		framesize += bits_to_bytes(size);
762f08c3bdfSopenharmony_ci	} END_FOR_EACH_PTR_REVERSE(arg);
763f08c3bdfSopenharmony_ci
764f08c3bdfSopenharmony_ci	fn = expr->fn;
765f08c3bdfSopenharmony_ci
766f08c3bdfSopenharmony_ci	/* Remove dereference, if any */
767f08c3bdfSopenharmony_ci	direct = NULL;
768f08c3bdfSopenharmony_ci	if (fn->type == EXPR_PREOP) {
769f08c3bdfSopenharmony_ci		if (fn->unop->type == EXPR_SYMBOL) {
770f08c3bdfSopenharmony_ci			struct symbol *sym = fn->unop->symbol;
771f08c3bdfSopenharmony_ci			if (sym->ctype.base_type->type == SYM_FN)
772f08c3bdfSopenharmony_ci				direct = sym;
773f08c3bdfSopenharmony_ci		}
774f08c3bdfSopenharmony_ci	}
775f08c3bdfSopenharmony_ci	if (direct) {
776f08c3bdfSopenharmony_ci		printf("\tcall\t\t%s\n", show_ident(direct->ident));
777f08c3bdfSopenharmony_ci	} else {
778f08c3bdfSopenharmony_ci		fncall = show_expression(fn);
779f08c3bdfSopenharmony_ci		printf("\tcall\t\t*v%d\n", fncall);
780f08c3bdfSopenharmony_ci	}
781f08c3bdfSopenharmony_ci	if (framesize)
782f08c3bdfSopenharmony_ci		printf("\tadd.%d\t\tvSP,vSP,$%d\n", bits_in_pointer, framesize);
783f08c3bdfSopenharmony_ci
784f08c3bdfSopenharmony_ci	retval = new_pseudo();
785f08c3bdfSopenharmony_ci	printf("\tmov.%d\t\tv%d,retval\n", expr->ctype->bit_size, retval);
786f08c3bdfSopenharmony_ci	return retval;
787f08c3bdfSopenharmony_ci}
788f08c3bdfSopenharmony_ci
789f08c3bdfSopenharmony_cistatic int show_comma(struct expression *expr)
790f08c3bdfSopenharmony_ci{
791f08c3bdfSopenharmony_ci	show_expression(expr->left);
792f08c3bdfSopenharmony_ci	return show_expression(expr->right);
793f08c3bdfSopenharmony_ci}
794f08c3bdfSopenharmony_ci
795f08c3bdfSopenharmony_cistatic int show_binop(struct expression *expr)
796f08c3bdfSopenharmony_ci{
797f08c3bdfSopenharmony_ci	int left = show_expression(expr->left);
798f08c3bdfSopenharmony_ci	int right = show_expression(expr->right);
799f08c3bdfSopenharmony_ci	int new = new_pseudo();
800f08c3bdfSopenharmony_ci	const char *opname;
801f08c3bdfSopenharmony_ci	static const char *name[] = {
802f08c3bdfSopenharmony_ci		['+'] = "add", ['-'] = "sub",
803f08c3bdfSopenharmony_ci		['*'] = "mul", ['/'] = "div",
804f08c3bdfSopenharmony_ci		['%'] = "mod", ['&'] = "and",
805f08c3bdfSopenharmony_ci		['|'] = "lor", ['^'] = "xor"
806f08c3bdfSopenharmony_ci	};
807f08c3bdfSopenharmony_ci	unsigned int op = expr->op;
808f08c3bdfSopenharmony_ci
809f08c3bdfSopenharmony_ci	opname = show_special(op);
810f08c3bdfSopenharmony_ci	if (op < ARRAY_SIZE(name))
811f08c3bdfSopenharmony_ci		opname = name[op];
812f08c3bdfSopenharmony_ci	printf("\t%s.%d\t\tv%d,v%d,v%d\n", opname,
813f08c3bdfSopenharmony_ci		expr->ctype->bit_size,
814f08c3bdfSopenharmony_ci		new, left, right);
815f08c3bdfSopenharmony_ci	return new;
816f08c3bdfSopenharmony_ci}
817f08c3bdfSopenharmony_ci
818f08c3bdfSopenharmony_cistatic int show_slice(struct expression *expr)
819f08c3bdfSopenharmony_ci{
820f08c3bdfSopenharmony_ci	int target = show_expression(expr->base);
821f08c3bdfSopenharmony_ci	int new = new_pseudo();
822f08c3bdfSopenharmony_ci	printf("\tslice.%d\t\tv%d,v%d,%d\n", expr->ctype->bit_size, target, new, expr->r_bitpos);
823f08c3bdfSopenharmony_ci	return new;
824f08c3bdfSopenharmony_ci}
825f08c3bdfSopenharmony_ci
826f08c3bdfSopenharmony_cistatic int show_regular_preop(struct expression *expr)
827f08c3bdfSopenharmony_ci{
828f08c3bdfSopenharmony_ci	int target = show_expression(expr->unop);
829f08c3bdfSopenharmony_ci	int new = new_pseudo();
830f08c3bdfSopenharmony_ci	static const char *name[] = {
831f08c3bdfSopenharmony_ci		['!'] = "nonzero", ['-'] = "neg",
832f08c3bdfSopenharmony_ci		['~'] = "not",
833f08c3bdfSopenharmony_ci	};
834f08c3bdfSopenharmony_ci	unsigned int op = expr->op;
835f08c3bdfSopenharmony_ci	const char *opname;
836f08c3bdfSopenharmony_ci
837f08c3bdfSopenharmony_ci	opname = show_special(op);
838f08c3bdfSopenharmony_ci	if (op < ARRAY_SIZE(name))
839f08c3bdfSopenharmony_ci		opname = name[op];
840f08c3bdfSopenharmony_ci	printf("\t%s.%d\t\tv%d,v%d\n", opname, expr->ctype->bit_size, new, target);
841f08c3bdfSopenharmony_ci	return new;
842f08c3bdfSopenharmony_ci}
843f08c3bdfSopenharmony_ci
844f08c3bdfSopenharmony_ci/*
845f08c3bdfSopenharmony_ci * FIXME! Not all accesses are memory loads. We should
846f08c3bdfSopenharmony_ci * check what kind of symbol is behind the dereference.
847f08c3bdfSopenharmony_ci */
848f08c3bdfSopenharmony_cistatic int show_address_gen(struct expression *expr)
849f08c3bdfSopenharmony_ci{
850f08c3bdfSopenharmony_ci	return show_expression(expr->unop);
851f08c3bdfSopenharmony_ci}
852f08c3bdfSopenharmony_ci
853f08c3bdfSopenharmony_cistatic int show_load_gen(int bits, struct expression *expr, int addr)
854f08c3bdfSopenharmony_ci{
855f08c3bdfSopenharmony_ci	int new = new_pseudo();
856f08c3bdfSopenharmony_ci
857f08c3bdfSopenharmony_ci	printf("\tld.%d\t\tv%d,[v%d]\n", bits, new, addr);
858f08c3bdfSopenharmony_ci	return new;
859f08c3bdfSopenharmony_ci}
860f08c3bdfSopenharmony_ci
861f08c3bdfSopenharmony_cistatic void show_store_gen(int bits, int value, struct expression *expr, int addr)
862f08c3bdfSopenharmony_ci{
863f08c3bdfSopenharmony_ci	/* FIXME!!! Bitfield store! */
864f08c3bdfSopenharmony_ci	printf("\tst.%d\t\tv%d,[v%d]\n", bits, value, addr);
865f08c3bdfSopenharmony_ci}
866f08c3bdfSopenharmony_ci
867f08c3bdfSopenharmony_cistatic int show_assignment(struct expression *expr)
868f08c3bdfSopenharmony_ci{
869f08c3bdfSopenharmony_ci	struct expression *target = expr->left;
870f08c3bdfSopenharmony_ci	int val, addr, bits;
871f08c3bdfSopenharmony_ci
872f08c3bdfSopenharmony_ci	if (!expr->ctype)
873f08c3bdfSopenharmony_ci		return 0;
874f08c3bdfSopenharmony_ci
875f08c3bdfSopenharmony_ci	bits = expr->ctype->bit_size;
876f08c3bdfSopenharmony_ci	val = show_expression(expr->right);
877f08c3bdfSopenharmony_ci	addr = show_address_gen(target);
878f08c3bdfSopenharmony_ci	show_store_gen(bits, val, target, addr);
879f08c3bdfSopenharmony_ci	return val;
880f08c3bdfSopenharmony_ci}
881f08c3bdfSopenharmony_ci
882f08c3bdfSopenharmony_cistatic int show_return_stmt(struct statement *stmt)
883f08c3bdfSopenharmony_ci{
884f08c3bdfSopenharmony_ci	struct expression *expr = stmt->ret_value;
885f08c3bdfSopenharmony_ci	struct symbol *target = stmt->ret_target;
886f08c3bdfSopenharmony_ci
887f08c3bdfSopenharmony_ci	if (expr && expr->ctype) {
888f08c3bdfSopenharmony_ci		int val = show_expression(expr);
889f08c3bdfSopenharmony_ci		int bits = expr->ctype->bit_size;
890f08c3bdfSopenharmony_ci		int addr = show_symbol_expr(target);
891f08c3bdfSopenharmony_ci		show_store_gen(bits, val, NULL, addr);
892f08c3bdfSopenharmony_ci	}
893f08c3bdfSopenharmony_ci	printf("\tret\t\t(%p)\n", target);
894f08c3bdfSopenharmony_ci	return 0;
895f08c3bdfSopenharmony_ci}
896f08c3bdfSopenharmony_ci
897f08c3bdfSopenharmony_cistatic int show_initialization(struct symbol *sym, struct expression *expr)
898f08c3bdfSopenharmony_ci{
899f08c3bdfSopenharmony_ci	int val, addr, bits;
900f08c3bdfSopenharmony_ci
901f08c3bdfSopenharmony_ci	if (!expr->ctype)
902f08c3bdfSopenharmony_ci		return 0;
903f08c3bdfSopenharmony_ci
904f08c3bdfSopenharmony_ci	bits = expr->ctype->bit_size;
905f08c3bdfSopenharmony_ci	val = show_expression(expr);
906f08c3bdfSopenharmony_ci	addr = show_symbol_expr(sym);
907f08c3bdfSopenharmony_ci	// FIXME! The "target" expression is for bitfield store information.
908f08c3bdfSopenharmony_ci	// Leave it NULL, which works fine.
909f08c3bdfSopenharmony_ci	show_store_gen(bits, val, NULL, addr);
910f08c3bdfSopenharmony_ci	return 0;
911f08c3bdfSopenharmony_ci}
912f08c3bdfSopenharmony_ci
913f08c3bdfSopenharmony_cistatic int show_access(struct expression *expr)
914f08c3bdfSopenharmony_ci{
915f08c3bdfSopenharmony_ci	int addr = show_address_gen(expr);
916f08c3bdfSopenharmony_ci	return show_load_gen(expr->ctype->bit_size, expr, addr);
917f08c3bdfSopenharmony_ci}
918f08c3bdfSopenharmony_ci
919f08c3bdfSopenharmony_cistatic int show_inc_dec(struct expression *expr, int postop)
920f08c3bdfSopenharmony_ci{
921f08c3bdfSopenharmony_ci	int addr = show_address_gen(expr->unop);
922f08c3bdfSopenharmony_ci	int retval, new;
923f08c3bdfSopenharmony_ci	const char *opname = expr->op == SPECIAL_INCREMENT ? "add" : "sub";
924f08c3bdfSopenharmony_ci	int bits = expr->ctype->bit_size;
925f08c3bdfSopenharmony_ci
926f08c3bdfSopenharmony_ci	retval = show_load_gen(bits, expr->unop, addr);
927f08c3bdfSopenharmony_ci	new = retval;
928f08c3bdfSopenharmony_ci	if (postop)
929f08c3bdfSopenharmony_ci		new = new_pseudo();
930f08c3bdfSopenharmony_ci	printf("\t%s.%d\t\tv%d,v%d,$1\n", opname, bits, new, retval);
931f08c3bdfSopenharmony_ci	show_store_gen(bits, new, expr->unop, addr);
932f08c3bdfSopenharmony_ci	return retval;
933f08c3bdfSopenharmony_ci}
934f08c3bdfSopenharmony_ci
935f08c3bdfSopenharmony_cistatic int show_preop(struct expression *expr)
936f08c3bdfSopenharmony_ci{
937f08c3bdfSopenharmony_ci	/*
938f08c3bdfSopenharmony_ci	 * '*' is an lvalue access, and is fundamentally different
939f08c3bdfSopenharmony_ci	 * from an arithmetic operation. Maybe it should have an
940f08c3bdfSopenharmony_ci	 * expression type of its own..
941f08c3bdfSopenharmony_ci	 */
942f08c3bdfSopenharmony_ci	if (expr->op == '*')
943f08c3bdfSopenharmony_ci		return show_access(expr);
944f08c3bdfSopenharmony_ci	if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
945f08c3bdfSopenharmony_ci		return show_inc_dec(expr, 0);
946f08c3bdfSopenharmony_ci	return show_regular_preop(expr);
947f08c3bdfSopenharmony_ci}
948f08c3bdfSopenharmony_ci
949f08c3bdfSopenharmony_cistatic int show_postop(struct expression *expr)
950f08c3bdfSopenharmony_ci{
951f08c3bdfSopenharmony_ci	return show_inc_dec(expr, 1);
952f08c3bdfSopenharmony_ci}
953f08c3bdfSopenharmony_ci
954f08c3bdfSopenharmony_cistatic int show_symbol_expr(struct symbol *sym)
955f08c3bdfSopenharmony_ci{
956f08c3bdfSopenharmony_ci	int new = new_pseudo();
957f08c3bdfSopenharmony_ci
958f08c3bdfSopenharmony_ci	if (sym->initializer && sym->initializer->type == EXPR_STRING)
959f08c3bdfSopenharmony_ci		return show_string_expr(sym->initializer);
960f08c3bdfSopenharmony_ci
961f08c3bdfSopenharmony_ci	if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_EXTERN | MOD_STATIC)) {
962f08c3bdfSopenharmony_ci		printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer, new, show_ident(sym->ident));
963f08c3bdfSopenharmony_ci		return new;
964f08c3bdfSopenharmony_ci	}
965f08c3bdfSopenharmony_ci	if (sym->ctype.modifiers & MOD_ADDRESSABLE) {
966f08c3bdfSopenharmony_ci		printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new, 0LL);
967f08c3bdfSopenharmony_ci		return new;
968f08c3bdfSopenharmony_ci	}
969f08c3bdfSopenharmony_ci	printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new, show_ident(sym->ident), sym);
970f08c3bdfSopenharmony_ci	return new;
971f08c3bdfSopenharmony_ci}
972f08c3bdfSopenharmony_ci
973f08c3bdfSopenharmony_cistatic int show_symbol_init(struct symbol *sym)
974f08c3bdfSopenharmony_ci{
975f08c3bdfSopenharmony_ci	struct expression *expr = sym->initializer;
976f08c3bdfSopenharmony_ci
977f08c3bdfSopenharmony_ci	if (expr) {
978f08c3bdfSopenharmony_ci		int val, addr, bits;
979f08c3bdfSopenharmony_ci
980f08c3bdfSopenharmony_ci		bits = expr->ctype->bit_size;
981f08c3bdfSopenharmony_ci		val = show_expression(expr);
982f08c3bdfSopenharmony_ci		addr = show_symbol_expr(sym);
983f08c3bdfSopenharmony_ci		show_store_gen(bits, val, NULL, addr);
984f08c3bdfSopenharmony_ci	}
985f08c3bdfSopenharmony_ci	return 0;
986f08c3bdfSopenharmony_ci}
987f08c3bdfSopenharmony_ci
988f08c3bdfSopenharmony_cistatic int show_cast_expr(struct expression *expr)
989f08c3bdfSopenharmony_ci{
990f08c3bdfSopenharmony_ci	struct symbol *old_type, *new_type;
991f08c3bdfSopenharmony_ci	int op = show_expression(expr->cast_expression);
992f08c3bdfSopenharmony_ci	int oldbits, newbits;
993f08c3bdfSopenharmony_ci	int new, is_signed;
994f08c3bdfSopenharmony_ci
995f08c3bdfSopenharmony_ci	old_type = expr->cast_expression->ctype;
996f08c3bdfSopenharmony_ci	new_type = expr->cast_type;
997f08c3bdfSopenharmony_ci
998f08c3bdfSopenharmony_ci	oldbits = old_type->bit_size;
999f08c3bdfSopenharmony_ci	newbits = new_type->bit_size;
1000f08c3bdfSopenharmony_ci	if (oldbits >= newbits)
1001f08c3bdfSopenharmony_ci		return op;
1002f08c3bdfSopenharmony_ci	new = new_pseudo();
1003f08c3bdfSopenharmony_ci	is_signed = is_signed_type(old_type);
1004f08c3bdfSopenharmony_ci	if (is_signed) {
1005f08c3bdfSopenharmony_ci		printf("\tsext%d.%d\tv%d,v%d\n", oldbits, newbits, new, op);
1006f08c3bdfSopenharmony_ci	} else {
1007f08c3bdfSopenharmony_ci		printf("\tandl.%d\t\tv%d,v%d,$%lu\n", newbits, new, op, (1UL << oldbits)-1);
1008f08c3bdfSopenharmony_ci	}
1009f08c3bdfSopenharmony_ci	return new;
1010f08c3bdfSopenharmony_ci}
1011f08c3bdfSopenharmony_ci
1012f08c3bdfSopenharmony_cistatic int show_value(struct expression *expr)
1013f08c3bdfSopenharmony_ci{
1014f08c3bdfSopenharmony_ci	int new = new_pseudo();
1015f08c3bdfSopenharmony_ci	unsigned long long value = expr->value;
1016f08c3bdfSopenharmony_ci
1017f08c3bdfSopenharmony_ci	printf("\tmovi.%d\t\tv%d,$%llu\n", expr->ctype->bit_size, new, value);
1018f08c3bdfSopenharmony_ci	return new;
1019f08c3bdfSopenharmony_ci}
1020f08c3bdfSopenharmony_ci
1021f08c3bdfSopenharmony_cistatic int show_fvalue(struct expression *expr)
1022f08c3bdfSopenharmony_ci{
1023f08c3bdfSopenharmony_ci	int new = new_pseudo();
1024f08c3bdfSopenharmony_ci	long double value = expr->fvalue;
1025f08c3bdfSopenharmony_ci
1026f08c3bdfSopenharmony_ci	printf("\tmovf.%d\t\tv%d,$%Le\n", expr->ctype->bit_size, new, value);
1027f08c3bdfSopenharmony_ci	return new;
1028f08c3bdfSopenharmony_ci}
1029f08c3bdfSopenharmony_ci
1030f08c3bdfSopenharmony_cistatic int show_string_expr(struct expression *expr)
1031f08c3bdfSopenharmony_ci{
1032f08c3bdfSopenharmony_ci	int new = new_pseudo();
1033f08c3bdfSopenharmony_ci
1034f08c3bdfSopenharmony_ci	printf("\tmovi.%d\t\tv%d,&%s\n", bits_in_pointer, new, show_string(expr->string));
1035f08c3bdfSopenharmony_ci	return new;
1036f08c3bdfSopenharmony_ci}
1037f08c3bdfSopenharmony_ci
1038f08c3bdfSopenharmony_cistatic int show_label_expr(struct expression *expr)
1039f08c3bdfSopenharmony_ci{
1040f08c3bdfSopenharmony_ci	int new = new_pseudo();
1041f08c3bdfSopenharmony_ci	printf("\tmovi.%d\t\tv%d,.L%p\n",bits_in_pointer, new, expr->label_symbol);
1042f08c3bdfSopenharmony_ci	return new;
1043f08c3bdfSopenharmony_ci}
1044f08c3bdfSopenharmony_ci
1045f08c3bdfSopenharmony_cistatic int show_conditional_expr(struct expression *expr)
1046f08c3bdfSopenharmony_ci{
1047f08c3bdfSopenharmony_ci	int cond = show_expression(expr->conditional);
1048f08c3bdfSopenharmony_ci	int valt = show_expression(expr->cond_true);
1049f08c3bdfSopenharmony_ci	int valf = show_expression(expr->cond_false);
1050f08c3bdfSopenharmony_ci	int new = new_pseudo();
1051f08c3bdfSopenharmony_ci
1052f08c3bdfSopenharmony_ci	printf("[v%d]\tcmov.%d\t\tv%d,v%d,v%d\n", cond, expr->ctype->bit_size, new, valt, valf);
1053f08c3bdfSopenharmony_ci	return new;
1054f08c3bdfSopenharmony_ci}
1055f08c3bdfSopenharmony_ci
1056f08c3bdfSopenharmony_cistatic int show_statement_expr(struct expression *expr)
1057f08c3bdfSopenharmony_ci{
1058f08c3bdfSopenharmony_ci	return show_statement(expr->statement);
1059f08c3bdfSopenharmony_ci}
1060f08c3bdfSopenharmony_ci
1061f08c3bdfSopenharmony_cistatic int show_position_expr(struct expression *expr, struct symbol *base)
1062f08c3bdfSopenharmony_ci{
1063f08c3bdfSopenharmony_ci	int new = show_expression(expr->init_expr);
1064f08c3bdfSopenharmony_ci	struct symbol *ctype = expr->init_expr->ctype;
1065f08c3bdfSopenharmony_ci	int bit_offset;
1066f08c3bdfSopenharmony_ci
1067f08c3bdfSopenharmony_ci	bit_offset = ctype ? ctype->bit_offset : -1;
1068f08c3bdfSopenharmony_ci
1069f08c3bdfSopenharmony_ci	printf("\tinsert v%d at [%d:%d] of %s\n", new,
1070f08c3bdfSopenharmony_ci		expr->init_offset, bit_offset,
1071f08c3bdfSopenharmony_ci		show_ident(base->ident));
1072f08c3bdfSopenharmony_ci	return 0;
1073f08c3bdfSopenharmony_ci}
1074f08c3bdfSopenharmony_ci
1075f08c3bdfSopenharmony_cistatic int show_initializer_expr(struct expression *expr, struct symbol *ctype)
1076f08c3bdfSopenharmony_ci{
1077f08c3bdfSopenharmony_ci	struct expression *entry;
1078f08c3bdfSopenharmony_ci
1079f08c3bdfSopenharmony_ci	FOR_EACH_PTR(expr->expr_list, entry) {
1080f08c3bdfSopenharmony_ci
1081f08c3bdfSopenharmony_ciagain:
1082f08c3bdfSopenharmony_ci		// Nested initializers have their positions already
1083f08c3bdfSopenharmony_ci		// recursively calculated - just output them too
1084f08c3bdfSopenharmony_ci		if (entry->type == EXPR_INITIALIZER) {
1085f08c3bdfSopenharmony_ci			show_initializer_expr(entry, ctype);
1086f08c3bdfSopenharmony_ci			continue;
1087f08c3bdfSopenharmony_ci		}
1088f08c3bdfSopenharmony_ci
1089f08c3bdfSopenharmony_ci		// Initializer indexes and identifiers should
1090f08c3bdfSopenharmony_ci		// have been evaluated to EXPR_POS
1091f08c3bdfSopenharmony_ci		if (entry->type == EXPR_IDENTIFIER) {
1092f08c3bdfSopenharmony_ci			printf(" AT '%s':\n", show_ident(entry->expr_ident));
1093f08c3bdfSopenharmony_ci			entry = entry->ident_expression;
1094f08c3bdfSopenharmony_ci			goto again;
1095f08c3bdfSopenharmony_ci		}
1096f08c3bdfSopenharmony_ci
1097f08c3bdfSopenharmony_ci		if (entry->type == EXPR_INDEX) {
1098f08c3bdfSopenharmony_ci			printf(" AT '%d..%d:\n", entry->idx_from, entry->idx_to);
1099f08c3bdfSopenharmony_ci			entry = entry->idx_expression;
1100f08c3bdfSopenharmony_ci			goto again;
1101f08c3bdfSopenharmony_ci		}
1102f08c3bdfSopenharmony_ci		if (entry->type == EXPR_POS) {
1103f08c3bdfSopenharmony_ci			show_position_expr(entry, ctype);
1104f08c3bdfSopenharmony_ci			continue;
1105f08c3bdfSopenharmony_ci		}
1106f08c3bdfSopenharmony_ci		show_initialization(ctype, entry);
1107f08c3bdfSopenharmony_ci	} END_FOR_EACH_PTR(entry);
1108f08c3bdfSopenharmony_ci	return 0;
1109f08c3bdfSopenharmony_ci}
1110f08c3bdfSopenharmony_ci
1111f08c3bdfSopenharmony_ciint show_symbol_expr_init(struct symbol *sym)
1112f08c3bdfSopenharmony_ci{
1113f08c3bdfSopenharmony_ci	struct expression *expr = sym->initializer;
1114f08c3bdfSopenharmony_ci
1115f08c3bdfSopenharmony_ci	if (expr)
1116f08c3bdfSopenharmony_ci		show_expression(expr);
1117f08c3bdfSopenharmony_ci	return show_symbol_expr(sym);
1118f08c3bdfSopenharmony_ci}
1119f08c3bdfSopenharmony_ci
1120f08c3bdfSopenharmony_ci/*
1121f08c3bdfSopenharmony_ci * Print out an expression. Return the pseudo that contains the
1122f08c3bdfSopenharmony_ci * variable.
1123f08c3bdfSopenharmony_ci */
1124f08c3bdfSopenharmony_ciint show_expression(struct expression *expr)
1125f08c3bdfSopenharmony_ci{
1126f08c3bdfSopenharmony_ci	if (!expr)
1127f08c3bdfSopenharmony_ci		return 0;
1128f08c3bdfSopenharmony_ci
1129f08c3bdfSopenharmony_ci	if (!expr->ctype) {
1130f08c3bdfSopenharmony_ci		struct position *pos = &expr->pos;
1131f08c3bdfSopenharmony_ci		printf("\tno type at %s:%d:%d\n",
1132f08c3bdfSopenharmony_ci			stream_name(pos->stream),
1133f08c3bdfSopenharmony_ci			pos->line, pos->pos);
1134f08c3bdfSopenharmony_ci		return 0;
1135f08c3bdfSopenharmony_ci	}
1136f08c3bdfSopenharmony_ci
1137f08c3bdfSopenharmony_ci	switch (expr->type) {
1138f08c3bdfSopenharmony_ci	case EXPR_CALL:
1139f08c3bdfSopenharmony_ci		return show_call_expression(expr);
1140f08c3bdfSopenharmony_ci
1141f08c3bdfSopenharmony_ci	case EXPR_ASSIGNMENT:
1142f08c3bdfSopenharmony_ci		return show_assignment(expr);
1143f08c3bdfSopenharmony_ci
1144f08c3bdfSopenharmony_ci	case EXPR_COMMA:
1145f08c3bdfSopenharmony_ci		return show_comma(expr);
1146f08c3bdfSopenharmony_ci	case EXPR_BINOP:
1147f08c3bdfSopenharmony_ci	case EXPR_COMPARE:
1148f08c3bdfSopenharmony_ci	case EXPR_LOGICAL:
1149f08c3bdfSopenharmony_ci		return show_binop(expr);
1150f08c3bdfSopenharmony_ci	case EXPR_PREOP:
1151f08c3bdfSopenharmony_ci		return show_preop(expr);
1152f08c3bdfSopenharmony_ci	case EXPR_POSTOP:
1153f08c3bdfSopenharmony_ci		return show_postop(expr);
1154f08c3bdfSopenharmony_ci	case EXPR_SYMBOL:
1155f08c3bdfSopenharmony_ci		return show_symbol_expr(expr->symbol);
1156f08c3bdfSopenharmony_ci	case EXPR_DEREF:
1157f08c3bdfSopenharmony_ci	case EXPR_SIZEOF:
1158f08c3bdfSopenharmony_ci	case EXPR_PTRSIZEOF:
1159f08c3bdfSopenharmony_ci	case EXPR_ALIGNOF:
1160f08c3bdfSopenharmony_ci	case EXPR_OFFSETOF:
1161f08c3bdfSopenharmony_ci		warning(expr->pos, "invalid expression after evaluation");
1162f08c3bdfSopenharmony_ci		return 0;
1163f08c3bdfSopenharmony_ci	case EXPR_CAST:
1164f08c3bdfSopenharmony_ci	case EXPR_FORCE_CAST:
1165f08c3bdfSopenharmony_ci	case EXPR_IMPLIED_CAST:
1166f08c3bdfSopenharmony_ci		return show_cast_expr(expr);
1167f08c3bdfSopenharmony_ci	case EXPR_VALUE:
1168f08c3bdfSopenharmony_ci		return show_value(expr);
1169f08c3bdfSopenharmony_ci	case EXPR_FVALUE:
1170f08c3bdfSopenharmony_ci		return show_fvalue(expr);
1171f08c3bdfSopenharmony_ci	case EXPR_STRING:
1172f08c3bdfSopenharmony_ci		return show_string_expr(expr);
1173f08c3bdfSopenharmony_ci	case EXPR_INITIALIZER:
1174f08c3bdfSopenharmony_ci		return show_initializer_expr(expr, expr->ctype);
1175f08c3bdfSopenharmony_ci	case EXPR_SELECT:
1176f08c3bdfSopenharmony_ci	case EXPR_CONDITIONAL:
1177f08c3bdfSopenharmony_ci		return show_conditional_expr(expr);
1178f08c3bdfSopenharmony_ci	case EXPR_STATEMENT:
1179f08c3bdfSopenharmony_ci		return show_statement_expr(expr);
1180f08c3bdfSopenharmony_ci	case EXPR_LABEL:
1181f08c3bdfSopenharmony_ci		return show_label_expr(expr);
1182f08c3bdfSopenharmony_ci	case EXPR_SLICE:
1183f08c3bdfSopenharmony_ci		return show_slice(expr);
1184f08c3bdfSopenharmony_ci
1185f08c3bdfSopenharmony_ci	// None of these should exist as direct expressions: they are only
1186f08c3bdfSopenharmony_ci	// valid as sub-expressions of initializers.
1187f08c3bdfSopenharmony_ci	case EXPR_POS:
1188f08c3bdfSopenharmony_ci		warning(expr->pos, "unable to show plain initializer position expression");
1189f08c3bdfSopenharmony_ci		return 0;
1190f08c3bdfSopenharmony_ci	case EXPR_IDENTIFIER:
1191f08c3bdfSopenharmony_ci		warning(expr->pos, "unable to show identifier expression");
1192f08c3bdfSopenharmony_ci		return 0;
1193f08c3bdfSopenharmony_ci	case EXPR_INDEX:
1194f08c3bdfSopenharmony_ci		warning(expr->pos, "unable to show index expression");
1195f08c3bdfSopenharmony_ci		return 0;
1196f08c3bdfSopenharmony_ci	case EXPR_TYPE:
1197f08c3bdfSopenharmony_ci		warning(expr->pos, "unable to show type expression");
1198f08c3bdfSopenharmony_ci		return 0;
1199f08c3bdfSopenharmony_ci	case EXPR_GENERIC:
1200f08c3bdfSopenharmony_ci		warning(expr->pos, "unable to show generic expression");
1201f08c3bdfSopenharmony_ci		return 0;
1202f08c3bdfSopenharmony_ci	}
1203f08c3bdfSopenharmony_ci	return 0;
1204f08c3bdfSopenharmony_ci}
1205