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

Reply via email to