Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/xlint/lint1 lint: document how initialization works,...
details: https://anonhg.NetBSD.org/src/rev/b0e2585622c9
branches: trunk
changeset: 953723:b0e2585622c9
user: rillig <rillig%NetBSD.org@localhost>
date: Thu Mar 18 20:22:50 2021 +0000
description:
lint: document how initialization works, improve debug logging
No functional change outside debug mode.
diffstat:
usr.bin/xlint/lint1/init.c | 66 ++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 58 insertions(+), 8 deletions(-)
diffs (142 lines):
diff -r d2b38d9d021b -r b0e2585622c9 usr.bin/xlint/lint1/init.c
--- a/usr.bin/xlint/lint1/init.c Thu Mar 18 20:20:55 2021 +0000
+++ b/usr.bin/xlint/lint1/init.c Thu Mar 18 20:22:50 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: init.c,v 1.92 2021/03/18 14:58:44 rillig Exp $ */
+/* $NetBSD: init.c,v 1.93 2021/03/18 20:22:50 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: init.c,v 1.92 2021/03/18 14:58:44 rillig Exp $");
+__RCSID("$NetBSD: init.c,v 1.93 2021/03/18 20:22:50 rillig Exp $");
#endif
#include <stdlib.h>
@@ -47,6 +47,46 @@
/*
+ * Initialization
+ *
+ * Handles initializations of global or local objects, like in:
+ *
+ * int number = 12345;
+ * int number_with_braces = { 12345 };
+ *
+ * int array_of_unknown_size[] = { 111, 222, 333 };
+ * int array_flat[2][2] = { 11, 12, 21, 22 };
+ * int array_nested[2][2] = { { 11, 12 }, { 21, 22 } };
+ *
+ * struct { int x, y; } point = { 3, 4 };
+ * struct { int x, y; } point = { .y = 3, .x = 4 };
+ *
+ * An initializer may be surrounded by an extra pair of braces, like in the
+ * example 'number_with_braces'. For multi-dimensional arrays, the inner
+ * braces may be omitted like in array_flat or spelled out like in
+ * array_nested.
+ *
+ * For the initializer, the grammar parser calls these functions:
+ *
+ * init_lbrace for a '{'
+ * init_using_expr for a value
+ * init_rbrace for a '}'
+ *
+ * The state of the current initialization is stored in initstk, a stack of
+ * initstack_element, one element per level of braces.
+ * (TODO: It might be more complicated for multi-dimensional arrays.)
+ *
+ * In initstk, when initializing an array, there is an additional level where
+ * the number of remaining elements toggles between 1 and 0.
+ * (TODO: Why is this extra level actually needed? It seems redundant.)
+ *
+ * See also:
+ * C99 6.7.8 "Initialization"
+ * d_c99_init.c for more examples
+ */
+
+
+/*
* Type of stack which is used for initialization of aggregate types.
*
* XXX: Since C99, a stack is an inappropriate data structure for modelling
@@ -94,6 +134,7 @@
*/
bool i_brace: 1;
+ /* Whether i_type is an array of unknown size. */
bool i_array_of_unknown_size: 1;
bool i_seen_named_member: 1;
@@ -106,6 +147,8 @@
/*
* The number of remaining elements.
*
+ * For an array of unknown size, this is always 0 and thus irrelevant.
+ *
* XXX: for scalars?
* XXX: for structs?
* XXX: for unions?
@@ -499,11 +542,13 @@
*/
lint_assert(istk->i_enclosing->i_enclosing == NULL);
lint_assert(istk->i_type->t_tspec == ARRAY);
+
debug_step("extending array of unknown size '%s'",
type_name(istk->i_type));
istk->i_remaining = 1;
istk->i_type->t_dim++;
setcomplete(istk->i_type, true);
+
debug_step("extended type is '%s'", type_name(istk->i_type));
}
@@ -544,9 +589,9 @@
istk->i_subt = istk->i_type->t_subt;
istk->i_array_of_unknown_size = is_incomplete(istk->i_type);
istk->i_remaining = istk->i_type->t_dim;
- debug_step("elements array %s[%d] %s",
- type_name(istk->i_subt), istk->i_remaining,
- namedmem != NULL ? namedmem->n_name : "*none*");
+ debug_named_member();
+ debug_step("type '%s' remaining %d",
+ type_name(istk->i_type), istk->i_remaining);
break;
case UNION:
if (tflag)
@@ -563,10 +608,10 @@
return;
}
cnt = 0;
- debug_step("lookup type=%s, name=%s named=%d",
+ debug_named_member();
+ debug_step("lookup for '%s'%s",
type_name(istk->i_type),
- namedmem != NULL ? namedmem->n_name : "*none*",
- istk->i_seen_named_member);
+ istk->i_seen_named_member ? ", seen named member" : "");
for (m = istk->i_type->t_str->sou_first_member;
m != NULL; m = m->s_next) {
if (m->s_bitfield && m->s_name == unnamed)
@@ -876,6 +921,8 @@
lint_assert(is_scalar(lt)); /* at least before C99 */
+ debug_step("typeok '%s', '%s'",
+ type_name(ln->tn_type), type_name(tn->tn_type));
if (!typeok(INIT, 0, ln, tn)) {
debug_initstack();
debug_leave();
@@ -892,6 +939,9 @@
check_bit_field_init(ln, lt, rt);
+ /*
+ * XXX: Is it correct to do this conversion _after_ the typeok above?
+ */
if (lt != rt || (initstk->i_type->t_bitfield && tn->tn_op == CON))
tn = convert(INIT, 0, initstk->i_type, tn);
Home |
Main Index |
Thread Index |
Old Index