Module Name:    src
Committed By:   rillig
Date:           Wed Jul 12 16:07:35 UTC 2023

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

Log Message:
lint: don't treat 'inline' as a storage class

The additional conflict in the grammar is in the same place as the other
conflicts, as T_SCLASS and T_FUNCTION_SPECIFIER are now separate tokens.

No functional change.


To generate a diff of this commit:
cvs rdiff -u -r1.455 -r1.456 src/usr.bin/xlint/lint1/cgram.y
cvs rdiff -u -r1.49 -r1.50 src/usr.bin/xlint/lint1/debug.c
cvs rdiff -u -r1.348 -r1.349 src/usr.bin/xlint/lint1/decl.c
cvs rdiff -u -r1.190 -r1.191 src/usr.bin/xlint/lint1/externs1.h
cvs rdiff -u -r1.175 -r1.176 src/usr.bin/xlint/lint1/lex.c
cvs rdiff -u -r1.185 -r1.186 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.455 src/usr.bin/xlint/lint1/cgram.y:1.456
--- src/usr.bin/xlint/lint1/cgram.y:1.455	Wed Jul 12 13:00:09 2023
+++ src/usr.bin/xlint/lint1/cgram.y	Wed Jul 12 16:07:35 2023
@@ -1,5 +1,5 @@
 %{
-/* $NetBSD: cgram.y,v 1.455 2023/07/12 13:00:09 rillig Exp $ */
+/* $NetBSD: cgram.y,v 1.456 2023/07/12 16:07:35 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.455 2023/07/12 13:00:09 rillig Exp $");
+__RCSID("$NetBSD: cgram.y,v 1.456 2023/07/12 16:07:35 rillig Exp $");
 #endif
 
 #include <limits.h>
@@ -132,7 +132,7 @@ is_either(const char *s, const char *a, 
 
 %}
 
-%expect 131
+%expect 132
 
 %union {
 	val_t	*y_val;
@@ -142,6 +142,7 @@ is_either(const char *s, const char *a, 
 	scl_t	y_scl;
 	tspec_t	y_tspec;
 	tqual_t	y_tqual;
+	function_specifier y_function_specifier;
 	type_t	*y_type;
 	tnode_t	*y_tnode;
 	range_t	y_range;
@@ -166,6 +167,9 @@ is_either(const char *s, const char *a, 
 %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", function_specifier_name($$));
+} <y_function_specifier>
 %printer { fprintf(yyo, "%s", type_name($$)); } <y_type>
 %printer {
 	if ($$ == NULL)
@@ -223,6 +227,7 @@ is_either(const char *s, const char *a, 
 
 /* storage classes (extern, static, auto, register and typedef) */
 %token	<y_scl>		T_SCLASS
+%token	<y_function_specifier> T_FUNCTION_SPECIFIER
 
 /*
  * predefined type keywords (char, int, short, long, unsigned, signed,
@@ -847,6 +852,9 @@ begin_type_declmods:		/* see C99 6.7 */
 |	begin_type T_SCLASS {
 		dcs_add_storage_class($2);
 	}
+|	begin_type T_FUNCTION_SPECIFIER {
+		dcs_add_function_specifier($2);
+	}
 |	begin_type_declmods declmod
 ;
 
@@ -896,6 +904,9 @@ declmod:
 |	T_SCLASS {
 		dcs_add_storage_class($1);
 	}
+|	T_FUNCTION_SPECIFIER {
+		dcs_add_function_specifier($1);
+	}
 |	type_attribute_list
 ;
 
@@ -2251,6 +2262,8 @@ cgram_to_string(int token, YYSTYPE val)
 		return tspec_name(val.y_tspec);
 	case T_QUAL:
 		return tqual_name(val.y_tqual);
+	case T_FUNCTION_SPECIFIER:
+		return function_specifier_name(val.y_function_specifier);
 	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.49 src/usr.bin/xlint/lint1/debug.c:1.50
--- src/usr.bin/xlint/lint1/debug.c:1.49	Mon Jul 10 19:47:12 2023
+++ src/usr.bin/xlint/lint1/debug.c	Wed Jul 12 16:07:35 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: debug.c,v 1.49 2023/07/10 19:47:12 rillig Exp $ */
+/* $NetBSD: debug.c,v 1.50 2023/07/12 16:07:35 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.49 2023/07/10 19:47:12 rillig Exp $");
+__RCSID("$NetBSD: debug.c,v 1.50 2023/07/12 16:07:35 rillig Exp $");
 #endif
 
 #include <stdlib.h>
@@ -227,7 +227,7 @@ debug_node(const tnode_t *tn) // NOLINT(
 		debug_node(tn->tn_left);
 		if (op != INCBEF && op != INCAFT
 		    && op != DECBEF && op != DECAFT
-		    && op != PUSH)
+		    && op != CALL && op != PUSH)
 			lint_assert(is_binary(tn) == (tn->tn_right != NULL));
 		if (tn->tn_right != NULL)
 			debug_node(tn->tn_right);
@@ -283,7 +283,6 @@ scl_name(scl_t scl)
 		"abstract",
 		"old-style-function-argument",
 		"prototype-argument",
-		"inline",
 	};
 
 	return name[scl];
@@ -316,6 +315,16 @@ tqual_name(tqual_t qual)
 	return name[qual];
 }
 
+const char *
+function_specifier_name(function_specifier spec)
+{
+	static const char *const name[] = {
+		"inline",
+	};
+
+	return name[spec];
+}
+
 static void
 debug_word(bool flag, const char *name)
 {
@@ -380,10 +389,13 @@ debug_sym(const char *prefix, const sym_
 		int t = sym->u.s_keyword.sk_token;
 		if (t == T_TYPE || t == T_STRUCT_OR_UNION)
 			debug_printf(" %s",
-			    tspec_name(sym->u.s_keyword.sk_tspec));
+			    tspec_name(sym->u.s_keyword.u.sk_tspec));
 		if (t == T_QUAL)
 			debug_printf(" %s",
-			    tqual_name(sym->u.s_keyword.sk_qualifier));
+			    tqual_name(sym->u.s_keyword.u.sk_qualifier));
+		if (t == T_FUNCTION_SPECIFIER)
+			debug_printf(" %s", function_specifier_name(
+			    sym->u.s_keyword.u.function_specifier));
 	}
 
 	debug_word(sym->s_osdef && sym->u.s_old_style_args != NULL,

Index: src/usr.bin/xlint/lint1/decl.c
diff -u src/usr.bin/xlint/lint1/decl.c:1.348 src/usr.bin/xlint/lint1/decl.c:1.349
--- src/usr.bin/xlint/lint1/decl.c:1.348	Sun Jul  9 12:15:07 2023
+++ src/usr.bin/xlint/lint1/decl.c	Wed Jul 12 16:07:35 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: decl.c,v 1.348 2023/07/09 12:15:07 rillig Exp $ */
+/* $NetBSD: decl.c,v 1.349 2023/07/12 16:07:35 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.348 2023/07/09 12:15:07 rillig Exp $");
+__RCSID("$NetBSD: decl.c,v 1.349 2023/07/12 16:07:35 rillig Exp $");
 #endif
 
 #include <sys/param.h>
@@ -200,21 +200,25 @@ is_incomplete(const type_t *tp)
 	return false;
 }
 
-/*
- * Remember the storage class of the current declaration and detect multiple
- * storage classes.
- */
 void
-dcs_add_storage_class(scl_t sc)
+dcs_add_function_specifier(function_specifier fs)
 {
-
-	if (sc == INLINE) {
+	debug_step("%s: %s", __func__, function_specifier_name(fs));
+	if (fs == FS_INLINE) {
 		if (dcs->d_inline)
 			/* duplicate '%s' */
 			warning(10, "inline");
 		dcs->d_inline = true;
-		return;
 	}
+}
+
+/*
+ * Remember the storage class of the current declaration and detect multiple
+ * storage classes.
+ */
+void
+dcs_add_storage_class(scl_t sc)
+{
 
 	if (dcs->d_type != NULL || dcs->d_abstract_type != NO_TSPEC ||
 	    dcs->d_sign_mod != NO_TSPEC || dcs->d_rank_mod != NO_TSPEC) {
@@ -619,6 +623,7 @@ void
 dcs_begin_type(void)
 {
 
+	debug_step("%s", __func__);
 	dcs->d_abstract_type = NO_TSPEC;
 	dcs->d_complex_mod = NO_TSPEC;
 	dcs->d_sign_mod = NO_TSPEC;
@@ -723,6 +728,7 @@ void
 dcs_end_type(void)
 {
 
+	debug_step("%s", __func__);
 	dcs_merge_declaration_specifiers();
 
 	if (dcs->d_multiple_storage_classes) {

Index: src/usr.bin/xlint/lint1/externs1.h
diff -u src/usr.bin/xlint/lint1/externs1.h:1.190 src/usr.bin/xlint/lint1/externs1.h:1.191
--- src/usr.bin/xlint/lint1/externs1.h:1.190	Fri Jul  7 19:45:22 2023
+++ src/usr.bin/xlint/lint1/externs1.h	Wed Jul 12 16:07:35 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: externs1.h,v 1.190 2023/07/07 19:45:22 rillig Exp $	*/
+/*	$NetBSD: externs1.h,v 1.191 2023/07/12 16:07:35 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -123,6 +123,7 @@ const char *decl_level_kind_name(decl_le
 const char *scl_name(scl_t);
 const char *symt_name(symt_t);
 const char *tqual_name(tqual_t);
+const char *function_specifier_name(function_specifier);
 void	debug_dcs(bool);
 void	debug_node(const tnode_t *);
 void	debug_type(const type_t *);
@@ -192,6 +193,7 @@ type_t	*block_dup_type(const type_t *);
 type_t	*expr_dup_type(const type_t *);
 type_t	*expr_unqualified_type(const type_t *);
 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);

Index: src/usr.bin/xlint/lint1/lex.c
diff -u src/usr.bin/xlint/lint1/lex.c:1.175 src/usr.bin/xlint/lint1/lex.c:1.176
--- src/usr.bin/xlint/lint1/lex.c:1.175	Wed Jul 12 10:08:11 2023
+++ src/usr.bin/xlint/lint1/lex.c	Wed Jul 12 16:07:35 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: lex.c,v 1.175 2023/07/12 10:08:11 rillig Exp $ */
+/* $NetBSD: lex.c,v 1.176 2023/07/12 16:07:35 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.175 2023/07/12 10:08:11 rillig Exp $");
+__RCSID("$NetBSD: lex.c,v 1.176 2023/07/12 16:07:35 rillig Exp $");
 #endif
 
 #include <ctype.h>
@@ -97,13 +97,15 @@ bool in_system_header;
 /* During initialization, these keywords are written to the symbol table. */
 static const struct keyword {
 	const	char *kw_name;
-	int	kw_token;	/* token returned by yylex() */
+	int	kw_token;	/* token to be returned by yylex() */
 	union {
 		bool kw_dummy;
 		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 */
+		function_specifier kw_fs;	/* if kw_token is
+						 * T_FUNCTION_SPECIFIER */
 	} u;
 	bool	kw_c90:1;	/* available in C90 mode */
 	bool	kw_c99_or_c11:1; /* available in C99 or C11 mode */
@@ -140,7 +142,7 @@ static const struct keyword {
 	kwdef_keyword(	"goto",		T_GOTO),
 	kwdef_keyword(	"if",		T_IF),
 	kwdef_token(	"__imag__",	T_IMAG,			78,1,1),
-	kwdef_sclass(	"inline",	INLINE,			99,0,7),
+	kwdef("inline",	T_FUNCTION_SPECIFIER, .u.kw_fs = FS_INLINE, 99,0,7),
 	kwdef_type(	"int",		INT,			78),
 #ifdef INT128_SIZE
 	kwdef_type(	"__int128_t",	INT128,			99),
@@ -348,11 +350,13 @@ add_keyword(const struct keyword *kw, bo
 	int tok = kw->kw_token;
 	sym->u.s_keyword.sk_token = tok;
 	if (tok == T_TYPE || tok == T_STRUCT_OR_UNION)
-		sym->u.s_keyword.sk_tspec = kw->u.kw_tspec;
+		sym->u.s_keyword.u.sk_tspec = kw->u.kw_tspec;
 	if (tok == T_SCLASS)
 		sym->s_scl = kw->u.kw_scl;
 	if (tok == T_QUAL)
-		sym->u.s_keyword.sk_qualifier = kw->u.kw_tqual;
+		sym->u.s_keyword.u.sk_qualifier = kw->u.kw_tqual;
+	if (tok == T_FUNCTION_SPECIFIER)
+		sym->u.s_keyword.u.function_specifier = kw->u.kw_fs;
 
 	symtab_add(sym);
 }
@@ -427,9 +431,12 @@ lex_keyword(sym_t *sym)
 	if (tok == T_SCLASS)
 		yylval.y_scl = sym->s_scl;
 	if (tok == T_TYPE || tok == T_STRUCT_OR_UNION)
-		yylval.y_tspec = sym->u.s_keyword.sk_tspec;
+		yylval.y_tspec = sym->u.s_keyword.u.sk_tspec;
 	if (tok == T_QUAL)
-		yylval.y_tqual = sym->u.s_keyword.sk_qualifier;
+		yylval.y_tqual = sym->u.s_keyword.u.sk_qualifier;
+	if (tok == T_FUNCTION_SPECIFIER)
+		yylval.y_function_specifier =
+		    sym->u.s_keyword.u.function_specifier;
 	return tok;
 }
 

Index: src/usr.bin/xlint/lint1/lint1.h
diff -u src/usr.bin/xlint/lint1/lint1.h:1.185 src/usr.bin/xlint/lint1/lint1.h:1.186
--- src/usr.bin/xlint/lint1/lint1.h:1.185	Tue Jul 11 20:54:23 2023
+++ src/usr.bin/xlint/lint1/lint1.h	Wed Jul 12 16:07:35 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: lint1.h,v 1.185 2023/07/11 20:54:23 rillig Exp $ */
+/* $NetBSD: lint1.h,v 1.186 2023/07/12 16:07:35 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -206,9 +206,14 @@ typedef enum {
 	BOOL_CONST,
 	ENUM_CONST,
 	ABSTRACT,	/* abstract symbol (sizeof, casts, unnamed argument) */
-	INLINE		/* only used by the parser */
 } scl_t;
 
+/* C23 6.7.4 */
+typedef enum {
+	FS_INLINE,
+	// TODO: Add FS_NORETURN, for C23.
+} function_specifier;
+
 /*
  * symbol table entry
  */
@@ -250,8 +255,14 @@ typedef	struct sym {
 		} s_member;
 		struct {
 			int sk_token;
-			tspec_t	sk_tspec;	/* only for types */
-			tqual_t	sk_qualifier;	/* only for qualifiers */
+			union {
+				/* if T_TYPE or T_STRUCT_OR_UNION */
+				tspec_t sk_tspec;
+				/* if T_QUAL */
+				tqual_t sk_qualifier;
+				/* if T_FUNCTION_SPECIFIER */
+				function_specifier function_specifier;
+			} u;
 		} s_keyword;
 		struct	sym *s_old_style_args;	/* arguments in an old-style
 						 * function definition */

Reply via email to