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.diff -r1.386 -r1.387 src/usr.bin/xlint/lint1/cgram.y
(rillig)
--- src/usr.bin/xlint/lint1/cgram.y 2022/02/27 19:32:51 1.386
+++ src/usr.bin/xlint/lint1/cgram.y 2022/03/01 00:17:12 1.387
@@ -1,15 +1,15 @@ | @@ -1,15 +1,15 @@ | |||
1 | %{ | 1 | %{ | |
2 | /* $NetBSD: cgram.y,v 1.386 2022/02/27 19:32:51 rillig Exp $ */ | 2 | /* $NetBSD: cgram.y,v 1.387 2022/03/01 00:17:12 rillig Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. | 5 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. | |
6 | * Copyright (c) 1994, 1995 Jochen Pohl | 6 | * Copyright (c) 1994, 1995 Jochen Pohl | |
7 | * All Rights Reserved. | 7 | * All Rights Reserved. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
15 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the | |
@@ -25,27 +25,27 @@ | @@ -25,27 +25,27 @@ | |||
25 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 25 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
26 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 26 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
27 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 27 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
29 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 29 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
34 | */ | 34 | */ | |
35 | 35 | |||
36 | #include <sys/cdefs.h> | 36 | #include <sys/cdefs.h> | |
37 | #if defined(__RCSID) && !defined(lint) | 37 | #if defined(__RCSID) && !defined(lint) | |
38 | __RCSID("$NetBSD: cgram.y,v 1.386 2022/02/27 19:32:51 rillig Exp $"); | 38 | __RCSID("$NetBSD: cgram.y,v 1.387 2022/03/01 00:17:12 rillig Exp $"); | |
39 | #endif | 39 | #endif | |
40 | 40 | |||
41 | #include <limits.h> | 41 | #include <limits.h> | |
42 | #include <stdlib.h> | 42 | #include <stdlib.h> | |
43 | #include <string.h> | 43 | #include <string.h> | |
44 | 44 | |||
45 | #include "lint1.h" | 45 | #include "lint1.h" | |
46 | 46 | |||
47 | extern char *yytext; | 47 | extern char *yytext; | |
48 | 48 | |||
49 | /* | 49 | /* | |
50 | * Contains the level of current declaration, used for symbol table entries. | 50 | * Contains the level of current declaration, used for symbol table entries. | |
51 | * 0 is the top-level, > 0 is inside a function body. | 51 | * 0 is the top-level, > 0 is inside a function body. | |
@@ -2152,46 +2152,43 @@ yyerror(const char *msg) | @@ -2152,46 +2152,43 @@ yyerror(const char *msg) | |||
2152 | { | 2152 | { | |
2153 | /* syntax error '%s' */ | 2153 | /* syntax error '%s' */ | |
2154 | error(249, yytext); | 2154 | error(249, yytext); | |
2155 | if (++sytxerr >= 5) | 2155 | if (++sytxerr >= 5) | |
2156 | norecover(); | 2156 | norecover(); | |
2157 | return 0; | 2157 | return 0; | |
2158 | } | 2158 | } | |
2159 | 2159 | |||
2160 | #if (defined(YYDEBUG) && YYDEBUG > 0 && defined(YYBYACC)) \ | 2160 | #if (defined(YYDEBUG) && YYDEBUG > 0 && defined(YYBYACC)) \ | |
2161 | || (defined(YYDEBUG) && defined(YYBISON)) | 2161 | || (defined(YYDEBUG) && defined(YYBISON)) | |
2162 | static const char * | 2162 | static const char * | |
2163 | cgram_to_string(int token, YYSTYPE val) | 2163 | cgram_to_string(int token, YYSTYPE val) | |
2164 | { | 2164 | { | |
2165 | static const char *tqual_name[] = { | |||
2166 | "const", "volatile", "restrict", "_Thread_local" | |||
2167 | }; | |||
2168 | 2165 | |||
2169 | switch (token) { | 2166 | switch (token) { | |
2170 | case T_INCDEC: | 2167 | case T_INCDEC: | |
2171 | case T_MULTIPLICATIVE: | 2168 | case T_MULTIPLICATIVE: | |
2172 | case T_ADDITIVE: | 2169 | case T_ADDITIVE: | |
2173 | case T_SHIFT: | 2170 | case T_SHIFT: | |
2174 | case T_RELATIONAL: | 2171 | case T_RELATIONAL: | |
2175 | case T_EQUALITY: | 2172 | case T_EQUALITY: | |
2176 | case T_OPASSIGN: | 2173 | case T_OPASSIGN: | |
2177 | return modtab[val.y_op].m_name; | 2174 | return modtab[val.y_op].m_name; | |
2178 | case T_SCLASS: | 2175 | case T_SCLASS: | |
2179 | return scl_name(val.y_scl); | 2176 | return scl_name(val.y_scl); | |
2180 | case T_TYPE: | 2177 | case T_TYPE: | |
2181 | case T_STRUCT_OR_UNION: | 2178 | case T_STRUCT_OR_UNION: | |
2182 | return tspec_name(val.y_tspec); | 2179 | return tspec_name(val.y_tspec); | |
2183 | case T_QUAL: | 2180 | case T_QUAL: | |
2184 | return tqual_name[val.y_tqual]; | 2181 | return tqual_name(val.y_tqual); | |
2185 | case T_NAME: | 2182 | case T_NAME: | |
2186 | return val.y_name->sb_name; | 2183 | return val.y_name->sb_name; | |
2187 | default: | 2184 | default: | |
2188 | return "<none>"; | 2185 | return "<none>"; | |
2189 | } | 2186 | } | |
2190 | } | 2187 | } | |
2191 | #endif | 2188 | #endif | |
2192 | 2189 | |||
2193 | #if defined(YYDEBUG) && defined(YYBISON) | 2190 | #if defined(YYDEBUG) && defined(YYBISON) | |
2194 | static inline void | 2191 | static inline void | |
2195 | cgram_print(FILE *output, int token, YYSTYPE val) | 2192 | cgram_print(FILE *output, int token, YYSTYPE val) | |
2196 | { | 2193 | { | |
2197 | (void)fprintf(output, "%s", cgram_to_string(token, val)); | 2194 | (void)fprintf(output, "%s", cgram_to_string(token, val)); |
--- src/usr.bin/xlint/lint1/debug.c 2022/02/27 18:29:14 1.8
+++ src/usr.bin/xlint/lint1/debug.c 2022/03/01 00:17:12 1.9
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: debug.c,v 1.8 2022/02/27 18:29:14 rillig Exp $ */ | 1 | /* $NetBSD: debug.c,v 1.9 2022/03/01 00:17:12 rillig Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2021 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2021 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Roland Illig <rillig@NetBSD.org>. | 8 | * by Roland Illig <rillig@NetBSD.org>. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -25,32 +25,33 @@ | @@ -25,32 +25,33 @@ | |||
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | #if HAVE_NBTOOL_CONFIG_H | 32 | #if HAVE_NBTOOL_CONFIG_H | |
33 | #include "nbtool_config.h" | 33 | #include "nbtool_config.h" | |
34 | #endif | 34 | #endif | |
35 | 35 | |||
36 | #include <sys/cdefs.h> | 36 | #include <sys/cdefs.h> | |
37 | #if defined(__RCSID) && !defined(lint) | 37 | #if defined(__RCSID) && !defined(lint) | |
38 | __RCSID("$NetBSD: debug.c,v 1.8 2022/02/27 18:29:14 rillig Exp $"); | 38 | __RCSID("$NetBSD: debug.c,v 1.9 2022/03/01 00:17:12 rillig Exp $"); | |
39 | #endif | 39 | #endif | |
40 | 40 | |||
41 | #include <stdlib.h> | 41 | #include <stdlib.h> | |
42 | 42 | |||
43 | #include "lint1.h" | 43 | #include "lint1.h" | |
44 | #include "cgram.h" | |||
44 | 45 | |||
45 | 46 | |||
46 | #ifdef DEBUG | 47 | #ifdef DEBUG | |
47 | 48 | |||
48 | static int debug_indentation = 0; | 49 | static int debug_indentation = 0; | |
49 | 50 | |||
50 | 51 | |||
51 | void __printflike(1, 2) | 52 | void __printflike(1, 2) | |
52 | debug_printf(const char *fmt, ...) | 53 | debug_printf(const char *fmt, ...) | |
53 | { | 54 | { | |
54 | va_list va; | 55 | va_list va; | |
55 | 56 | |||
56 | va_start(va, fmt); | 57 | va_start(va, fmt); | |
@@ -119,29 +120,31 @@ debug_node(const tnode_t *tn) | @@ -119,29 +120,31 @@ debug_node(const tnode_t *tn) | |||
119 | debug_print_indent(); | 120 | debug_print_indent(); | |
120 | debug_printf("'%s' with type '%s'%s%s%s", | 121 | debug_printf("'%s' with type '%s'%s%s%s", | |
121 | op == CVT && !tn->tn_cast ? "convert" : modtab[op].m_name, | 122 | op == CVT && !tn->tn_cast ? "convert" : modtab[op].m_name, | |
122 | type_name(tn->tn_type), tn->tn_lvalue ? ", lvalue" : "", | 123 | type_name(tn->tn_type), tn->tn_lvalue ? ", lvalue" : "", | |
123 | tn->tn_parenthesized ? ", parenthesized" : "", | 124 | tn->tn_parenthesized ? ", parenthesized" : "", | |
124 | tn->tn_sys ? ", sys" : ""); | 125 | tn->tn_sys ? ", sys" : ""); | |
125 | 126 | |||
126 | if (op == NAME) | 127 | if (op == NAME) | |
127 | debug_printf(" %s %s\n", tn->tn_sym->s_name, | 128 | debug_printf(" %s %s\n", tn->tn_sym->s_name, | |
128 | storage_class_name(tn->tn_sym->s_scl)); | 129 | storage_class_name(tn->tn_sym->s_scl)); | |
129 | else if (op == CON && is_floating(tn->tn_type->t_tspec)) | 130 | else if (op == CON && is_floating(tn->tn_type->t_tspec)) | |
130 | debug_printf(", value %Lg", tn->tn_val->v_ldbl); | 131 | debug_printf(", value %Lg", tn->tn_val->v_ldbl); | |
131 | else if (op == CON && is_uinteger(tn->tn_type->t_tspec)) | 132 | else if (op == CON && is_uinteger(tn->tn_type->t_tspec)) | |
132 | debug_printf(", value %llu\n", (unsigned long long)tn->tn_val->v_quad); | 133 | debug_printf(", value %llu\n", | |
134 | (unsigned long long)tn->tn_val->v_quad); | |||
133 | else if (op == CON && is_integer(tn->tn_type->t_tspec)) | 135 | else if (op == CON && is_integer(tn->tn_type->t_tspec)) | |
134 | debug_printf(", value %lld\n", (long long)tn->tn_val->v_quad); | 136 | debug_printf(", value %lld\n", | |
137 | (long long)tn->tn_val->v_quad); | |||
135 | else if (op == CON && tn->tn_type->t_tspec == BOOL) | 138 | else if (op == CON && tn->tn_type->t_tspec == BOOL) | |
136 | debug_printf(", value %s\n", | 139 | debug_printf(", value %s\n", | |
137 | tn->tn_val->v_quad != 0 ? "true" : "false"); | 140 | tn->tn_val->v_quad != 0 ? "true" : "false"); | |
138 | else if (op == CON) | 141 | else if (op == CON) | |
139 | debug_printf(", unknown value\n"); | 142 | debug_printf(", unknown value\n"); | |
140 | else if (op == STRING && tn->tn_string->st_char) | 143 | else if (op == STRING && tn->tn_string->st_char) | |
141 | debug_printf(", length %zu, \"%s\"\n", | 144 | debug_printf(", length %zu, \"%s\"\n", | |
142 | tn->tn_string->st_len, | 145 | tn->tn_string->st_len, | |
143 | (const char *)tn->tn_string->st_mem); | 146 | (const char *)tn->tn_string->st_mem); | |
144 | else if (op == STRING) { | 147 | else if (op == STRING) { | |
145 | size_t n = MB_CUR_MAX * (tn->tn_string->st_len + 1); | 148 | size_t n = MB_CUR_MAX * (tn->tn_string->st_len + 1); | |
146 | char *s = xmalloc(n); | 149 | char *s = xmalloc(n); | |
147 | (void)wcstombs(s, tn->tn_string->st_mem, n); | 150 | (void)wcstombs(s, tn->tn_string->st_mem, n); | |
@@ -150,14 +153,148 @@ debug_node(const tnode_t *tn) | @@ -150,14 +153,148 @@ debug_node(const tnode_t *tn) | |||
150 | free(s); | 153 | free(s); | |
151 | 154 | |||
152 | } else { | 155 | } else { | |
153 | debug_printf("\n"); | 156 | debug_printf("\n"); | |
154 | 157 | |||
155 | debug_indent_inc(); | 158 | debug_indent_inc(); | |
156 | debug_node(tn->tn_left); | 159 | debug_node(tn->tn_left); | |
157 | if (is_binary(tn) || tn->tn_right != NULL) | 160 | if (is_binary(tn) || tn->tn_right != NULL) | |
158 | debug_node(tn->tn_right); | 161 | debug_node(tn->tn_right); | |
159 | debug_indent_dec(); | 162 | debug_indent_dec(); | |
160 | } | 163 | } | |
161 | } | 164 | } | |
162 | 165 | |||
166 | static const char * | |||
167 | def_name(def_t def) | |||
168 | { | |||
169 | static const char *const name[] = { | |||
170 | "not-declared", | |||
171 | "declared", | |||
172 | "tentative-defined", | |||
173 | "defined", | |||
174 | }; | |||
175 | ||||
176 | return name[def]; | |||
177 | } | |||
178 | ||||
179 | const char * | |||
180 | scl_name(scl_t scl) | |||
181 | { | |||
182 | static const char *const name[] = { | |||
183 | "none", | |||
184 | "extern", | |||
185 | "static", | |||
186 | "auto", | |||
187 | "register", | |||
188 | "typedef", | |||
189 | "struct", | |||
190 | "union", | |||
191 | "enum", | |||
192 | "member-of-struct", | |||
193 | "member-of-union", | |||
194 | "compile-time-constant", | |||
195 | "abstract", | |||
196 | "old-style-function-argument", | |||
197 | "prototype-argument", | |||
198 | "inline", | |||
199 | }; | |||
200 | ||||
201 | return name[scl]; | |||
202 | } | |||
203 | ||||
204 | const char * | |||
205 | symt_name(symt_t kind) | |||
206 | { | |||
207 | static const char *const name[] = { | |||
208 | "var-func-type", | |||
209 | "member", | |||
210 | "tag", | |||
211 | "label", | |||
212 | }; | |||
213 | ||||
214 | return name[kind]; | |||
215 | } | |||
216 | ||||
217 | const char * | |||
218 | tqual_name(tqual_t qual) | |||
219 | { | |||
220 | static const char *const name[] = { | |||
221 | "const", | |||
222 | "volatile", | |||
223 | "restrict", | |||
224 | "_Thread_local", | |||
225 | }; | |||
226 | ||||
227 | return name[qual]; | |||
228 | } | |||
229 | ||||
230 | static void | |||
231 | debug_word(bool flag, const char *name) | |||
232 | { | |||
233 | ||||
234 | if (flag) | |||
235 | debug_printf(" %s", name); | |||
236 | } | |||
237 | ||||
238 | void | |||
239 | debug_sym(const sym_t *sym) | |||
240 | { | |||
241 | ||||
242 | debug_print_indent(); | |||
243 | debug_printf("%s", sym->s_name); | |||
244 | if (sym->s_type != NULL) | |||
245 | debug_printf(" type='%s'", type_name(sym->s_type)); | |||
246 | if (sym->s_rename != NULL) | |||
247 | debug_printf(" rename=%s", sym->s_rename); | |||
248 | debug_printf(" %s", symt_name(sym->s_kind)); | |||
249 | debug_word(sym->s_keyword != NULL, "keyword"); | |||
250 | debug_word(sym->s_bitfield, "bit-field"); | |||
251 | debug_word(sym->s_set, "set"); | |||
252 | debug_word(sym->s_used, "used"); | |||
253 | debug_word(sym->s_arg, "argument"); | |||
254 | debug_word(sym->s_register, "register"); | |||
255 | debug_word(sym->s_defarg, "old-style-undefined"); | |||
256 | debug_word(sym->s_return_type_implicit_int, "return-int"); | |||
257 | debug_word(sym->s_osdef, "old-style"); | |||
258 | debug_word(sym->s_inline, "inline"); | |||
259 | debug_word(sym->s_ext_sym != NULL, "has-external"); | |||
260 | debug_word(sym->s_scl != NOSCL, scl_name(sym->s_scl)); | |||
261 | debug_word(sym->s_keyword == NULL, def_name(sym->s_def)); | |||
262 | ||||
263 | if (sym->s_def_pos.p_file != NULL) | |||
264 | debug_printf(" defined-at=%s:%d", | |||
265 | sym->s_def_pos.p_file, sym->s_def_pos.p_line); | |||
266 | if (sym->s_set_pos.p_file != NULL) | |||
267 | debug_printf(" set-at=%s:%d", | |||
268 | sym->s_set_pos.p_file, sym->s_set_pos.p_line); | |||
269 | if (sym->s_use_pos.p_file != NULL) | |||
270 | debug_printf(" used-at=%s:%d", | |||
271 | sym->s_use_pos.p_file, sym->s_use_pos.p_line); | |||
272 | ||||
273 | if (sym->s_type != NULL && | |||
274 | (sym->s_type->t_is_enum || sym->s_type->t_tspec == BOOL)) | |||
275 | debug_printf(" value=%d", (int)sym->s_value.v_quad); | |||
276 | ||||
277 | if ((sym->s_scl == MOS || sym->s_scl == MOU) && | |||
278 | sym->s_sou_type != NULL) { | |||
279 | const char *tag = sym->s_sou_type->sou_tag->s_name; | |||
280 | const sym_t *def = sym->s_sou_type->sou_first_typedef; | |||
281 | if (tag == unnamed && def != NULL) | |||
282 | debug_printf(" sou='typedef %s'", def->s_name); | |||
283 | else | |||
284 | debug_printf(" sou=%s", tag); | |||
285 | } | |||
286 | ||||
287 | if (sym->s_keyword != NULL) { | |||
288 | int t = (int)sym->s_value.v_quad; | |||
289 | if (t == T_TYPE || t == T_STRUCT_OR_UNION) | |||
290 | debug_printf(" %s", tspec_name(sym->s_tspec)); | |||
291 | else if (t == T_QUAL) | |||
292 | debug_printf(" %s", tqual_name(sym->s_tqual)); | |||
293 | } | |||
294 | ||||
295 | debug_word(sym->s_osdef && sym->s_args != NULL, "old-style-args"); | |||
296 | ||||
297 | debug_printf("\n"); | |||
298 | } | |||
299 | ||||
163 | #endif | 300 | #endif |
--- src/usr.bin/xlint/lint1/decl.c 2022/02/27 20:02:43 1.251
+++ src/usr.bin/xlint/lint1/decl.c 2022/03/01 00:17:12 1.252
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: decl.c,v 1.251 2022/02/27 20:02:43 rillig Exp $ */ | 1 | /* $NetBSD: decl.c,v 1.252 2022/03/01 00:17:12 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. | 4 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. | |
5 | * Copyright (c) 1994, 1995 Jochen Pohl | 5 | * Copyright (c) 1994, 1995 Jochen Pohl | |
6 | * All Rights Reserved. | 6 | * All Rights Reserved. | |
7 | * | 7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | 10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | 11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | 12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | 13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | 14 | * notice, this list of conditions and the following disclaimer in the | |
@@ -28,27 +28,27 @@ | @@ -28,27 +28,27 @@ | |||
28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
33 | */ | 33 | */ | |
34 | 34 | |||
35 | #if HAVE_NBTOOL_CONFIG_H | 35 | #if HAVE_NBTOOL_CONFIG_H | |
36 | #include "nbtool_config.h" | 36 | #include "nbtool_config.h" | |
37 | #endif | 37 | #endif | |
38 | 38 | |||
39 | #include <sys/cdefs.h> | 39 | #include <sys/cdefs.h> | |
40 | #if defined(__RCSID) && !defined(lint) | 40 | #if defined(__RCSID) && !defined(lint) | |
41 | __RCSID("$NetBSD: decl.c,v 1.251 2022/02/27 20:02:43 rillig Exp $"); | 41 | __RCSID("$NetBSD: decl.c,v 1.252 2022/03/01 00:17:12 rillig Exp $"); | |
42 | #endif | 42 | #endif | |
43 | 43 | |||
44 | #include <sys/param.h> | 44 | #include <sys/param.h> | |
45 | #include <limits.h> | 45 | #include <limits.h> | |
46 | #include <stdlib.h> | 46 | #include <stdlib.h> | |
47 | #include <string.h> | 47 | #include <string.h> | |
48 | 48 | |||
49 | #include "lint1.h" | 49 | #include "lint1.h" | |
50 | 50 | |||
51 | const char *unnamed = "<unnamed>"; | 51 | const char *unnamed = "<unnamed>"; | |
52 | 52 | |||
53 | /* shared type structures for arithmetic types and void */ | 53 | /* shared type structures for arithmetic types and void */ | |
54 | static type_t *typetab; | 54 | static type_t *typetab; | |
@@ -130,42 +130,26 @@ initdecl(void) | @@ -130,42 +130,26 @@ initdecl(void) | |||
130 | typetab[UINT128].t_tspec = UINT128; | 130 | typetab[UINT128].t_tspec = UINT128; | |
131 | #endif | 131 | #endif | |
132 | typetab[FLOAT].t_tspec = FLOAT; | 132 | typetab[FLOAT].t_tspec = FLOAT; | |
133 | typetab[DOUBLE].t_tspec = DOUBLE; | 133 | typetab[DOUBLE].t_tspec = DOUBLE; | |
134 | typetab[LDOUBLE].t_tspec = LDOUBLE; | 134 | typetab[LDOUBLE].t_tspec = LDOUBLE; | |
135 | typetab[VOID].t_tspec = VOID; | 135 | typetab[VOID].t_tspec = VOID; | |
136 | /* struct, union, enum, ptr, array and func are not shared. */ | 136 | /* struct, union, enum, ptr, array and func are not shared. */ | |
137 | typetab[COMPLEX].t_tspec = COMPLEX; | 137 | typetab[COMPLEX].t_tspec = COMPLEX; | |
138 | typetab[FCOMPLEX].t_tspec = FCOMPLEX; | 138 | typetab[FCOMPLEX].t_tspec = FCOMPLEX; | |
139 | typetab[DCOMPLEX].t_tspec = DCOMPLEX; | 139 | typetab[DCOMPLEX].t_tspec = DCOMPLEX; | |
140 | typetab[LCOMPLEX].t_tspec = LCOMPLEX; | 140 | typetab[LCOMPLEX].t_tspec = LCOMPLEX; | |
141 | } | 141 | } | |
142 | 142 | |||
143 | #ifdef DEBUG | |||
144 | /* Return the name of the "storage class" in the wider sense. */ | |||
145 | const char * | |||
146 | scl_name(scl_t scl) | |||
147 | { | |||
148 | static const char *const names[] = { | |||
149 | "none", "extern", "static", "auto", "register", "typedef", | |||
150 | "struct", "union", "enum", "member of struct", "member of union", | |||
151 | "compile-time constant", "abstract", | |||
152 | "old-style function argument", "prototype argument", "inline" | |||
153 | }; | |||
154 | ||||
155 | return names[scl]; | |||
156 | } | |||
157 | #endif | |||
158 | ||||
159 | /* | 143 | /* | |
160 | * Returns a shared type structure for arithmetic types and void. | 144 | * Returns a shared type structure for arithmetic types and void. | |
161 | * | 145 | * | |
162 | * It's important to duplicate this structure using block_dup_type or | 146 | * It's important to duplicate this structure using block_dup_type or | |
163 | * expr_dup_type if it is to be modified (adding qualifiers or anything | 147 | * expr_dup_type if it is to be modified (adding qualifiers or anything | |
164 | * else). | 148 | * else). | |
165 | */ | 149 | */ | |
166 | type_t * | 150 | type_t * | |
167 | gettyp(tspec_t t) | 151 | gettyp(tspec_t t) | |
168 | { | 152 | { | |
169 | 153 | |||
170 | /* TODO: make the return type 'const' */ | 154 | /* TODO: make the return type 'const' */ | |
171 | return &typetab[t]; | 155 | return &typetab[t]; | |
@@ -1936,27 +1920,27 @@ declare_extern(sym_t *dsym, bool initflg | @@ -1936,27 +1920,27 @@ declare_extern(sym_t *dsym, bool initflg | |||
1936 | * With both LINTLIBRARY and PROTOLIB the prototype is | 1920 | * With both LINTLIBRARY and PROTOLIB the prototype is | |
1937 | * written as a function definition to the output file. | 1921 | * written as a function definition to the output file. | |
1938 | */ | 1922 | */ | |
1939 | rval = dsym->s_type->t_subt->t_tspec != VOID; | 1923 | rval = dsym->s_type->t_subt->t_tspec != VOID; | |
1940 | outfdef(dsym, &dsym->s_def_pos, rval, false, NULL); | 1924 | outfdef(dsym, &dsym->s_def_pos, rval, false, NULL); | |
1941 | } else if (!is_compiler_builtin(dsym->s_name)) { | 1925 | } else if (!is_compiler_builtin(dsym->s_name)) { | |
1942 | outsym(dsym, dsym->s_scl, dsym->s_def); | 1926 | outsym(dsym, dsym->s_scl, dsym->s_def); | |
1943 | } | 1927 | } | |
1944 | 1928 | |||
1945 | if ((rdsym = dcs->d_redeclared_symbol) != NULL) { | 1929 | if ((rdsym = dcs->d_redeclared_symbol) != NULL) { | |
1946 | 1930 | |||
1947 | /* | 1931 | /* | |
1948 | * If the old symbol stems from an old style function | 1932 | * If the old symbol stems from an old style function | |
1949 | * definition, we have remembered the params in rdsmy->s_args | 1933 | * definition, we have remembered the params in rdsym->s_args | |
1950 | * and compare them with the params of the prototype. | 1934 | * and compare them with the params of the prototype. | |
1951 | */ | 1935 | */ | |
1952 | if (rdsym->s_osdef && dsym->s_type->t_proto) { | 1936 | if (rdsym->s_osdef && dsym->s_type->t_proto) { | |
1953 | redec = check_old_style_definition(rdsym, dsym); | 1937 | redec = check_old_style_definition(rdsym, dsym); | |
1954 | } else { | 1938 | } else { | |
1955 | redec = false; | 1939 | redec = false; | |
1956 | } | 1940 | } | |
1957 | 1941 | |||
1958 | if (!redec && | 1942 | if (!redec && | |
1959 | !check_redeclaration(dsym, (dowarn = false, &dowarn))) { | 1943 | !check_redeclaration(dsym, (dowarn = false, &dowarn))) { | |
1960 | 1944 | |||
1961 | if (dowarn) { | 1945 | if (dowarn) { | |
1962 | if (sflag) | 1946 | if (sflag) |
--- src/usr.bin/xlint/lint1/externs1.h 2022/02/27 10:31:58 1.148
+++ src/usr.bin/xlint/lint1/externs1.h 2022/03/01 00:17:12 1.149
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: externs1.h,v 1.148 2022/02/27 10:31:58 rillig Exp $ */ | 1 | /* $NetBSD: externs1.h,v 1.149 2022/03/01 00:17:12 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1994, 1995 Jochen Pohl | 4 | * Copyright (c) 1994, 1995 Jochen Pohl | |
5 | * All Rights Reserved. | 5 | * All Rights Reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -105,27 +105,32 @@ extern void *level_zero_alloc(size_t, si | @@ -105,27 +105,32 @@ extern void *level_zero_alloc(size_t, si | |||
105 | extern void level_free_all(size_t); | 105 | extern void level_free_all(size_t); | |
106 | 106 | |||
107 | extern void *expr_zero_alloc(size_t); | 107 | extern void *expr_zero_alloc(size_t); | |
108 | extern tnode_t *expr_alloc_tnode(void); | 108 | extern tnode_t *expr_alloc_tnode(void); | |
109 | extern void expr_free_all(void); | 109 | extern void expr_free_all(void); | |
110 | extern struct memory_block *expr_save_memory(void); | 110 | extern struct memory_block *expr_save_memory(void); | |
111 | extern void expr_restore_memory(struct memory_block *); | 111 | extern void expr_restore_memory(struct memory_block *); | |
112 | 112 | |||
113 | /* | 113 | /* | |
114 | * debug.c | 114 | * debug.c | |
115 | */ | 115 | */ | |
116 | 116 | |||
117 | #ifdef DEBUG | 117 | #ifdef DEBUG | |
118 | const char *scl_name(scl_t); | |||
119 | const char *symt_name(symt_t); | |||
120 | const char *tqual_name(tqual_t); | |||
118 | void debug_node(const tnode_t *); | 121 | void debug_node(const tnode_t *); | |
122 | void debug_sym(const sym_t *); | |||
123 | void debug_symtab(void); | |||
119 | void debug_printf(const char *fmt, ...) __printflike(1, 2); | 124 | void debug_printf(const char *fmt, ...) __printflike(1, 2); | |
120 | void debug_print_indent(void); | 125 | void debug_print_indent(void); | |
121 | void debug_indent_inc(void); | 126 | void debug_indent_inc(void); | |
122 | void debug_indent_dec(void); | 127 | void debug_indent_dec(void); | |
123 | void debug_enter(const char *); | 128 | void debug_enter(const char *); | |
124 | void debug_step(const char *fmt, ...) __printflike(1, 2); | 129 | void debug_step(const char *fmt, ...) __printflike(1, 2); | |
125 | void debug_leave(const char *); | 130 | void debug_leave(const char *); | |
126 | #define debug_enter() (debug_enter)(__func__) | 131 | #define debug_enter() (debug_enter)(__func__) | |
127 | #define debug_leave() (debug_leave)(__func__) | 132 | #define debug_leave() (debug_leave)(__func__) | |
128 | #else | 133 | #else | |
129 | #define debug_noop() do { } while (false) | 134 | #define debug_noop() do { } while (false) | |
130 | #define debug_node(tn) debug_noop() | 135 | #define debug_node(tn) debug_noop() | |
131 | #define debug_printf(...) debug_noop() | 136 | #define debug_printf(...) debug_noop() | |
@@ -213,27 +218,26 @@ extern void check_func_old_style_argumen | @@ -213,27 +218,26 @@ extern void check_func_old_style_argumen | |||
213 | 218 | |||
214 | extern void declare_local(sym_t *, bool); | 219 | extern void declare_local(sym_t *, bool); | |
215 | extern sym_t *abstract_name(void); | 220 | extern sym_t *abstract_name(void); | |
216 | extern void global_clean_up(void); | 221 | extern void global_clean_up(void); | |
217 | extern sym_t *declare_1_abstract(sym_t *); | 222 | extern sym_t *declare_1_abstract(sym_t *); | |
218 | extern void check_size(sym_t *); | 223 | extern void check_size(sym_t *); | |
219 | extern void mark_as_set(sym_t *); | 224 | extern void mark_as_set(sym_t *); | |
220 | extern void mark_as_used(sym_t *, bool, bool); | 225 | extern void mark_as_used(sym_t *, bool, bool); | |
221 | extern void check_usage(dinfo_t *); | 226 | extern void check_usage(dinfo_t *); | |
222 | extern void check_usage_sym(bool, sym_t *); | 227 | extern void check_usage_sym(bool, sym_t *); | |
223 | extern void check_global_symbols(void); | 228 | extern void check_global_symbols(void); | |
224 | extern void print_previous_declaration(int, const sym_t *); | 229 | extern void print_previous_declaration(int, const sym_t *); | |
225 | extern int to_int_constant(tnode_t *, bool); | 230 | extern int to_int_constant(tnode_t *, bool); | |
226 | extern const char *scl_name(scl_t); | |||
227 | 231 | |||
228 | /* | 232 | /* | |
229 | * tree.c | 233 | * tree.c | |
230 | */ | 234 | */ | |
231 | extern const tnode_t *before_conversion(const tnode_t *); | 235 | extern const tnode_t *before_conversion(const tnode_t *); | |
232 | extern type_t *block_derive_type(type_t *, tspec_t); | 236 | extern type_t *block_derive_type(type_t *, tspec_t); | |
233 | extern type_t *expr_derive_type(type_t *, tspec_t); | 237 | extern type_t *expr_derive_type(type_t *, tspec_t); | |
234 | extern bool is_compiler_builtin(const char *); | 238 | extern bool is_compiler_builtin(const char *); | |
235 | extern tnode_t *build_constant(type_t *, val_t *); | 239 | extern tnode_t *build_constant(type_t *, val_t *); | |
236 | extern tnode_t *build_name(sym_t *, bool); | 240 | extern tnode_t *build_name(sym_t *, bool); | |
237 | extern tnode_t *build_string(strg_t *); | 241 | extern tnode_t *build_string(strg_t *); | |
238 | extern tnode_t *build_generic_selection(const tnode_t *, | 242 | extern tnode_t *build_generic_selection(const tnode_t *, | |
239 | struct generic_association *); | 243 | struct generic_association *); |
--- src/usr.bin/xlint/lint1/lex.c 2022/02/28 22:41:07 1.106
+++ src/usr.bin/xlint/lint1/lex.c 2022/03/01 00:17:12 1.107
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: lex.c,v 1.106 2022/02/28 22:41:07 rillig Exp $ */ | 1 | /* $NetBSD: lex.c,v 1.107 2022/03/01 00:17:12 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. | 4 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. | |
5 | * Copyright (c) 1994, 1995 Jochen Pohl | 5 | * Copyright (c) 1994, 1995 Jochen Pohl | |
6 | * All Rights Reserved. | 6 | * All Rights Reserved. | |
7 | * | 7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | 10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | 11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | 12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | 13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | 14 | * notice, this list of conditions and the following disclaimer in the | |
@@ -28,27 +28,27 @@ | @@ -28,27 +28,27 @@ | |||
28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
33 | */ | 33 | */ | |
34 | 34 | |||
35 | #if HAVE_NBTOOL_CONFIG_H | 35 | #if HAVE_NBTOOL_CONFIG_H | |
36 | #include "nbtool_config.h" | 36 | #include "nbtool_config.h" | |
37 | #endif | 37 | #endif | |
38 | 38 | |||
39 | #include <sys/cdefs.h> | 39 | #include <sys/cdefs.h> | |
40 | #if defined(__RCSID) && !defined(lint) | 40 | #if defined(__RCSID) && !defined(lint) | |
41 | __RCSID("$NetBSD: lex.c,v 1.106 2022/02/28 22:41:07 rillig Exp $"); | 41 | __RCSID("$NetBSD: lex.c,v 1.107 2022/03/01 00:17:12 rillig Exp $"); | |
42 | #endif | 42 | #endif | |
43 | 43 | |||
44 | #include <ctype.h> | 44 | #include <ctype.h> | |
45 | #include <errno.h> | 45 | #include <errno.h> | |
46 | #include <float.h> | 46 | #include <float.h> | |
47 | #include <limits.h> | 47 | #include <limits.h> | |
48 | #include <math.h> | 48 | #include <math.h> | |
49 | #include <stdlib.h> | 49 | #include <stdlib.h> | |
50 | #include <string.h> | 50 | #include <string.h> | |
51 | 51 | |||
52 | #include "lint1.h" | 52 | #include "lint1.h" | |
53 | #include "cgram.h" | 53 | #include "cgram.h" | |
54 | 54 | |||
@@ -297,26 +297,91 @@ static void | @@ -297,26 +297,91 @@ static void | |||
297 | symtab_remove_locals(void) | 297 | symtab_remove_locals(void) | |
298 | { | 298 | { | |
299 | 299 | |||
300 | for (size_t i = 0; i < HSHSIZ1; i++) { | 300 | for (size_t i = 0; i < HSHSIZ1; i++) { | |
301 | for (sym_t *sym = symtab[i]; sym != NULL; ) { | 301 | for (sym_t *sym = symtab[i]; sym != NULL; ) { | |
302 | sym_t *next = sym->s_symtab_next; | 302 | sym_t *next = sym->s_symtab_next; | |
303 | if (sym->s_block_level >= 1) | 303 | if (sym->s_block_level >= 1) | |
304 | symtab_remove(sym); | 304 | symtab_remove(sym); | |
305 | sym = next; | 305 | sym = next; | |
306 | } | 306 | } | |
307 | } | 307 | } | |
308 | } | 308 | } | |
309 | 309 | |||
310 | #ifdef DEBUG | |||
311 | static int | |||
312 | sym_by_name(const void *va, const void *vb) | |||
313 | { | |||
314 | const sym_t *a = *(const sym_t *const *)va; | |||
315 | const sym_t *b = *(const sym_t *const *)vb; | |||
316 | ||||
317 | return strcmp(a->s_name, b->s_name); | |||
318 | } | |||
319 | ||||
320 | struct syms { | |||
321 | const sym_t **items; | |||
322 | size_t len; | |||
323 | size_t cap; | |||
324 | }; | |||
325 | ||||
326 | static void | |||
327 | syms_add(struct syms *syms, const sym_t *sym) | |||
328 | { | |||
329 | while (syms->len + 1 >= syms->cap) { | |||
330 | syms->cap *= 2; | |||
331 | syms->items = xrealloc(syms->items, | |||
332 | syms->cap * sizeof(syms->items[0])); | |||
333 | } | |||
334 | syms->items[syms->len++] = sym; | |||
335 | } | |||
336 | ||||
337 | void | |||
338 | debug_symtab(void) | |||
339 | { | |||
340 | struct syms syms = { xcalloc(64, sizeof(syms.items[0])), 0, 64 }; | |||
341 | ||||
342 | for (int level = 0;; level++) { | |||
343 | debug_printf("symbol table level %d\n", level); | |||
344 | ||||
345 | bool more = false; | |||
346 | size_t n = sizeof(symtab) / sizeof(symtab[0]); | |||
347 | ||||
348 | syms.len = 0; | |||
349 | for (size_t i = 0; i < n; i++) { | |||
350 | for (sym_t *sym = symtab[i]; sym != NULL;) { | |||
351 | if (sym->s_block_level == level && | |||
352 | sym->s_keyword == NULL) | |||
353 | syms_add(&syms, sym); | |||
354 | if (sym->s_block_level > level) | |||
355 | more = true; | |||
356 | sym = sym->s_symtab_next; | |||
357 | } | |||
358 | } | |||
359 | ||||
360 | debug_indent_inc(); | |||
361 | qsort(syms.items, syms.len, sizeof(syms.items[0]), | |||
362 | sym_by_name); | |||
363 | for (size_t i = 0; i < syms.len; i++) | |||
364 | debug_sym(syms.items[i]); | |||
365 | debug_indent_dec(); | |||
366 | ||||
367 | if (!more) | |||
368 | break; | |||
369 | } | |||
370 | ||||
371 | free(syms.items); | |||
372 | } | |||
373 | #endif | |||
374 | ||||
310 | static void | 375 | static void | |
311 | add_keyword(const struct keyword *kw, bool leading, bool trailing) | 376 | add_keyword(const struct keyword *kw, bool leading, bool trailing) | |
312 | { | 377 | { | |
313 | sym_t *sym; | 378 | sym_t *sym; | |
314 | char buf[256]; | 379 | char buf[256]; | |
315 | const char *name; | 380 | const char *name; | |
316 | 381 | |||
317 | if (!leading && !trailing) { | 382 | if (!leading && !trailing) { | |
318 | name = kw->kw_name; | 383 | name = kw->kw_name; | |
319 | } else { | 384 | } else { | |
320 | (void)snprintf(buf, sizeof(buf), "%s%s%s", | 385 | (void)snprintf(buf, sizeof(buf), "%s%s%s", | |
321 | leading ? "__" : "", kw->kw_name, trailing ? "__" : ""); | 386 | leading ? "__" : "", kw->kw_name, trailing ? "__" : ""); | |
322 | name = xstrdup(buf); | 387 | name = xstrdup(buf); | |
@@ -1291,40 +1356,26 @@ lex_next_line(void) | @@ -1291,40 +1356,26 @@ lex_next_line(void) | |||
1291 | csrc_pos.p_line++; | 1356 | csrc_pos.p_line++; | |
1292 | csrc_pos.p_uniq = 0; | 1357 | csrc_pos.p_uniq = 0; | |
1293 | } | 1358 | } | |
1294 | } | 1359 | } | |
1295 | 1360 | |||
1296 | void | 1361 | void | |
1297 | lex_unknown_character(int c) | 1362 | lex_unknown_character(int c) | |
1298 | { | 1363 | { | |
1299 | 1364 | |||
1300 | /* unknown character \%o */ | 1365 | /* unknown character \%o */ | |
1301 | error(250, c); | 1366 | error(250, c); | |
1302 | } | 1367 | } | |
1303 | 1368 | |||
1304 | #ifdef DEBUG | |||
1305 | static const char * | |||
1306 | symt_name(symt_t kind) | |||
1307 | { | |||
1308 | static const char *name[] = { | |||
1309 | "var-func-type", | |||
1310 | "member", | |||
1311 | "tag", | |||
1312 | "label", | |||
1313 | }; | |||
1314 | return name[kind]; | |||
1315 | } | |||
1316 | #endif | |||
1317 | ||||
1318 | /* | 1369 | /* | |
1319 | * As noted above, the scanner does not create new symbol table entries | 1370 | * As noted above, the scanner does not create new symbol table entries | |
1320 | * for symbols it cannot find in the symbol table. This is to avoid | 1371 | * for symbols it cannot find in the symbol table. This is to avoid | |
1321 | * putting undeclared symbols into the symbol table if a syntax error | 1372 | * putting undeclared symbols into the symbol table if a syntax error | |
1322 | * occurs. | 1373 | * occurs. | |
1323 | * | 1374 | * | |
1324 | * getsym() is called as soon as it is probably ok to put the symbol in the | 1375 | * getsym() is called as soon as it is probably ok to put the symbol in the | |
1325 | * symbol table. It is still possible that symbols are put in the symbol | 1376 | * symbol table. It is still possible that symbols are put in the symbol | |
1326 | * table that are not completely declared due to syntax errors. To avoid too | 1377 | * table that are not completely declared due to syntax errors. To avoid too | |
1327 | * many problems in this case, symbols get type 'int' in getsym(). | 1378 | * many problems in this case, symbols get type 'int' in getsym(). | |
1328 | * | 1379 | * | |
1329 | * XXX calls to getsym() should be delayed until decl1*() is called. | 1380 | * XXX calls to getsym() should be delayed until decl1*() is called. | |
1330 | */ | 1381 | */ |