Module Name:    src
Committed By:   rillig
Date:           Thu Jul 13 23:11:11 UTC 2023

Modified Files:
        src/usr.bin/xlint/lint1: cgram.y debug.c decl.c externs1.h lex.c
            lint1.h

Log Message:
lint: use separate types for parsing pointer types and type qualifiers

The documentation of the previous 'qual_ptr_t' was misleading, as that
type was used for other type qualifier lists as well, even if these were
not related to pointer types.


To generate a diff of this commit:
cvs rdiff -u -r1.460 -r1.461 src/usr.bin/xlint/lint1/cgram.y
cvs rdiff -u -r1.53 -r1.54 src/usr.bin/xlint/lint1/debug.c
cvs rdiff -u -r1.353 -r1.354 src/usr.bin/xlint/lint1/decl.c
cvs rdiff -u -r1.194 -r1.195 src/usr.bin/xlint/lint1/externs1.h
cvs rdiff -u -r1.184 -r1.185 src/usr.bin/xlint/lint1/lex.c
cvs rdiff -u -r1.190 -r1.191 src/usr.bin/xlint/lint1/lint1.h

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.460 src/usr.bin/xlint/lint1/cgram.y:1.461
--- src/usr.bin/xlint/lint1/cgram.y:1.460	Thu Jul 13 08:40:38 2023
+++ src/usr.bin/xlint/lint1/cgram.y	Thu Jul 13 23:11:11 2023
@@ -1,5 +1,5 @@
 %{
-/* $NetBSD: cgram.y,v 1.460 2023/07/13 08:40:38 rillig Exp $ */
+/* $NetBSD: cgram.y,v 1.461 2023/07/13 23:11:11 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: cgram.y,v 1.460 2023/07/13 08:40:38 rillig Exp $");
+__RCSID("$NetBSD: cgram.y,v 1.461 2023/07/13 23:11:11 rillig Exp $");
 #endif
 
 #include <limits.h>
@@ -141,7 +141,7 @@ is_either(const char *s, const char *a, 
 	op_t	y_op;
 	scl_t	y_scl;
 	tspec_t	y_tspec;
-	tqual_t	y_tqual;
+	type_qualifiers y_type_qualifiers;
 	function_specifier y_function_specifier;
 	type_t	*y_type;
 	tnode_t	*y_tnode;
@@ -166,7 +166,7 @@ is_either(const char *s, const char *a, 
 %printer { fprintf(yyo, "%s", op_name($$)); } <y_op>
 %printer { fprintf(yyo, "%s", scl_name($$)); } <y_scl>
 %printer { fprintf(yyo, "%s", tspec_name($$)); } <y_tspec>
-%printer { fprintf(yyo, "%s", tqual_name($$)); } <y_tqual>
+%printer { fprintf(yyo, "%s", type_qualifiers_string($$)); } <y_type_qualifiers>
 %printer {
 	fprintf(yyo, "%s", function_specifier_name($$));
 } <y_function_specifier>
@@ -181,10 +181,7 @@ is_either(const char *s, const char *a, 
 %printer { fprintf(yyo, "%zu to %zu", $$.lo, $$.hi); } <y_range>
 %printer { fprintf(yyo, "length %zu", $$->st_len); } <y_string>
 %printer {
-	fprintf(yyo, "%s%s%s",
-	    $$->p_const ? "const " : "",
-	    $$->p_volatile ? "volatile " : "",
-	    $$->p_pointer ? "*" : "");
+	fprintf(yyo, "%s *", type_qualifiers_string($$->qualifiers));
 } <y_qual_ptr>
 %printer { fprintf(yyo, "%s", $$ ? "yes" : "no"); } <y_seen_statement>
 %printer { fprintf(yyo, "%s", type_name($$->ga_arg)); } <y_generic>
@@ -234,9 +231,8 @@ is_either(const char *s, const char *a, 
  */
 %token	<y_tspec>	T_TYPE
 
-/* qualifiers (const, volatile, restrict, _Thread_local) */
-%token	<y_tqual>	T_QUAL
-%token	<y_tqual>	T_ATOMIC
+%token	<y_type_qualifiers>	T_QUAL
+%token	<y_type_qualifiers>	T_ATOMIC
 
 /* struct or union */
 %token	<y_tspec>	T_STRUCT_OR_UNION
@@ -338,13 +334,11 @@ is_either(const char *s, const char *a, 
 %type	<y_sym>		enums_with_opt_comma
 %type	<y_sym>		enumerator_list
 %type	<y_sym>		enumerator
-%type	<y_tqual>	type_qualifier
+%type	<y_type_qualifiers>	type_qualifier
 /* No type for atomic. */
 %type	<y_qual_ptr>	pointer
-%type	<y_qual_ptr>	asterisk
-%type	<y_qual_ptr>	type_qualifier_list_opt
-%type	<y_qual_ptr>	type_qualifier_list
-%type	<y_qual_ptr>	type_qualifier_list_elem
+%type	<y_type_qualifiers>	type_qualifier_list_opt
+%type	<y_type_qualifiers>	type_qualifier_list
 /* No type for notype_init_declarators. */
 /* No type for type_init_declarators. */
 /* No type for notype_init_declarator. */
@@ -846,7 +840,7 @@ begin_type_declaration_specifiers:	/* se
 
 begin_type_declmods:		/* see C99 6.7 */
 	begin_type type_qualifier {
-		dcs_add_qualifier($2);
+		dcs_add_qualifiers($2);
 	}
 |	begin_type T_SCLASS {
 		dcs_add_storage_class($2);
@@ -870,7 +864,7 @@ begin_type_specifier_qualifier_list_post
 		dcs_add_type($2);
 	}
 |	begin_type_specifier_qualifier_list_postfix type_qualifier {
-		dcs_add_qualifier($2);
+		dcs_add_qualifiers($2);
 	}
 |	begin_type_specifier_qualifier_list_postfix notype_type_specifier {
 		dcs_add_type($2);
@@ -889,16 +883,16 @@ begin_type_typespec:
 
 begin_type_qualifier_list:
 	begin_type type_qualifier {
-		dcs_add_qualifier($2);
+		dcs_add_qualifiers($2);
 	}
 |	begin_type_qualifier_list type_qualifier {
-		dcs_add_qualifier($2);
+		dcs_add_qualifiers($2);
 	}
 ;
 
 declmod:
 	type_qualifier {
-		dcs_add_qualifier($1);
+		dcs_add_qualifiers($1);
 	}
 |	T_SCLASS {
 		dcs_add_storage_class($1);
@@ -1223,7 +1217,7 @@ enumerator:			/* C99 6.7.2.2 */
 type_qualifier:			/* C99 6.7.3 */
 	T_QUAL
 |	atomic {
-		$$ = ATOMIC;
+		$$ = (type_qualifiers){ .tq_atomic = true };
 	}
 ;
 
@@ -1237,43 +1231,29 @@ atomic:				/* helper */
 ;
 
 pointer:			/* C99 6.7.5 */
-	asterisk type_qualifier_list_opt {
-		$$ = merge_qualified_pointer($1, $2);
-	}
-|	asterisk type_qualifier_list_opt pointer {
-		$$ = merge_qualified_pointer($1, $2);
-		$$ = merge_qualified_pointer($$, $3);
+	T_ASTERISK type_qualifier_list_opt {
+		$$ = xcalloc(1, sizeof(*$$));
+		add_type_qualifiers(&$$->qualifiers, $2);
 	}
-;
-
-asterisk:			/* helper for 'pointer' */
-	T_ASTERISK {
+|	T_ASTERISK type_qualifier_list_opt pointer {
 		$$ = xcalloc(1, sizeof(*$$));
-		$$->p_pointer = true;
+		add_type_qualifiers(&$$->qualifiers, $2);
+		$$ = append_qualified_pointer($$, $3);
 	}
 ;
 
 type_qualifier_list_opt:	/* see C99 6.7.5 */
 	/* empty */ {
-		$$ = NULL;
+		$$ = (type_qualifiers){ .tq_const = false };
 	}
 |	type_qualifier_list
 ;
 
 type_qualifier_list:		/* C99 6.7.5 */
-	type_qualifier_list_elem
-|	type_qualifier_list type_qualifier_list_elem {
-		$$ = merge_qualified_pointer($1, $2);
-	}
-;
-
-type_qualifier_list_elem:	/* helper for 'pointer' */
-	type_qualifier {
-		$$ = xcalloc(1, sizeof(*$$));
-		if ($1 == CONST)
-			$$->p_const = true;
-		if ($1 == VOLATILE)
-			$$->p_volatile = true;
+	type_qualifier
+|	type_qualifier_list type_qualifier {
+		$$ = $1;
+		add_type_qualifiers(&$$, $2);
 	}
 ;
 
@@ -1470,7 +1450,7 @@ array_size:
 	}
 |	type_qualifier {
 		/* C11 6.7.6.2 */
-		if ($1 != RESTRICT)
+		if (!$1.tq_restrict)
 			yyerror("Bad attribute");
 		$$ = NULL;
 	}
@@ -2210,7 +2190,7 @@ gcc_attribute:
 |	T_NAME T_LPAREN T_RPAREN
 |	T_NAME T_LPAREN gcc_attribute_parameters T_RPAREN
 |	type_qualifier {
-		if ($1 != CONST)
+		if (!$1.tq_const)
 			yyerror("Bad attribute");
 	}
 ;
@@ -2259,7 +2239,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 type_qualifiers_string(val.y_type_qualifiers);
 	case T_FUNCTION_SPECIFIER:
 		return function_specifier_name(val.y_function_specifier);
 	case T_NAME:

Index: src/usr.bin/xlint/lint1/debug.c
diff -u src/usr.bin/xlint/lint1/debug.c:1.53 src/usr.bin/xlint/lint1/debug.c:1.54
--- src/usr.bin/xlint/lint1/debug.c:1.53	Thu Jul 13 19:59:08 2023
+++ src/usr.bin/xlint/lint1/debug.c	Thu Jul 13 23:11:11 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: debug.c,v 1.53 2023/07/13 19:59:08 rillig Exp $ */
+/* $NetBSD: debug.c,v 1.54 2023/07/13 23:11:11 rillig Exp $ */
 
 /*-
  * Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: debug.c,v 1.53 2023/07/13 19:59:08 rillig Exp $");
+__RCSID("$NetBSD: debug.c,v 1.54 2023/07/13 23:11:11 rillig Exp $");
 #endif
 
 #include <stdlib.h>
@@ -303,16 +303,16 @@ symt_name(symt_t kind)
 }
 
 const char *
-tqual_name(tqual_t qual)
+type_qualifiers_string(type_qualifiers tq)
 {
-	static const char *const name[] = {
-		"const",
-		"volatile",
-		"restrict",
-		"_Atomic",
-	};
+	static char buf[32];
 
-	return name[qual];
+	snprintf(buf, sizeof(buf), "%s%s%s%s",
+	    tq.tq_const ? " const" : "",
+	    tq.tq_restrict ? " restrict" : "",
+	    tq.tq_volatile ? " volatile" : "",
+	    tq.tq_atomic ? " atomic" : "");
+	return buf[0] != '\0' ? buf + 1 : "none";
 }
 
 const char *
@@ -392,8 +392,8 @@ debug_sym(const char *prefix, const sym_
 			debug_printf(" %s",
 			    tspec_name(sym->u.s_keyword.u.sk_tspec));
 		if (t == T_QUAL)
-			debug_printf(" %s",
-			    tqual_name(sym->u.s_keyword.u.sk_qualifier));
+			debug_printf(" %s", type_qualifiers_string(
+			    sym->u.s_keyword.u.sk_type_qualifier));
 		if (t == T_FUNCTION_SPECIFIER)
 			debug_printf(" %s", function_specifier_name(
 			    sym->u.s_keyword.u.function_specifier));

Index: src/usr.bin/xlint/lint1/decl.c
diff -u src/usr.bin/xlint/lint1/decl.c:1.353 src/usr.bin/xlint/lint1/decl.c:1.354
--- src/usr.bin/xlint/lint1/decl.c:1.353	Thu Jul 13 20:30:21 2023
+++ src/usr.bin/xlint/lint1/decl.c	Thu Jul 13 23:11:11 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: decl.c,v 1.353 2023/07/13 20:30:21 rillig Exp $ */
+/* $NetBSD: decl.c,v 1.354 2023/07/13 23:11:11 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -38,7 +38,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: decl.c,v 1.353 2023/07/13 20:30:21 rillig Exp $");
+__RCSID("$NetBSD: decl.c,v 1.354 2023/07/13 23:11:11 rillig Exp $");
 #endif
 
 #include <sys/param.h>
@@ -499,24 +499,22 @@ dcs_set_used(void)
  * declarators.
  */
 void
-dcs_add_qualifier(tqual_t q)
+dcs_add_qualifiers(type_qualifiers qs)
 {
 
-	if (q == CONST) {
+	if (qs.tq_const) {
 		if (dcs->d_const) {
 			/* duplicate '%s' */
 			warning(10, "const");
 		}
 		dcs->d_const = true;
-	} else if (q == VOLATILE) {
+	}
+	if (qs.tq_volatile) {
 		if (dcs->d_volatile) {
 			/* duplicate '%s' */
 			warning(10, "volatile");
 		}
 		dcs->d_volatile = true;
-	} else {
-		lint_assert(q == RESTRICT || q == ATOMIC);
-		/* Silently ignore these qualifiers. */
 	}
 }
 
@@ -1153,45 +1151,36 @@ set_bit_field_width(sym_t *dsym, int bit
 	return dsym;
 }
 
-/*
- * A sequence of asterisks and qualifiers, from right to left.  For example,
- * 'const ***volatile **const volatile' results in [cvp, p, vp, p, p].  The
- * leftmost 'const' is not included in this list, it is stored in dcs->d_const
- * instead.
- */
+void
+add_type_qualifiers(type_qualifiers *dst, type_qualifiers src)
+{
+
+	if (src.tq_const && dst->tq_const)
+		/* duplicate '%s' */
+		warning(10, "const");
+	if (src.tq_volatile && dst->tq_volatile)
+		/* duplicate '%s' */
+		warning(10, "volatile");
+
+	dst->tq_const = dst->tq_const || src.tq_const;
+	dst->tq_restrict = dst->tq_restrict || src.tq_restrict;
+	dst->tq_volatile = dst->tq_volatile || src.tq_volatile;
+	dst->tq_atomic = dst->tq_atomic || src.tq_atomic;
+}
+
 qual_ptr *
-merge_qualified_pointer(qual_ptr *p1, qual_ptr *p2)
+append_qualified_pointer(qual_ptr *p1, qual_ptr *p2)
 {
 
 	if (p2 == NULL)
-		return p1;	/* for optional qualifiers */
+		return p1;
 
-	if (p2->p_pointer) {
-		/* append p1 to p2, keeping p2 */
-		qual_ptr *tail = p2;
-		while (tail->p_next != NULL)
-			tail = tail->p_next;
-		tail->p_next = p1;
-		return p2;
-	}
-
-	/* merge p2 into p1, keeping p1 */
-	if (p2->p_const) {
-		if (p1->p_const) {
-			/* duplicate '%s' */
-			warning(10, "const");
-		}
-		p1->p_const = true;
-	}
-	if (p2->p_volatile) {
-		if (p1->p_volatile) {
-			/* duplicate '%s' */
-			warning(10, "volatile");
-		}
-		p1->p_volatile = true;
-	}
-	free(p2);
-	return p1;
+	/* append p1 to p2, keeping p2 */
+	qual_ptr *tail = p2;
+	while (tail->p_next != NULL)
+		tail = tail->p_next;
+	tail->p_next = p1;
+	return p2;
 }
 
 static type_t *
@@ -1229,7 +1218,7 @@ add_pointer(sym_t *decl, qual_ptr *p)
 
 	while (p != NULL) {
 		*tpp = block_derive_pointer(dcs->d_type,
-		    p->p_const, p->p_volatile);
+		    p->qualifiers.tq_const, p->qualifiers.tq_volatile);
 
 		tpp = &(*tpp)->t_subt;
 

Index: src/usr.bin/xlint/lint1/externs1.h
diff -u src/usr.bin/xlint/lint1/externs1.h:1.194 src/usr.bin/xlint/lint1/externs1.h:1.195
--- src/usr.bin/xlint/lint1/externs1.h:1.194	Thu Jul 13 08:40:38 2023
+++ src/usr.bin/xlint/lint1/externs1.h	Thu Jul 13 23:11:11 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: externs1.h,v 1.194 2023/07/13 08:40:38 rillig Exp $	*/
+/*	$NetBSD: externs1.h,v 1.195 2023/07/13 23:11:11 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -122,7 +122,7 @@ void	expr_restore_memory(memory_pool);
 const char *decl_level_kind_name(decl_level_kind);
 const char *scl_name(scl_t);
 const char *symt_name(symt_t);
-const char *tqual_name(tqual_t);
+const char *type_qualifiers_string(type_qualifiers);
 const char *function_specifier_name(function_specifier);
 void	debug_dcs(bool);
 void	debug_node(const tnode_t *);
@@ -196,7 +196,7 @@ bool	is_incomplete(const type_t *);
 void	dcs_add_function_specifier(function_specifier);
 void	dcs_add_storage_class(scl_t);
 void	dcs_add_type(type_t *);
-void	dcs_add_qualifier(tqual_t);
+void	dcs_add_qualifiers(type_qualifiers);
 void	dcs_add_packed(void);
 void	dcs_set_used(void);
 void	begin_declaration_level(decl_level_kind);
@@ -211,7 +211,8 @@ void	check_type(sym_t *);
 sym_t	*declare_unnamed_member(void);
 sym_t	*declare_member(sym_t *);
 sym_t	*set_bit_field_width(sym_t *, int);
-qual_ptr *merge_qualified_pointer(qual_ptr *, qual_ptr *);
+void	add_type_qualifiers(type_qualifiers *, type_qualifiers);
+qual_ptr *append_qualified_pointer(qual_ptr *, qual_ptr *);
 sym_t	*add_pointer(sym_t *, qual_ptr *);
 sym_t	*add_array(sym_t *, bool, int);
 sym_t	*add_function(sym_t *, sym_t *);

Index: src/usr.bin/xlint/lint1/lex.c
diff -u src/usr.bin/xlint/lint1/lex.c:1.184 src/usr.bin/xlint/lint1/lex.c:1.185
--- src/usr.bin/xlint/lint1/lex.c:1.184	Thu Jul 13 20:30:21 2023
+++ src/usr.bin/xlint/lint1/lex.c	Thu Jul 13 23:11:11 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: lex.c,v 1.184 2023/07/13 20:30:21 rillig Exp $ */
+/* $NetBSD: lex.c,v 1.185 2023/07/13 23:11:11 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -38,7 +38,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: lex.c,v 1.184 2023/07/13 20:30:21 rillig Exp $");
+__RCSID("$NetBSD: lex.c,v 1.185 2023/07/13 23:11:11 rillig Exp $");
 #endif
 
 #include <ctype.h>
@@ -94,7 +94,7 @@ bool in_system_header;
 #define kwdef_type(name, tspec,			since) \
 	kwdef(name, T_TYPE, .u.kw_tspec = (tspec), since, 0, 1)
 #define kwdef_tqual(name, tqual,		since, gcc, deco) \
-	kwdef(name, T_QUAL, .u.kw_tqual = (tqual), since, gcc, deco)
+	kwdef(name, T_QUAL, .u.kw_tqual = {.tqual = true}, since, gcc, deco)
 #define kwdef_keyword(name, token) \
 	kwdef(name, token, {false},		78, 0, 1)
 
@@ -107,7 +107,7 @@ static const struct keyword {
 		scl_t kw_scl;		/* if kw_token is T_SCLASS */
 		tspec_t kw_tspec;	/* if kw_token is T_TYPE or
 					 * T_STRUCT_OR_UNION */
-		tqual_t kw_tqual;	/* if kw_token is T_QUAL */
+		type_qualifiers kw_tqual;	/* if kw_token is T_QUAL */
 		function_specifier kw_fs;	/* if kw_token is
 						 * T_FUNCTION_SPECIFIER */
 	} u;
@@ -132,7 +132,7 @@ static const struct keyword {
 	kwdef_keyword(	"case",		T_CASE),
 	kwdef_type(	"char",		CHAR,			78),
 	kwdef_type(	"_Complex",	COMPLEX,		99),
-	kwdef_tqual(	"const",	CONST,			90,0,7),
+	kwdef_tqual(	"const",	tq_const,		90,0,7),
 	kwdef_keyword(	"continue",	T_CONTINUE),
 	kwdef_keyword(	"default",	T_DEFAULT),
 	kwdef_keyword(	"do",		T_DO),
@@ -157,7 +157,7 @@ static const struct keyword {
 	kwdef_token(	"__packed",	T_PACKED,		78,0,1),
 	kwdef_token(	"__real__",	T_REAL,			78,1,1),
 	kwdef_sclass(	"register",	REG,			78,0,1),
-	kwdef_tqual(	"restrict",	RESTRICT,		99,0,7),
+	kwdef_tqual(	"restrict",	tq_restrict,		99,0,7),
 	kwdef_keyword(	"return",	T_RETURN),
 	kwdef_type(	"short",	SHORT,			78),
 	kwdef(		"signed", T_TYPE, .u.kw_tspec = SIGNED,	90,0,3),
@@ -178,7 +178,7 @@ static const struct keyword {
 	kwdef("union",	T_STRUCT_OR_UNION, .u.kw_tspec = UNION,	78,0,1),
 	kwdef_type(	"unsigned",	UNSIGN,			78),
 	kwdef_type(	"void",		VOID,			78),
-	kwdef_tqual(	"volatile",	VOLATILE,		90,0,7),
+	kwdef_tqual(	"volatile",	tq_volatile,		90,0,7),
 	kwdef_keyword(	"while",	T_WHILE),
 #undef kwdef
 #undef kwdef_token
@@ -359,7 +359,7 @@ add_keyword(const struct keyword *kw, bo
 	if (tok == T_SCLASS)
 		sym->s_scl = kw->u.kw_scl;
 	if (tok == T_QUAL)
-		sym->u.s_keyword.u.sk_qualifier = kw->u.kw_tqual;
+		sym->u.s_keyword.u.sk_type_qualifier = kw->u.kw_tqual;
 	if (tok == T_FUNCTION_SPECIFIER)
 		sym->u.s_keyword.u.function_specifier = kw->u.kw_fs;
 
@@ -440,7 +440,8 @@ lex_keyword(sym_t *sym)
 	if (tok == T_TYPE || tok == T_STRUCT_OR_UNION)
 		yylval.y_tspec = sym->u.s_keyword.u.sk_tspec;
 	if (tok == T_QUAL)
-		yylval.y_tqual = sym->u.s_keyword.u.sk_qualifier;
+		yylval.y_type_qualifiers =
+		    sym->u.s_keyword.u.sk_type_qualifier;
 	if (tok == T_FUNCTION_SPECIFIER)
 		yylval.y_function_specifier =
 		    sym->u.s_keyword.u.function_specifier;

Index: src/usr.bin/xlint/lint1/lint1.h
diff -u src/usr.bin/xlint/lint1/lint1.h:1.190 src/usr.bin/xlint/lint1/lint1.h:1.191
--- src/usr.bin/xlint/lint1/lint1.h:1.190	Thu Jul 13 19:59:08 2023
+++ src/usr.bin/xlint/lint1/lint1.h	Thu Jul 13 23:11:11 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: lint1.h,v 1.190 2023/07/13 19:59:08 rillig Exp $ */
+/* $NetBSD: lint1.h,v 1.191 2023/07/13 23:11:11 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -79,13 +79,12 @@ typedef	struct strg {
 	void	*st_mem;	/* char[] for st_char, or wchar_t[] */
 } strg_t;
 
-/* type qualifiers (only used during parsing) */
-typedef enum {
-	CONST,
-	VOLATILE,
-	RESTRICT,
-	ATOMIC,
-} tqual_t;
+typedef struct {
+	bool tq_const:1;
+	bool tq_restrict:1;
+	bool tq_volatile:1;
+	bool tq_atomic:1;
+} type_qualifiers;
 
 /* An integer or floating-point value. */
 typedef struct {
@@ -257,7 +256,7 @@ typedef	struct sym {
 				/* if T_TYPE or T_STRUCT_OR_UNION */
 				tspec_t sk_tspec;
 				/* if T_QUAL */
-				tqual_t sk_qualifier;
+				type_qualifiers sk_type_qualifier;
 				/* if T_FUNCTION_SPECIFIER */
 				function_specifier function_specifier;
 			} u;
@@ -390,11 +389,14 @@ typedef	struct decl_level {
 	struct decl_level *d_enclosing; /* the enclosing declaration level */
 } decl_level;
 
-/* One level of pointer indirection in declarators, including qualifiers. */
+/*
+ * A sequence of asterisks and qualifiers, from right to left.  For example,
+ * 'const ***volatile **const volatile' results in [c-v-, ----, --v-, ----,
+ * ----].  The leftmost 'const' is not included in this list, it is stored in
+ * dcs->d_const instead.
+ */
 typedef	struct qual_ptr {
-	bool	p_const:1;
-	bool	p_volatile:1;
-	bool	p_pointer:1;
+	type_qualifiers qualifiers;
 	struct	qual_ptr *p_next;
 } qual_ptr;
 

Reply via email to