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