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