Module Name: src Committed By: rillig Date: Tue Mar 1 00:17:12 UTC 2022
Modified Files: src/usr.bin/xlint/lint1: cgram.y debug.c decl.c externs1.h lex.c Log Message: lint: add debug logging for symbols and the symbol table This logging is not active by default, the functions debug_sym and debug_symtab can be called as needed during a debug session. To generate a diff of this commit: cvs rdiff -u -r1.386 -r1.387 src/usr.bin/xlint/lint1/cgram.y cvs rdiff -u -r1.8 -r1.9 src/usr.bin/xlint/lint1/debug.c cvs rdiff -u -r1.251 -r1.252 src/usr.bin/xlint/lint1/decl.c cvs rdiff -u -r1.148 -r1.149 src/usr.bin/xlint/lint1/externs1.h cvs rdiff -u -r1.106 -r1.107 src/usr.bin/xlint/lint1/lex.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/xlint/lint1/cgram.y diff -u src/usr.bin/xlint/lint1/cgram.y:1.386 src/usr.bin/xlint/lint1/cgram.y:1.387 --- src/usr.bin/xlint/lint1/cgram.y:1.386 Sun Feb 27 19:32:51 2022 +++ src/usr.bin/xlint/lint1/cgram.y Tue Mar 1 00:17:12 2022 @@ -1,5 +1,5 @@ %{ -/* $NetBSD: cgram.y,v 1.386 2022/02/27 19:32:51 rillig Exp $ */ +/* $NetBSD: cgram.y,v 1.387 2022/03/01 00:17:12 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -35,7 +35,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: cgram.y,v 1.386 2022/02/27 19:32:51 rillig Exp $"); +__RCSID("$NetBSD: cgram.y,v 1.387 2022/03/01 00:17:12 rillig Exp $"); #endif #include <limits.h> @@ -2162,9 +2162,6 @@ yyerror(const char *msg) static const char * cgram_to_string(int token, YYSTYPE val) { - static const char *tqual_name[] = { - "const", "volatile", "restrict", "_Thread_local" - }; switch (token) { case T_INCDEC: @@ -2181,7 +2178,7 @@ cgram_to_string(int token, YYSTYPE val) case T_STRUCT_OR_UNION: return tspec_name(val.y_tspec); case T_QUAL: - return tqual_name[val.y_tqual]; + return tqual_name(val.y_tqual); case T_NAME: return val.y_name->sb_name; default: Index: src/usr.bin/xlint/lint1/debug.c diff -u src/usr.bin/xlint/lint1/debug.c:1.8 src/usr.bin/xlint/lint1/debug.c:1.9 --- src/usr.bin/xlint/lint1/debug.c:1.8 Sun Feb 27 18:29:14 2022 +++ src/usr.bin/xlint/lint1/debug.c Tue Mar 1 00:17:12 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: debug.c,v 1.8 2022/02/27 18:29:14 rillig Exp $ */ +/* $NetBSD: debug.c,v 1.9 2022/03/01 00:17:12 rillig Exp $ */ /*- * Copyright (c) 2021 The NetBSD Foundation, Inc. @@ -35,12 +35,13 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: debug.c,v 1.8 2022/02/27 18:29:14 rillig Exp $"); +__RCSID("$NetBSD: debug.c,v 1.9 2022/03/01 00:17:12 rillig Exp $"); #endif #include <stdlib.h> #include "lint1.h" +#include "cgram.h" #ifdef DEBUG @@ -129,9 +130,11 @@ debug_node(const tnode_t *tn) else if (op == CON && is_floating(tn->tn_type->t_tspec)) debug_printf(", value %Lg", tn->tn_val->v_ldbl); else if (op == CON && is_uinteger(tn->tn_type->t_tspec)) - debug_printf(", value %llu\n", (unsigned long long)tn->tn_val->v_quad); + debug_printf(", value %llu\n", + (unsigned long long)tn->tn_val->v_quad); else if (op == CON && is_integer(tn->tn_type->t_tspec)) - debug_printf(", value %lld\n", (long long)tn->tn_val->v_quad); + debug_printf(", value %lld\n", + (long long)tn->tn_val->v_quad); else if (op == CON && tn->tn_type->t_tspec == BOOL) debug_printf(", value %s\n", tn->tn_val->v_quad != 0 ? "true" : "false"); @@ -160,4 +163,138 @@ debug_node(const tnode_t *tn) } } +static const char * +def_name(def_t def) +{ + static const char *const name[] = { + "not-declared", + "declared", + "tentative-defined", + "defined", + }; + + return name[def]; +} + +const char * +scl_name(scl_t scl) +{ + static const char *const name[] = { + "none", + "extern", + "static", + "auto", + "register", + "typedef", + "struct", + "union", + "enum", + "member-of-struct", + "member-of-union", + "compile-time-constant", + "abstract", + "old-style-function-argument", + "prototype-argument", + "inline", + }; + + return name[scl]; +} + +const char * +symt_name(symt_t kind) +{ + static const char *const name[] = { + "var-func-type", + "member", + "tag", + "label", + }; + + return name[kind]; +} + +const char * +tqual_name(tqual_t qual) +{ + static const char *const name[] = { + "const", + "volatile", + "restrict", + "_Thread_local", + }; + + return name[qual]; +} + +static void +debug_word(bool flag, const char *name) +{ + + if (flag) + debug_printf(" %s", name); +} + +void +debug_sym(const sym_t *sym) +{ + + debug_print_indent(); + debug_printf("%s", sym->s_name); + if (sym->s_type != NULL) + debug_printf(" type='%s'", type_name(sym->s_type)); + if (sym->s_rename != NULL) + debug_printf(" rename=%s", sym->s_rename); + debug_printf(" %s", symt_name(sym->s_kind)); + debug_word(sym->s_keyword != NULL, "keyword"); + debug_word(sym->s_bitfield, "bit-field"); + debug_word(sym->s_set, "set"); + debug_word(sym->s_used, "used"); + debug_word(sym->s_arg, "argument"); + debug_word(sym->s_register, "register"); + debug_word(sym->s_defarg, "old-style-undefined"); + debug_word(sym->s_return_type_implicit_int, "return-int"); + debug_word(sym->s_osdef, "old-style"); + debug_word(sym->s_inline, "inline"); + debug_word(sym->s_ext_sym != NULL, "has-external"); + debug_word(sym->s_scl != NOSCL, scl_name(sym->s_scl)); + debug_word(sym->s_keyword == NULL, def_name(sym->s_def)); + + if (sym->s_def_pos.p_file != NULL) + debug_printf(" defined-at=%s:%d", + sym->s_def_pos.p_file, sym->s_def_pos.p_line); + if (sym->s_set_pos.p_file != NULL) + debug_printf(" set-at=%s:%d", + sym->s_set_pos.p_file, sym->s_set_pos.p_line); + if (sym->s_use_pos.p_file != NULL) + debug_printf(" used-at=%s:%d", + sym->s_use_pos.p_file, sym->s_use_pos.p_line); + + if (sym->s_type != NULL && + (sym->s_type->t_is_enum || sym->s_type->t_tspec == BOOL)) + debug_printf(" value=%d", (int)sym->s_value.v_quad); + + if ((sym->s_scl == MOS || sym->s_scl == MOU) && + sym->s_sou_type != NULL) { + const char *tag = sym->s_sou_type->sou_tag->s_name; + const sym_t *def = sym->s_sou_type->sou_first_typedef; + if (tag == unnamed && def != NULL) + debug_printf(" sou='typedef %s'", def->s_name); + else + debug_printf(" sou=%s", tag); + } + + if (sym->s_keyword != NULL) { + int t = (int)sym->s_value.v_quad; + if (t == T_TYPE || t == T_STRUCT_OR_UNION) + debug_printf(" %s", tspec_name(sym->s_tspec)); + else if (t == T_QUAL) + debug_printf(" %s", tqual_name(sym->s_tqual)); + } + + debug_word(sym->s_osdef && sym->s_args != NULL, "old-style-args"); + + debug_printf("\n"); +} + #endif Index: src/usr.bin/xlint/lint1/decl.c diff -u src/usr.bin/xlint/lint1/decl.c:1.251 src/usr.bin/xlint/lint1/decl.c:1.252 --- src/usr.bin/xlint/lint1/decl.c:1.251 Sun Feb 27 20:02:43 2022 +++ src/usr.bin/xlint/lint1/decl.c Tue Mar 1 00:17:12 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: decl.c,v 1.251 2022/02/27 20:02:43 rillig Exp $ */ +/* $NetBSD: decl.c,v 1.252 2022/03/01 00:17:12 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -38,7 +38,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: decl.c,v 1.251 2022/02/27 20:02:43 rillig Exp $"); +__RCSID("$NetBSD: decl.c,v 1.252 2022/03/01 00:17:12 rillig Exp $"); #endif #include <sys/param.h> @@ -140,22 +140,6 @@ initdecl(void) typetab[LCOMPLEX].t_tspec = LCOMPLEX; } -#ifdef DEBUG -/* Return the name of the "storage class" in the wider sense. */ -const char * -scl_name(scl_t scl) -{ - static const char *const names[] = { - "none", "extern", "static", "auto", "register", "typedef", - "struct", "union", "enum", "member of struct", "member of union", - "compile-time constant", "abstract", - "old-style function argument", "prototype argument", "inline" - }; - - return names[scl]; -} -#endif - /* * Returns a shared type structure for arithmetic types and void. * @@ -1946,7 +1930,7 @@ declare_extern(sym_t *dsym, bool initflg /* * If the old symbol stems from an old style function - * definition, we have remembered the params in rdsmy->s_args + * definition, we have remembered the params in rdsym->s_args * and compare them with the params of the prototype. */ if (rdsym->s_osdef && dsym->s_type->t_proto) { Index: src/usr.bin/xlint/lint1/externs1.h diff -u src/usr.bin/xlint/lint1/externs1.h:1.148 src/usr.bin/xlint/lint1/externs1.h:1.149 --- src/usr.bin/xlint/lint1/externs1.h:1.148 Sun Feb 27 10:31:58 2022 +++ src/usr.bin/xlint/lint1/externs1.h Tue Mar 1 00:17:12 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: externs1.h,v 1.148 2022/02/27 10:31:58 rillig Exp $ */ +/* $NetBSD: externs1.h,v 1.149 2022/03/01 00:17:12 rillig Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -115,7 +115,12 @@ extern void expr_restore_memory(struct m */ #ifdef DEBUG +const char *scl_name(scl_t); +const char *symt_name(symt_t); +const char *tqual_name(tqual_t); void debug_node(const tnode_t *); +void debug_sym(const sym_t *); +void debug_symtab(void); void debug_printf(const char *fmt, ...) __printflike(1, 2); void debug_print_indent(void); void debug_indent_inc(void); @@ -223,7 +228,6 @@ extern void check_usage_sym(bool, sym_t extern void check_global_symbols(void); extern void print_previous_declaration(int, const sym_t *); extern int to_int_constant(tnode_t *, bool); -extern const char *scl_name(scl_t); /* * tree.c Index: src/usr.bin/xlint/lint1/lex.c diff -u src/usr.bin/xlint/lint1/lex.c:1.106 src/usr.bin/xlint/lint1/lex.c:1.107 --- src/usr.bin/xlint/lint1/lex.c:1.106 Mon Feb 28 22:41:07 2022 +++ src/usr.bin/xlint/lint1/lex.c Tue Mar 1 00:17:12 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: lex.c,v 1.106 2022/02/28 22:41:07 rillig Exp $ */ +/* $NetBSD: lex.c,v 1.107 2022/03/01 00:17:12 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -38,7 +38,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: lex.c,v 1.106 2022/02/28 22:41:07 rillig Exp $"); +__RCSID("$NetBSD: lex.c,v 1.107 2022/03/01 00:17:12 rillig Exp $"); #endif #include <ctype.h> @@ -307,6 +307,71 @@ symtab_remove_locals(void) } } +#ifdef DEBUG +static int +sym_by_name(const void *va, const void *vb) +{ + const sym_t *a = *(const sym_t *const *)va; + const sym_t *b = *(const sym_t *const *)vb; + + return strcmp(a->s_name, b->s_name); +} + +struct syms { + const sym_t **items; + size_t len; + size_t cap; +}; + +static void +syms_add(struct syms *syms, const sym_t *sym) +{ + while (syms->len + 1 >= syms->cap) { + syms->cap *= 2; + syms->items = xrealloc(syms->items, + syms->cap * sizeof(syms->items[0])); + } + syms->items[syms->len++] = sym; +} + +void +debug_symtab(void) +{ + struct syms syms = { xcalloc(64, sizeof(syms.items[0])), 0, 64 }; + + for (int level = 0;; level++) { + debug_printf("symbol table level %d\n", level); + + bool more = false; + size_t n = sizeof(symtab) / sizeof(symtab[0]); + + syms.len = 0; + for (size_t i = 0; i < n; i++) { + for (sym_t *sym = symtab[i]; sym != NULL;) { + if (sym->s_block_level == level && + sym->s_keyword == NULL) + syms_add(&syms, sym); + if (sym->s_block_level > level) + more = true; + sym = sym->s_symtab_next; + } + } + + debug_indent_inc(); + qsort(syms.items, syms.len, sizeof(syms.items[0]), + sym_by_name); + for (size_t i = 0; i < syms.len; i++) + debug_sym(syms.items[i]); + debug_indent_dec(); + + if (!more) + break; + } + + free(syms.items); +} +#endif + static void add_keyword(const struct keyword *kw, bool leading, bool trailing) { @@ -1301,20 +1366,6 @@ lex_unknown_character(int c) error(250, c); } -#ifdef DEBUG -static const char * -symt_name(symt_t kind) -{ - static const char *name[] = { - "var-func-type", - "member", - "tag", - "label", - }; - return name[kind]; -} -#endif - /* * As noted above, the scanner does not create new symbol table entries * for symbols it cannot find in the symbol table. This is to avoid