1 1.84 rillig /* $NetBSD: debug.c,v 1.84 2025/07/11 19:03:01 rillig Exp $ */ 2 1.1 rillig 3 1.1 rillig /*- 4 1.1 rillig * Copyright (c) 2021 The NetBSD Foundation, Inc. 5 1.1 rillig * All rights reserved. 6 1.1 rillig * 7 1.1 rillig * This code is derived from software contributed to The NetBSD Foundation 8 1.1 rillig * by Roland Illig <rillig (at) NetBSD.org>. 9 1.1 rillig * 10 1.1 rillig * Redistribution and use in source and binary forms, with or without 11 1.1 rillig * modification, are permitted provided that the following conditions 12 1.1 rillig * are met: 13 1.1 rillig * 1. Redistributions of source code must retain the above copyright 14 1.1 rillig * notice, this list of conditions and the following disclaimer. 15 1.1 rillig * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 rillig * notice, this list of conditions and the following disclaimer in the 17 1.1 rillig * documentation and/or other materials provided with the distribution. 18 1.1 rillig * 19 1.1 rillig * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 rillig * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 rillig * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 rillig * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 rillig * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 rillig * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 rillig * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 rillig * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 rillig * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 rillig * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 rillig * POSSIBILITY OF SUCH DAMAGE. 30 1.1 rillig */ 31 1.1 rillig 32 1.1 rillig #if HAVE_NBTOOL_CONFIG_H 33 1.1 rillig #include "nbtool_config.h" 34 1.1 rillig #endif 35 1.1 rillig 36 1.1 rillig #include <sys/cdefs.h> 37 1.18 rillig #if defined(__RCSID) 38 1.84 rillig __RCSID("$NetBSD: debug.c,v 1.84 2025/07/11 19:03:01 rillig Exp $"); 39 1.1 rillig #endif 40 1.1 rillig 41 1.2 rillig #include <stdlib.h> 42 1.58 rillig #include <string.h> 43 1.2 rillig 44 1.1 rillig #include "lint1.h" 45 1.9 rillig #include "cgram.h" 46 1.1 rillig 47 1.1 rillig 48 1.1 rillig #ifdef DEBUG 49 1.1 rillig 50 1.80 rillig bool debug_enabled; 51 1.1 rillig static int debug_indentation = 0; 52 1.58 rillig static bool did_indentation; 53 1.1 rillig 54 1.1 rillig 55 1.32 rillig static FILE * 56 1.32 rillig debug_file(void) 57 1.32 rillig { 58 1.32 rillig /* 59 1.32 rillig * Using stdout preserves the order between the debug messages and 60 1.32 rillig * lint's diagnostics. 61 1.32 rillig */ 62 1.48 rillig return yflag ? stderr : stdout; 63 1.32 rillig } 64 1.32 rillig 65 1.58 rillig static void 66 1.58 rillig debug_vprintf(const char *fmt, va_list va) 67 1.58 rillig { 68 1.58 rillig 69 1.80 rillig if (!debug_enabled) 70 1.80 rillig return; 71 1.80 rillig 72 1.58 rillig if (!did_indentation) { 73 1.58 rillig did_indentation = true; 74 1.58 rillig fprintf(debug_file(), "%s%*s", 75 1.58 rillig yflag ? "| " : "", 2 * debug_indentation, ""); 76 1.58 rillig } 77 1.58 rillig 78 1.58 rillig (void)vfprintf(debug_file(), fmt, va); 79 1.58 rillig 80 1.58 rillig did_indentation = strchr(fmt, '\n') == NULL; 81 1.58 rillig } 82 1.58 rillig 83 1.34 rillig void 84 1.1 rillig debug_printf(const char *fmt, ...) 85 1.1 rillig { 86 1.1 rillig va_list va; 87 1.1 rillig 88 1.1 rillig va_start(va, fmt); 89 1.58 rillig debug_vprintf(fmt, va); 90 1.1 rillig va_end(va); 91 1.1 rillig } 92 1.1 rillig 93 1.1 rillig void 94 1.58 rillig debug_skip_indent(void) 95 1.1 rillig { 96 1.1 rillig 97 1.58 rillig did_indentation = true; 98 1.1 rillig } 99 1.1 rillig 100 1.1 rillig void 101 1.1 rillig debug_indent_inc(void) 102 1.1 rillig { 103 1.1 rillig 104 1.1 rillig debug_indentation++; 105 1.1 rillig } 106 1.1 rillig 107 1.1 rillig void 108 1.1 rillig debug_indent_dec(void) 109 1.1 rillig { 110 1.1 rillig 111 1.57 rillig lint_assert(debug_indentation > 0); 112 1.1 rillig debug_indentation--; 113 1.1 rillig } 114 1.1 rillig 115 1.59 rillig bool 116 1.59 rillig debug_push_indented(bool indented) 117 1.59 rillig { 118 1.59 rillig bool prev = did_indentation; 119 1.59 rillig did_indentation = indented; 120 1.59 rillig return prev; 121 1.59 rillig } 122 1.59 rillig 123 1.59 rillig void 124 1.59 rillig debug_pop_indented(bool indented) 125 1.59 rillig { 126 1.59 rillig did_indentation = indented; 127 1.59 rillig } 128 1.59 rillig 129 1.1 rillig void 130 1.1 rillig debug_step(const char *fmt, ...) 131 1.1 rillig { 132 1.1 rillig va_list va; 133 1.1 rillig 134 1.1 rillig va_start(va, fmt); 135 1.58 rillig debug_vprintf(fmt, va); 136 1.1 rillig va_end(va); 137 1.58 rillig debug_printf("\n"); 138 1.1 rillig } 139 1.1 rillig 140 1.1 rillig void 141 1.48 rillig debug_enter_func(const char *func) 142 1.48 rillig { 143 1.48 rillig 144 1.48 rillig debug_step("+ %s", func); 145 1.48 rillig debug_indent_inc(); 146 1.48 rillig } 147 1.48 rillig 148 1.48 rillig void 149 1.28 rillig debug_leave_func(const char *func) 150 1.1 rillig { 151 1.1 rillig 152 1.48 rillig debug_indent_dec(); 153 1.48 rillig debug_step("- %s", func); 154 1.1 rillig } 155 1.1 rillig 156 1.22 rillig static void 157 1.22 rillig debug_type_details(const type_t *tp) 158 1.22 rillig { 159 1.22 rillig 160 1.22 rillig if (is_struct_or_union(tp->t_tspec)) { 161 1.22 rillig debug_indent_inc(); 162 1.77 rillig unsigned int size_in_bits = tp->u.sou->sou_size_in_bits; 163 1.77 rillig debug_printf("size %u", size_in_bits / CHAR_SIZE); 164 1.77 rillig if (size_in_bits % CHAR_SIZE > 0) 165 1.77 rillig debug_printf("+%u", size_in_bits % CHAR_SIZE); 166 1.77 rillig debug_step(", align %u, %s", 167 1.77 rillig tp->u.sou->sou_align, 168 1.72 rillig tp->u.sou->sou_incomplete ? "incomplete" : "complete"); 169 1.38 rillig 170 1.72 rillig for (const sym_t *mem = tp->u.sou->sou_first_member; 171 1.65 rillig mem != NULL; mem = mem->s_next) { 172 1.22 rillig debug_sym("", mem, "\n"); 173 1.22 rillig debug_type_details(mem->s_type); 174 1.22 rillig } 175 1.22 rillig debug_indent_dec(); 176 1.22 rillig } 177 1.22 rillig if (tp->t_is_enum) { 178 1.22 rillig debug_indent_inc(); 179 1.72 rillig for (const sym_t *en = tp->u.enumer->en_first_enumerator; 180 1.65 rillig en != NULL; en = en->s_next) { 181 1.22 rillig debug_sym("", en, "\n"); 182 1.22 rillig } 183 1.22 rillig debug_indent_dec(); 184 1.22 rillig } 185 1.22 rillig } 186 1.22 rillig 187 1.22 rillig void 188 1.22 rillig debug_type(const type_t *tp) 189 1.22 rillig { 190 1.22 rillig 191 1.22 rillig debug_step("type details for '%s':", type_name(tp)); 192 1.22 rillig debug_type_details(tp); 193 1.22 rillig } 194 1.22 rillig 195 1.1 rillig void 196 1.10 rillig debug_node(const tnode_t *tn) // NOLINT(misc-no-recursion) 197 1.1 rillig { 198 1.1 rillig 199 1.1 rillig if (tn == NULL) { 200 1.2 rillig debug_step("null"); 201 1.1 rillig return; 202 1.1 rillig } 203 1.1 rillig 204 1.63 rillig op_t op = tn->tn_op; 205 1.20 rillig debug_printf("'%s'", 206 1.63 rillig op == CVT && tn->tn_cast ? "cast" : op_name(op)); 207 1.20 rillig if (op == NAME) 208 1.20 rillig debug_printf(" '%s' with %s", 209 1.73 rillig tn->u.sym->s_name, 210 1.73 rillig scl_name(tn->u.sym->s_scl)); 211 1.20 rillig else 212 1.20 rillig debug_printf(" type"); 213 1.20 rillig debug_printf(" '%s'", type_name(tn->tn_type)); 214 1.20 rillig if (tn->tn_lvalue) 215 1.20 rillig debug_printf(", lvalue"); 216 1.20 rillig if (tn->tn_parenthesized) 217 1.20 rillig debug_printf(", parenthesized"); 218 1.20 rillig if (tn->tn_sys) 219 1.20 rillig debug_printf(", sys"); 220 1.1 rillig 221 1.24 rillig switch (op) { 222 1.24 rillig case NAME: 223 1.20 rillig debug_printf("\n"); 224 1.24 rillig break; 225 1.24 rillig case CON: 226 1.24 rillig if (is_floating(tn->tn_type->t_tspec)) 227 1.73 rillig debug_printf(", value %Lg", tn->u.value.u.floating); 228 1.24 rillig else if (is_uinteger(tn->tn_type->t_tspec)) 229 1.27 rillig debug_printf(", value %llu", 230 1.73 rillig (unsigned long long)tn->u.value.u.integer); 231 1.24 rillig else if (is_integer(tn->tn_type->t_tspec)) 232 1.27 rillig debug_printf(", value %lld", 233 1.73 rillig (long long)tn->u.value.u.integer); 234 1.27 rillig else { 235 1.27 rillig lint_assert(tn->tn_type->t_tspec == BOOL); 236 1.27 rillig debug_printf(", value %s", 237 1.73 rillig tn->u.value.u.integer != 0 ? "true" : "false"); 238 1.27 rillig } 239 1.73 rillig if (tn->u.value.v_unsigned_since_c90) 240 1.27 rillig debug_printf(", unsigned_since_c90"); 241 1.73 rillig if (tn->u.value.v_char_constant) 242 1.35 rillig debug_printf(", char_constant"); 243 1.27 rillig debug_printf("\n"); 244 1.24 rillig break; 245 1.24 rillig case STRING: 246 1.73 rillig if (tn->u.str_literals->data != NULL) 247 1.73 rillig debug_printf(", %s\n", tn->u.str_literals->data); 248 1.70 rillig else 249 1.73 rillig debug_printf(", length %zu\n", tn->u.str_literals->len); 250 1.24 rillig break; 251 1.71 rillig case CALL: 252 1.71 rillig debug_printf("\n"); 253 1.71 rillig 254 1.71 rillig debug_indent_inc(); 255 1.73 rillig const function_call *call = tn->u.call; 256 1.71 rillig debug_node(call->func); 257 1.74 rillig for (size_t i = 0, n = call->args_len; i < n; i++) 258 1.74 rillig debug_node(call->args[i]); 259 1.71 rillig debug_indent_dec(); 260 1.71 rillig break; 261 1.24 rillig default: 262 1.2 rillig debug_printf("\n"); 263 1.1 rillig 264 1.2 rillig debug_indent_inc(); 265 1.62 rillig lint_assert(has_operands(tn)); 266 1.73 rillig lint_assert(tn->u.ops.left != NULL); 267 1.73 rillig debug_node(tn->u.ops.left); 268 1.33 rillig if (op != INCBEF && op != INCAFT 269 1.75 rillig && op != DECBEF && op != DECAFT) 270 1.73 rillig lint_assert(is_binary(tn) == (tn->u.ops.right != NULL)); 271 1.73 rillig if (tn->u.ops.right != NULL) 272 1.73 rillig debug_node(tn->u.ops.right); 273 1.2 rillig debug_indent_dec(); 274 1.1 rillig } 275 1.1 rillig } 276 1.1 rillig 277 1.9 rillig static const char * 278 1.9 rillig def_name(def_t def) 279 1.9 rillig { 280 1.9 rillig static const char *const name[] = { 281 1.9 rillig "not-declared", 282 1.9 rillig "declared", 283 1.9 rillig "tentative-defined", 284 1.9 rillig "defined", 285 1.9 rillig }; 286 1.9 rillig 287 1.9 rillig return name[def]; 288 1.9 rillig } 289 1.9 rillig 290 1.9 rillig const char * 291 1.40 rillig decl_level_kind_name(decl_level_kind kind) 292 1.17 rillig { 293 1.17 rillig static const char *const name[] = { 294 1.17 rillig "extern", 295 1.40 rillig "struct", 296 1.40 rillig "union", 297 1.40 rillig "enum", 298 1.60 rillig "old-style-function-parameters", 299 1.40 rillig "prototype-parameters", 300 1.17 rillig "auto", 301 1.17 rillig "abstract", 302 1.17 rillig }; 303 1.17 rillig 304 1.40 rillig return name[kind]; 305 1.17 rillig } 306 1.17 rillig 307 1.17 rillig const char * 308 1.9 rillig scl_name(scl_t scl) 309 1.9 rillig { 310 1.9 rillig static const char *const name[] = { 311 1.9 rillig "none", 312 1.9 rillig "extern", 313 1.9 rillig "static", 314 1.9 rillig "auto", 315 1.9 rillig "register", 316 1.9 rillig "typedef", 317 1.53 rillig "thread_local", 318 1.9 rillig "struct", 319 1.9 rillig "union", 320 1.9 rillig "enum", 321 1.9 rillig "member-of-struct", 322 1.9 rillig "member-of-union", 323 1.9 rillig "abstract", 324 1.60 rillig "old-style-function-parameter", 325 1.60 rillig "prototype-parameter", 326 1.9 rillig }; 327 1.9 rillig 328 1.9 rillig return name[scl]; 329 1.9 rillig } 330 1.9 rillig 331 1.9 rillig const char * 332 1.66 rillig symbol_kind_name(symbol_kind kind) 333 1.9 rillig { 334 1.9 rillig static const char *const name[] = { 335 1.9 rillig "var-func-type", 336 1.9 rillig "member", 337 1.9 rillig "tag", 338 1.9 rillig "label", 339 1.9 rillig }; 340 1.9 rillig 341 1.9 rillig return name[kind]; 342 1.9 rillig } 343 1.9 rillig 344 1.9 rillig const char * 345 1.54 rillig type_qualifiers_string(type_qualifiers tq) 346 1.9 rillig { 347 1.54 rillig static char buf[32]; 348 1.9 rillig 349 1.54 rillig snprintf(buf, sizeof(buf), "%s%s%s%s", 350 1.54 rillig tq.tq_const ? " const" : "", 351 1.54 rillig tq.tq_restrict ? " restrict" : "", 352 1.54 rillig tq.tq_volatile ? " volatile" : "", 353 1.54 rillig tq.tq_atomic ? " atomic" : ""); 354 1.54 rillig return buf[0] != '\0' ? buf + 1 : "none"; 355 1.9 rillig } 356 1.9 rillig 357 1.50 rillig const char * 358 1.81 rillig type_attributes_string(type_attributes attrs) 359 1.81 rillig { 360 1.82 rillig static char buf[32]; 361 1.82 rillig 362 1.83 rillig snprintf(buf, sizeof(buf), "%s%s%s", 363 1.82 rillig attrs.used ? " used" : "", 364 1.83 rillig attrs.noreturn ? " noreturn" : "", 365 1.83 rillig attrs.bit_width == 128 ? " 128bit" : 366 1.83 rillig attrs.bit_width == 64 ? " 64bit" : ""); 367 1.82 rillig return buf[0] != '\0' ? buf + 1 : "none"; 368 1.81 rillig } 369 1.81 rillig 370 1.81 rillig const char * 371 1.50 rillig function_specifier_name(function_specifier spec) 372 1.50 rillig { 373 1.50 rillig static const char *const name[] = { 374 1.50 rillig "inline", 375 1.51 rillig "_Noreturn", 376 1.50 rillig }; 377 1.50 rillig 378 1.50 rillig return name[spec]; 379 1.50 rillig } 380 1.50 rillig 381 1.78 rillig const char * 382 1.78 rillig named_constant_name(named_constant nc) 383 1.78 rillig { 384 1.78 rillig static const char *const name[] = { 385 1.78 rillig "false", 386 1.78 rillig "true", 387 1.78 rillig "nullptr", 388 1.78 rillig }; 389 1.78 rillig 390 1.78 rillig return name[nc]; 391 1.78 rillig } 392 1.78 rillig 393 1.9 rillig static void 394 1.9 rillig debug_word(bool flag, const char *name) 395 1.9 rillig { 396 1.9 rillig 397 1.9 rillig if (flag) 398 1.9 rillig debug_printf(" %s", name); 399 1.9 rillig } 400 1.9 rillig 401 1.9 rillig void 402 1.10 rillig debug_sym(const char *prefix, const sym_t *sym, const char *suffix) 403 1.9 rillig { 404 1.9 rillig 405 1.10 rillig debug_printf("%s%s", prefix, sym->s_name); 406 1.9 rillig if (sym->s_type != NULL) 407 1.9 rillig debug_printf(" type='%s'", type_name(sym->s_type)); 408 1.9 rillig if (sym->s_rename != NULL) 409 1.9 rillig debug_printf(" rename=%s", sym->s_rename); 410 1.66 rillig debug_printf(" %s", symbol_kind_name(sym->s_kind)); 411 1.9 rillig debug_word(sym->s_keyword != NULL, "keyword"); 412 1.9 rillig debug_word(sym->s_bitfield, "bit-field"); 413 1.9 rillig debug_word(sym->s_set, "set"); 414 1.9 rillig debug_word(sym->s_used, "used"); 415 1.60 rillig debug_word(sym->s_param, "parameter"); 416 1.9 rillig debug_word(sym->s_register, "register"); 417 1.60 rillig debug_word(sym->s_defparam, "old-style-undefined"); 418 1.9 rillig debug_word(sym->s_return_type_implicit_int, "return-int"); 419 1.9 rillig debug_word(sym->s_osdef, "old-style"); 420 1.9 rillig debug_word(sym->s_inline, "inline"); 421 1.9 rillig debug_word(sym->s_ext_sym != NULL, "has-external"); 422 1.64 rillig debug_word(sym->s_scl != NO_SCL, scl_name(sym->s_scl)); 423 1.9 rillig debug_word(sym->s_keyword == NULL, def_name(sym->s_def)); 424 1.9 rillig 425 1.9 rillig if (sym->s_def_pos.p_file != NULL) 426 1.9 rillig debug_printf(" defined-at=%s:%d", 427 1.9 rillig sym->s_def_pos.p_file, sym->s_def_pos.p_line); 428 1.9 rillig if (sym->s_set_pos.p_file != NULL) 429 1.9 rillig debug_printf(" set-at=%s:%d", 430 1.9 rillig sym->s_set_pos.p_file, sym->s_set_pos.p_line); 431 1.9 rillig if (sym->s_use_pos.p_file != NULL) 432 1.9 rillig debug_printf(" used-at=%s:%d", 433 1.9 rillig sym->s_use_pos.p_file, sym->s_use_pos.p_line); 434 1.9 rillig 435 1.14 rillig if (sym->s_type != NULL && sym->s_type->t_is_enum) 436 1.14 rillig debug_printf(" value=%d", sym->u.s_enum_constant); 437 1.14 rillig if (sym->s_type != NULL && sym->s_type->t_tspec == BOOL) 438 1.14 rillig debug_printf(" value=%s", 439 1.14 rillig sym->u.s_bool_constant ? "true" : "false"); 440 1.9 rillig 441 1.39 rillig if (is_member(sym)) { 442 1.42 rillig struct_or_union *sou = sym->u.s_member.sm_containing_type; 443 1.42 rillig const char *tag = sou->sou_tag->s_name; 444 1.42 rillig const sym_t *def = sou->sou_first_typedef; 445 1.9 rillig if (tag == unnamed && def != NULL) 446 1.9 rillig debug_printf(" sou='typedef %s'", def->s_name); 447 1.9 rillig else 448 1.42 rillig debug_printf(" sou='%s'", tag); 449 1.9 rillig } 450 1.9 rillig 451 1.9 rillig if (sym->s_keyword != NULL) { 452 1.14 rillig int t = sym->u.s_keyword.sk_token; 453 1.9 rillig if (t == T_TYPE || t == T_STRUCT_OR_UNION) 454 1.14 rillig debug_printf(" %s", 455 1.50 rillig tspec_name(sym->u.s_keyword.u.sk_tspec)); 456 1.42 rillig if (t == T_QUAL) 457 1.54 rillig debug_printf(" %s", type_qualifiers_string( 458 1.54 rillig sym->u.s_keyword.u.sk_type_qualifier)); 459 1.50 rillig if (t == T_FUNCTION_SPECIFIER) 460 1.50 rillig debug_printf(" %s", function_specifier_name( 461 1.50 rillig sym->u.s_keyword.u.function_specifier)); 462 1.9 rillig } 463 1.9 rillig 464 1.84 rillig if (sym->s_type->t_tspec == ARRAY 465 1.84 rillig && sym->u.s_array_nonnull_dimension > 0) 466 1.84 rillig debug_printf(" nonnull-dimension %zu", 467 1.84 rillig sym->u.s_array_nonnull_dimension); 468 1.84 rillig 469 1.60 rillig debug_word(sym->s_osdef && sym->u.s_old_style_params != NULL, 470 1.60 rillig "old-style-params"); 471 1.9 rillig 472 1.58 rillig if (strcmp(suffix, "\n") == 0) 473 1.58 rillig debug_printf("\n"); 474 1.58 rillig else 475 1.58 rillig debug_printf("%s", suffix); 476 1.10 rillig } 477 1.10 rillig 478 1.43 rillig static void 479 1.43 rillig debug_decl_level(const decl_level *dl) 480 1.10 rillig { 481 1.10 rillig 482 1.59 rillig debug_printf("kind=%s", decl_level_kind_name(dl->d_kind)); 483 1.64 rillig if (dl->d_scl != NO_SCL) 484 1.40 rillig debug_printf(" %s", scl_name(dl->d_scl)); 485 1.40 rillig if (dl->d_type != NULL) 486 1.40 rillig debug_printf(" '%s'", type_name(dl->d_type)); 487 1.40 rillig else { 488 1.40 rillig if (dl->d_abstract_type != NO_TSPEC) 489 1.40 rillig debug_printf(" %s", tspec_name(dl->d_abstract_type)); 490 1.40 rillig if (dl->d_complex_mod != NO_TSPEC) 491 1.40 rillig debug_printf(" %s", tspec_name(dl->d_complex_mod)); 492 1.40 rillig if (dl->d_sign_mod != NO_TSPEC) 493 1.40 rillig debug_printf(" %s", tspec_name(dl->d_sign_mod)); 494 1.40 rillig if (dl->d_rank_mod != NO_TSPEC) 495 1.40 rillig debug_printf(" %s", tspec_name(dl->d_rank_mod)); 496 1.10 rillig } 497 1.40 rillig if (dl->d_redeclared_symbol != NULL) 498 1.40 rillig debug_sym(" redeclared=(", dl->d_redeclared_symbol, ")"); 499 1.77 rillig if (dl->d_sou_size_in_bits > 0) 500 1.77 rillig debug_printf(" size=%u", dl->d_sou_size_in_bits / CHAR_SIZE); 501 1.77 rillig if (dl->d_sou_size_in_bits % CHAR_SIZE > 0) 502 1.77 rillig debug_printf("+%u", dl->d_sou_size_in_bits % CHAR_SIZE); 503 1.77 rillig if (dl->d_sou_align > 0) 504 1.77 rillig debug_printf(" sou_align=%u", dl->d_sou_align); 505 1.77 rillig if (dl->d_mem_align > 0) 506 1.77 rillig debug_printf(" mem_align=%u", dl->d_mem_align); 507 1.40 rillig 508 1.55 rillig debug_word(dl->d_qual.tq_const, "const"); 509 1.55 rillig debug_word(dl->d_qual.tq_restrict, "restrict"); 510 1.55 rillig debug_word(dl->d_qual.tq_volatile, "volatile"); 511 1.55 rillig debug_word(dl->d_qual.tq_atomic, "atomic"); 512 1.40 rillig debug_word(dl->d_inline, "inline"); 513 1.40 rillig debug_word(dl->d_multiple_storage_classes, "multiple_storage_classes"); 514 1.40 rillig debug_word(dl->d_invalid_type_combination, "invalid_type_combination"); 515 1.40 rillig debug_word(dl->d_nonempty_decl, "nonempty_decl"); 516 1.40 rillig debug_word(dl->d_no_type_specifier, "no_type_specifier"); 517 1.40 rillig debug_word(dl->d_asm, "asm"); 518 1.40 rillig debug_word(dl->d_packed, "packed"); 519 1.40 rillig debug_word(dl->d_used, "used"); 520 1.82 rillig debug_word(dl->d_noreturn, "noreturn"); 521 1.40 rillig 522 1.40 rillig if (dl->d_tag_type != NULL) 523 1.40 rillig debug_printf(" tag_type='%s'", type_name(dl->d_tag_type)); 524 1.60 rillig for (const sym_t *p = dl->d_func_params; p != NULL; p = p->s_next) 525 1.60 rillig debug_sym(" param(", p, ")"); 526 1.40 rillig if (dl->d_func_def_pos.p_file != NULL) 527 1.41 rillig debug_printf(" func_def_pos=%s:%d:%d", 528 1.40 rillig dl->d_func_def_pos.p_file, dl->d_func_def_pos.p_line, 529 1.40 rillig dl->d_func_def_pos.p_uniq); 530 1.40 rillig for (const sym_t *sym = dl->d_func_proto_syms; 531 1.65 rillig sym != NULL; sym = sym->s_next) 532 1.23 rillig debug_sym(" func_proto_sym(", sym, ")"); 533 1.9 rillig debug_printf("\n"); 534 1.43 rillig } 535 1.10 rillig 536 1.43 rillig void 537 1.59 rillig debug_dcs(void) 538 1.59 rillig { 539 1.59 rillig debug_printf("dcs "); 540 1.59 rillig debug_decl_level(dcs); 541 1.59 rillig } 542 1.59 rillig 543 1.59 rillig void 544 1.59 rillig debug_dcs_all(void) 545 1.43 rillig { 546 1.59 rillig size_t i = 0; 547 1.43 rillig for (const decl_level *dl = dcs; dl != NULL; dl = dl->d_enclosing) { 548 1.59 rillig debug_printf("dcs[%zu] ", i++); 549 1.43 rillig debug_decl_level(dl); 550 1.10 rillig } 551 1.9 rillig } 552 1.79 rillig 553 1.79 rillig static void 554 1.79 rillig debug_token(const token *tok) 555 1.79 rillig { 556 1.79 rillig switch (tok->kind) { 557 1.79 rillig case TK_IDENTIFIER: 558 1.79 rillig debug_printf("%s", tok->u.identifier); 559 1.79 rillig break; 560 1.79 rillig case TK_CONSTANT:; 561 1.79 rillig val_t c = tok->u.constant; 562 1.79 rillig tspec_t t = c.v_tspec; 563 1.79 rillig if (is_floating(t)) 564 1.79 rillig debug_printf("%Lg", c.u.floating); 565 1.79 rillig else if (is_uinteger(t)) 566 1.79 rillig debug_printf("%llu", (unsigned long long)c.u.integer); 567 1.79 rillig else if (is_integer(t)) 568 1.79 rillig debug_printf("%lld", (long long)c.u.integer); 569 1.79 rillig else { 570 1.79 rillig lint_assert(t == BOOL); 571 1.79 rillig debug_printf("%s", 572 1.79 rillig c.u.integer != 0 ? "true" : "false"); 573 1.79 rillig } 574 1.79 rillig break; 575 1.79 rillig case TK_STRING_LITERALS: 576 1.79 rillig debug_printf("%s", tok->u.string_literals.data); 577 1.79 rillig break; 578 1.79 rillig case TK_PUNCTUATOR: 579 1.79 rillig debug_printf("%s", tok->u.punctuator); 580 1.79 rillig break; 581 1.79 rillig } 582 1.79 rillig } 583 1.79 rillig 584 1.79 rillig static void 585 1.79 rillig debug_balanced_token_sequence(const balanced_token_sequence *seq) 586 1.79 rillig { 587 1.79 rillig const char *sep = ""; 588 1.79 rillig for (size_t i = 0, n = seq->len; i < n; i++) { 589 1.79 rillig const balanced_token *tok = seq->tokens + i; 590 1.79 rillig if (tok->kind != '\0') { 591 1.79 rillig debug_printf("%s%c", sep, tok->kind); 592 1.79 rillig debug_balanced_token_sequence(&tok->u.tokens); 593 1.79 rillig debug_printf("%c", tok->kind == '(' ? ')' 594 1.79 rillig : tok->kind == '[' ? ']' : '}'); 595 1.79 rillig } else { 596 1.79 rillig debug_printf("%s", sep); 597 1.79 rillig debug_token(&tok->u.token); 598 1.79 rillig } 599 1.79 rillig sep = " "; 600 1.79 rillig } 601 1.79 rillig } 602 1.79 rillig 603 1.79 rillig void 604 1.79 rillig debug_attribute_list(const attribute_list *list) 605 1.79 rillig { 606 1.79 rillig for (size_t i = 0, n = list->len; i < n; i++) { 607 1.79 rillig const attribute *attr = list->attrs + i; 608 1.79 rillig debug_printf("attribute [["); 609 1.79 rillig if (attr->prefix != NULL) 610 1.79 rillig debug_printf("%s::", attr->prefix); 611 1.79 rillig debug_printf("%s", attr->name); 612 1.79 rillig if (attr->arg != NULL) { 613 1.79 rillig debug_printf("("); 614 1.79 rillig debug_balanced_token_sequence(attr->arg); 615 1.79 rillig debug_printf(")"); 616 1.79 rillig } 617 1.79 rillig debug_step("]]"); 618 1.79 rillig } 619 1.79 rillig } 620 1.79 rillig 621 1.1 rillig #endif 622