Wed Apr 5 20:17:30 2023 UTC ()
lint: fix duplicate warning when parsing big float constants


(rillig)
diff -r1.4 -r1.5 src/tests/usr.bin/xlint/lint1/platform_ldbl128.c
diff -r1.4 -r1.5 src/tests/usr.bin/xlint/lint1/platform_ldbl96.c
diff -r1.155 -r1.156 src/usr.bin/xlint/lint1/lex.c

cvs diff -r1.4 -r1.5 src/tests/usr.bin/xlint/lint1/platform_ldbl128.c (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/platform_ldbl128.c 2023/04/05 20:13:01 1.4
+++ src/tests/usr.bin/xlint/lint1/platform_ldbl128.c 2023/04/05 20:17:30 1.5
@@ -1,31 +1,29 @@ @@ -1,31 +1,29 @@
1/* $NetBSD: platform_ldbl128.c,v 1.4 2023/04/05 20:13:01 rillig Exp $ */ 1/* $NetBSD: platform_ldbl128.c,v 1.5 2023/04/05 20:17:30 rillig Exp $ */
2# 3 "platform_ldbl128.c" 2# 3 "platform_ldbl128.c"
3 3
4/* 4/*
5 * Test features that only apply to platforms that have 128-bit long double. 5 * Test features that only apply to platforms that have 128-bit long double.
6 */ 6 */
7 7
8/* lint1-extra-flags: -c -h -a -p -b -r -z -X 351 */ 8/* lint1-extra-flags: -c -h -a -p -b -r -z -X 351 */
9/* lint1-only-if: ldbl-128 */ 9/* lint1-only-if: ldbl-128 */
10 10
11/* CONSTCOND */ 11/* CONSTCOND */
12typedef int bits_per_byte[((unsigned char)-1) == 255 ? 1 : -1]; 12typedef int bits_per_byte[((unsigned char)-1) == 255 ? 1 : -1];
13typedef int bytes_per_long_double[sizeof(long double) == 16 ? 1 : -1]; 13typedef int bytes_per_long_double[sizeof(long double) == 16 ? 1 : -1];
14 14
15/* 15/*
16 * Platforms with 128-bit 'long double' typically use IEEE 754-2008, which has 16 * Platforms with 128-bit 'long double' typically use IEEE 754-2008, which has
17 * 1 bit sign + 15 bit exponent + 112 bit normalized mantissa. This means the 17 * 1 bit sign + 15 bit exponent + 112 bit normalized mantissa. This means the
18 * maximum representable value is 1.1111111(bin) * 2^16383, which is about 18 * maximum representable value is 1.1111111(bin) * 2^16383, which is about
19 * 1.189e4932. This is in the same range as for 96-bit 'long double', as the 19 * 1.189e4932. This is in the same range as for 96-bit 'long double', as the
20 * exponent range is the same. 20 * exponent range is the same.
21 */ 21 */
22/* FIXME: remove the duplicate warning. */ 
23/* expect+2: warning: floating-point constant out of range [248] */ 
24/* expect+1: warning: floating-point constant out of range [248] */ 22/* expect+1: warning: floating-point constant out of range [248] */
25double larger_than_ldbl = 1e4933; 23double larger_than_ldbl = 1e4933;
26/* expect+1: warning: floating-point constant out of range [248] */ 24/* expect+1: warning: floating-point constant out of range [248] */
27long double larger_than_ldbl_l = 1e4933L; 25long double larger_than_ldbl_l = 1e4933L;
28/* expect+1: warning: floating-point constant out of range [248] */ 26/* expect+1: warning: floating-point constant out of range [248] */
29double larger_than_dbl = 1e4932; 27double larger_than_dbl = 1e4932;
30/* Fits in 'long double' but not in 'double'. */ 28/* Fits in 'long double' but not in 'double'. */
31long double larger_than_dbl_l = 1e4932L; 29long double larger_than_dbl_l = 1e4932L;

cvs diff -r1.4 -r1.5 src/tests/usr.bin/xlint/lint1/platform_ldbl96.c (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/platform_ldbl96.c 2023/04/05 20:13:01 1.4
+++ src/tests/usr.bin/xlint/lint1/platform_ldbl96.c 2023/04/05 20:17:30 1.5
@@ -1,30 +1,28 @@ @@ -1,30 +1,28 @@
1/* $NetBSD: platform_ldbl96.c,v 1.4 2023/04/05 20:13:01 rillig Exp $ */ 1/* $NetBSD: platform_ldbl96.c,v 1.5 2023/04/05 20:17:30 rillig Exp $ */
2# 3 "platform_ldbl96.c" 2# 3 "platform_ldbl96.c"
3 3
4/* 4/*
5 * Test features that only apply to platforms that have 96-bit long double. 5 * Test features that only apply to platforms that have 96-bit long double.
6 */ 6 */
7 7
8/* lint1-extra-flags: -c -h -a -p -b -r -z -X 351 */ 8/* lint1-extra-flags: -c -h -a -p -b -r -z -X 351 */
9/* lint1-only-if: ldbl-96 */ 9/* lint1-only-if: ldbl-96 */
10 10
11/* CONSTCOND */ 11/* CONSTCOND */
12typedef int bits_per_byte[((unsigned char)-1) == 255 ? 1 : -1]; 12typedef int bits_per_byte[((unsigned char)-1) == 255 ? 1 : -1];
13typedef int bytes_per_long_double[sizeof(long double) == 12 ? 1 : -1]; 13typedef int bytes_per_long_double[sizeof(long double) == 12 ? 1 : -1];
14 14
15/* 15/*
16 * Both i386 and m68k use the same floating point format for 'long double', 16 * Both i386 and m68k use the same floating point format for 'long double',
17 * which has 1 bit sign + 15 bit exponent + 64 bit unnormalized mantissa. 17 * which has 1 bit sign + 15 bit exponent + 64 bit unnormalized mantissa.
18 * This means the maximum representable value is 1.1111111(bin) * 2^16383, 18 * This means the maximum representable value is 1.1111111(bin) * 2^16383,
19 * which is about 1.189e4932. 19 * which is about 1.189e4932.
20 */ 20 */
21/* FIXME: Remove the duplicate warning. */ 
22/* expect+2: warning: floating-point constant out of range [248] */ 
23/* expect+1: warning: floating-point constant out of range [248] */ 21/* expect+1: warning: floating-point constant out of range [248] */
24double larger_than_ldbl = 1e4933; 22double larger_than_ldbl = 1e4933;
25/* expect+1: warning: floating-point constant out of range [248] */ 23/* expect+1: warning: floating-point constant out of range [248] */
26long double larger_than_ldbl_l = 1e4933L; 24long double larger_than_ldbl_l = 1e4933L;
27/* expect+1: warning: floating-point constant out of range [248] */ 25/* expect+1: warning: floating-point constant out of range [248] */
28double larger_than_dbl = 1e4932; 26double larger_than_dbl = 1e4932;
29/* Fits in 'long double' but not in 'double'. */ 27/* Fits in 'long double' but not in 'double'. */
30long double larger_than_dbl_l = 1e4932L; 28long double larger_than_dbl_l = 1e4932L;

cvs diff -r1.155 -r1.156 src/usr.bin/xlint/lint1/lex.c (switch to unified diff)

--- src/usr.bin/xlint/lint1/lex.c 2023/03/31 13:03:05 1.155
+++ src/usr.bin/xlint/lint1/lex.c 2023/04/05 20:17:30 1.156
@@ -1,1495 +1,1494 @@ @@ -1,1495 +1,1494 @@
1/* $NetBSD: lex.c,v 1.155 2023/03/31 13:03:05 rillig Exp $ */ 1/* $NetBSD: lex.c,v 1.156 2023/04/05 20:17:30 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
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement: 17 * must display the following acknowledgement:
18 * This product includes software developed by Jochen Pohl for 18 * This product includes software developed by Jochen Pohl for
19 * The NetBSD Project. 19 * The NetBSD Project.
20 * 4. The name of the author may not be used to endorse or promote products 20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission. 21 * derived from this software without specific prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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) 40#if defined(__RCSID)
41__RCSID("$NetBSD: lex.c,v 1.155 2023/03/31 13:03:05 rillig Exp $"); 41__RCSID("$NetBSD: lex.c,v 1.156 2023/04/05 20:17:30 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
55#define CHAR_MASK ((1U << CHAR_SIZE) - 1) 55#define CHAR_MASK ((1U << CHAR_SIZE) - 1)
56 56
57 57
58/* Current position (it's also updated when an included file is parsed) */ 58/* Current position (it's also updated when an included file is parsed) */
59pos_t curr_pos = { "", 1, 0 }; 59pos_t curr_pos = { "", 1, 0 };
60 60
61/* 61/*
62 * Current position in C source (not updated when an included file is 62 * Current position in C source (not updated when an included file is
63 * parsed). 63 * parsed).
64 */ 64 */
65pos_t csrc_pos = { "", 1, 0 }; 65pos_t csrc_pos = { "", 1, 0 };
66 66
67bool in_gcc_attribute; 67bool in_gcc_attribute;
68bool in_system_header; 68bool in_system_header;
69 69
70/* 70/*
71 * Valid values for 'since' are 78, 90, 99, 11. 71 * Valid values for 'since' are 78, 90, 99, 11.
72 * 72 *
73 * The C11 keywords are added in C99 mode as well, to provide good error 73 * The C11 keywords are added in C99 mode as well, to provide good error
74 * messages instead of a simple parse error. If the keyword '_Generic' were 74 * messages instead of a simple parse error. If the keyword '_Generic' were
75 * not defined, it would be interpreted as an implicit function call, leading 75 * not defined, it would be interpreted as an implicit function call, leading
76 * to a parse error. 76 * to a parse error.
77 */ 77 */
78#define kwdef(name, token, scl, tspec, tqual, since, gcc, deco) \ 78#define kwdef(name, token, scl, tspec, tqual, since, gcc, deco) \
79 { \ 79 { \
80 name, token, scl, tspec, tqual, \ 80 name, token, scl, tspec, tqual, \
81 (since) == 90, \ 81 (since) == 90, \
82 /* CONSTCOND */ (since) == 99 || (since) == 11, \ 82 /* CONSTCOND */ (since) == 99 || (since) == 11, \
83 (gcc) > 0, \ 83 (gcc) > 0, \
84 ((deco) & 1) != 0, ((deco) & 2) != 0, ((deco) & 4) != 0, \ 84 ((deco) & 1) != 0, ((deco) & 2) != 0, ((deco) & 4) != 0, \
85 } 85 }
86#define kwdef_token(name, token, since, gcc, deco) \ 86#define kwdef_token(name, token, since, gcc, deco) \
87 kwdef(name, token, 0, 0, 0, since, gcc, deco) 87 kwdef(name, token, 0, 0, 0, since, gcc, deco)
88#define kwdef_sclass(name, sclass, since, gcc, deco) \ 88#define kwdef_sclass(name, sclass, since, gcc, deco) \
89 kwdef(name, T_SCLASS, sclass, 0, 0, since, gcc, deco) 89 kwdef(name, T_SCLASS, sclass, 0, 0, since, gcc, deco)
90#define kwdef_type(name, tspec, since) \ 90#define kwdef_type(name, tspec, since) \
91 kwdef(name, T_TYPE, 0, tspec, 0, since, 0, 1) 91 kwdef(name, T_TYPE, 0, tspec, 0, since, 0, 1)
92#define kwdef_tqual(name, tqual, since, gcc, deco) \ 92#define kwdef_tqual(name, tqual, since, gcc, deco) \
93 kwdef(name, T_QUAL, 0, 0, tqual, since, gcc, deco) 93 kwdef(name, T_QUAL, 0, 0, tqual, since, gcc, deco)
94#define kwdef_keyword(name, token) \ 94#define kwdef_keyword(name, token) \
95 kwdef(name, token, 0, 0, 0, 78, 0, 1) 95 kwdef(name, token, 0, 0, 0, 78, 0, 1)
96 96
97/* During initialization, these keywords are written to the symbol table. */ 97/* During initialization, these keywords are written to the symbol table. */
98static const struct keyword { 98static const struct keyword {
99 const char *kw_name; 99 const char *kw_name;
100 int kw_token; /* token returned by yylex() */ 100 int kw_token; /* token returned by yylex() */
101 scl_t kw_scl; /* storage class if kw_token is T_SCLASS */ 101 scl_t kw_scl; /* storage class if kw_token is T_SCLASS */
102 tspec_t kw_tspec; /* type specifier if kw_token is T_TYPE or 102 tspec_t kw_tspec; /* type specifier if kw_token is T_TYPE or
103 * T_STRUCT_OR_UNION */ 103 * T_STRUCT_OR_UNION */
104 tqual_t kw_tqual; /* type qualifier if kw_token is T_QUAL */ 104 tqual_t kw_tqual; /* type qualifier if kw_token is T_QUAL */
105 bool kw_c90:1; /* available in C90 mode */ 105 bool kw_c90:1; /* available in C90 mode */
106 bool kw_c99_or_c11:1; /* available in C99 or C11 mode */ 106 bool kw_c99_or_c11:1; /* available in C99 or C11 mode */
107 bool kw_gcc:1; /* available in GCC mode */ 107 bool kw_gcc:1; /* available in GCC mode */
108 bool kw_plain:1; /* 'name' */ 108 bool kw_plain:1; /* 'name' */
109 bool kw_leading:1; /* '__name' */ 109 bool kw_leading:1; /* '__name' */
110 bool kw_both:1; /* '__name__' */ 110 bool kw_both:1; /* '__name__' */
111} keywords[] = { 111} keywords[] = {
112 kwdef_keyword( "_Alignas", T_ALIGNAS), 112 kwdef_keyword( "_Alignas", T_ALIGNAS),
113 kwdef_keyword( "_Alignof", T_ALIGNOF), 113 kwdef_keyword( "_Alignof", T_ALIGNOF),
114 kwdef_token( "alignof", T_ALIGNOF, 78,0,6), 114 kwdef_token( "alignof", T_ALIGNOF, 78,0,6),
115 kwdef_token( "asm", T_ASM, 78,1,7), 115 kwdef_token( "asm", T_ASM, 78,1,7),
116 kwdef_token( "_Atomic", T_ATOMIC, 11,0,1), 116 kwdef_token( "_Atomic", T_ATOMIC, 11,0,1),
117 kwdef_token( "attribute", T_ATTRIBUTE, 78,1,6), 117 kwdef_token( "attribute", T_ATTRIBUTE, 78,1,6),
118 kwdef_sclass( "auto", AUTO, 78,0,1), 118 kwdef_sclass( "auto", AUTO, 78,0,1),
119 kwdef_type( "_Bool", BOOL, 99), 119 kwdef_type( "_Bool", BOOL, 99),
120 kwdef_keyword( "break", T_BREAK), 120 kwdef_keyword( "break", T_BREAK),
121 kwdef_token( "__builtin_offsetof", T_BUILTIN_OFFSETOF, 78,1,1), 121 kwdef_token( "__builtin_offsetof", T_BUILTIN_OFFSETOF, 78,1,1),
122 kwdef_keyword( "case", T_CASE), 122 kwdef_keyword( "case", T_CASE),
123 kwdef_type( "char", CHAR, 78), 123 kwdef_type( "char", CHAR, 78),
124 kwdef_type( "_Complex", COMPLEX, 99), 124 kwdef_type( "_Complex", COMPLEX, 99),
125 kwdef_tqual( "const", CONST, 90,0,7), 125 kwdef_tqual( "const", CONST, 90,0,7),
126 kwdef_keyword( "continue", T_CONTINUE), 126 kwdef_keyword( "continue", T_CONTINUE),
127 kwdef_keyword( "default", T_DEFAULT), 127 kwdef_keyword( "default", T_DEFAULT),
128 kwdef_keyword( "do", T_DO), 128 kwdef_keyword( "do", T_DO),
129 kwdef_type( "double", DOUBLE, 78), 129 kwdef_type( "double", DOUBLE, 78),
130 kwdef_keyword( "else", T_ELSE), 130 kwdef_keyword( "else", T_ELSE),
131 kwdef_keyword( "enum", T_ENUM), 131 kwdef_keyword( "enum", T_ENUM),
132 kwdef_token( "__extension__",T_EXTENSION, 78,1,1), 132 kwdef_token( "__extension__",T_EXTENSION, 78,1,1),
133 kwdef_sclass( "extern", EXTERN, 78,0,1), 133 kwdef_sclass( "extern", EXTERN, 78,0,1),
134 kwdef_type( "float", FLOAT, 78), 134 kwdef_type( "float", FLOAT, 78),
135 kwdef_keyword( "for", T_FOR), 135 kwdef_keyword( "for", T_FOR),
136 kwdef_token( "_Generic", T_GENERIC, 11,0,1), 136 kwdef_token( "_Generic", T_GENERIC, 11,0,1),
137 kwdef_keyword( "goto", T_GOTO), 137 kwdef_keyword( "goto", T_GOTO),
138 kwdef_keyword( "if", T_IF), 138 kwdef_keyword( "if", T_IF),
139 kwdef_token( "__imag__", T_IMAG, 78,1,1), 139 kwdef_token( "__imag__", T_IMAG, 78,1,1),
140 kwdef_sclass( "inline", INLINE, 99,0,7), 140 kwdef_sclass( "inline", INLINE, 99,0,7),
141 kwdef_type( "int", INT, 78), 141 kwdef_type( "int", INT, 78),
142#ifdef INT128_SIZE 142#ifdef INT128_SIZE
143 kwdef_type( "__int128_t", INT128, 99), 143 kwdef_type( "__int128_t", INT128, 99),
144#endif 144#endif
145 kwdef_type( "long", LONG, 78), 145 kwdef_type( "long", LONG, 78),
146 kwdef_token( "_Noreturn", T_NORETURN, 11,0,1), 146 kwdef_token( "_Noreturn", T_NORETURN, 11,0,1),
147 kwdef_token( "__packed", T_PACKED, 78,0,1), 147 kwdef_token( "__packed", T_PACKED, 78,0,1),
148 kwdef_token( "__real__", T_REAL, 78,1,1), 148 kwdef_token( "__real__", T_REAL, 78,1,1),
149 kwdef_sclass( "register", REG, 78,0,1), 149 kwdef_sclass( "register", REG, 78,0,1),
150 kwdef_tqual( "restrict", RESTRICT, 99,0,7), 150 kwdef_tqual( "restrict", RESTRICT, 99,0,7),
151 kwdef_keyword( "return", T_RETURN), 151 kwdef_keyword( "return", T_RETURN),
152 kwdef_type( "short", SHORT, 78), 152 kwdef_type( "short", SHORT, 78),
153 kwdef( "signed", T_TYPE, 0, SIGNED, 0, 90,0,3), 153 kwdef( "signed", T_TYPE, 0, SIGNED, 0, 90,0,3),
154 kwdef_keyword( "sizeof", T_SIZEOF), 154 kwdef_keyword( "sizeof", T_SIZEOF),
155 kwdef_sclass( "static", STATIC, 78,0,1), 155 kwdef_sclass( "static", STATIC, 78,0,1),
156 kwdef_keyword( "_Static_assert", T_STATIC_ASSERT), 156 kwdef_keyword( "_Static_assert", T_STATIC_ASSERT),
157 kwdef("struct", T_STRUCT_OR_UNION, 0, STRUCT, 0, 78,0,1), 157 kwdef("struct", T_STRUCT_OR_UNION, 0, STRUCT, 0, 78,0,1),
158 kwdef_keyword( "switch", T_SWITCH), 158 kwdef_keyword( "switch", T_SWITCH),
159 kwdef_token( "__symbolrename", T_SYMBOLRENAME, 78,0,1), 159 kwdef_token( "__symbolrename", T_SYMBOLRENAME, 78,0,1),
160 kwdef_tqual( "__thread", THREAD, 78,1,1), 160 kwdef_tqual( "__thread", THREAD, 78,1,1),
161 /* XXX: _Thread_local is a storage-class-specifier, not tqual. */ 161 /* XXX: _Thread_local is a storage-class-specifier, not tqual. */
162 kwdef_tqual( "_Thread_local", THREAD, 11,0,1), 162 kwdef_tqual( "_Thread_local", THREAD, 11,0,1),
163 kwdef_sclass( "typedef", TYPEDEF, 78,0,1), 163 kwdef_sclass( "typedef", TYPEDEF, 78,0,1),
164 kwdef_token( "typeof", T_TYPEOF, 78,1,7), 164 kwdef_token( "typeof", T_TYPEOF, 78,1,7),
165#ifdef INT128_SIZE 165#ifdef INT128_SIZE
166 kwdef_type( "__uint128_t", UINT128, 99), 166 kwdef_type( "__uint128_t", UINT128, 99),
167#endif 167#endif
168 kwdef("union", T_STRUCT_OR_UNION, 0, UNION, 0, 78,0,1), 168 kwdef("union", T_STRUCT_OR_UNION, 0, UNION, 0, 78,0,1),
169 kwdef_type( "unsigned", UNSIGN, 78), 169 kwdef_type( "unsigned", UNSIGN, 78),
170 kwdef_type( "void", VOID, 78), 170 kwdef_type( "void", VOID, 78),
171 kwdef_tqual( "volatile", VOLATILE, 90,0,7), 171 kwdef_tqual( "volatile", VOLATILE, 90,0,7),
172 kwdef_keyword( "while", T_WHILE), 172 kwdef_keyword( "while", T_WHILE),
173#undef kwdef 173#undef kwdef
174#undef kwdef_token 174#undef kwdef_token
175#undef kwdef_sclass 175#undef kwdef_sclass
176#undef kwdef_type 176#undef kwdef_type
177#undef kwdef_tqual 177#undef kwdef_tqual
178#undef kwdef_keyword 178#undef kwdef_keyword
179}; 179};
180 180
181/* 181/*
182 * The symbol table containing all keywords, identifiers and labels. The hash 182 * The symbol table containing all keywords, identifiers and labels. The hash
183 * entries are linked via sym_t.s_symtab_next. 183 * entries are linked via sym_t.s_symtab_next.
184 */ 184 */
185static sym_t *symtab[HSHSIZ1]; 185static sym_t *symtab[HSHSIZ1];
186 186
187/* 187/*
188 * The kind of the next expected symbol, to distinguish the namespaces of 188 * The kind of the next expected symbol, to distinguish the namespaces of
189 * members, labels, type tags and other identifiers. 189 * members, labels, type tags and other identifiers.
190 */ 190 */
191symt_t symtyp; 191symt_t symtyp;
192 192
193 193
194static unsigned int 194static unsigned int
195hash(const char *s) 195hash(const char *s)
196{ 196{
197 unsigned int v; 197 unsigned int v;
198 const char *p; 198 const char *p;
199 199
200 v = 0; 200 v = 0;
201 for (p = s; *p != '\0'; p++) { 201 for (p = s; *p != '\0'; p++) {
202 v = (v << 4) + (unsigned char)*p; 202 v = (v << 4) + (unsigned char)*p;
203 v ^= v >> 28; 203 v ^= v >> 28;
204 } 204 }
205 return v % HSHSIZ1; 205 return v % HSHSIZ1;
206} 206}
207 207
208static void 208static void
209symtab_add(sym_t *sym) 209symtab_add(sym_t *sym)
210{ 210{
211 unsigned int h; 211 unsigned int h;
212 212
213 h = hash(sym->s_name); 213 h = hash(sym->s_name);
214 if ((sym->s_symtab_next = symtab[h]) != NULL) 214 if ((sym->s_symtab_next = symtab[h]) != NULL)
215 symtab[h]->s_symtab_ref = &sym->s_symtab_next; 215 symtab[h]->s_symtab_ref = &sym->s_symtab_next;
216 sym->s_symtab_ref = &symtab[h]; 216 sym->s_symtab_ref = &symtab[h];
217 symtab[h] = sym; 217 symtab[h] = sym;
218} 218}
219 219
220static sym_t * 220static sym_t *
221symtab_search(const char *name) 221symtab_search(const char *name)
222{ 222{
223 223
224 unsigned int h = hash(name); 224 unsigned int h = hash(name);
225 for (sym_t *sym = symtab[h]; sym != NULL; sym = sym->s_symtab_next) { 225 for (sym_t *sym = symtab[h]; sym != NULL; sym = sym->s_symtab_next) {
226 if (strcmp(sym->s_name, name) != 0) 226 if (strcmp(sym->s_name, name) != 0)
227 continue; 227 continue;
228 if (sym->s_keyword != NULL || 228 if (sym->s_keyword != NULL ||
229 sym->s_kind == symtyp || 229 sym->s_kind == symtyp ||
230 in_gcc_attribute) 230 in_gcc_attribute)
231 return sym; 231 return sym;
232 } 232 }
233 233
234 return NULL; 234 return NULL;
235} 235}
236 236
237static void 237static void
238symtab_remove(sym_t *sym) 238symtab_remove(sym_t *sym)
239{ 239{
240 240
241 if ((*sym->s_symtab_ref = sym->s_symtab_next) != NULL) 241 if ((*sym->s_symtab_ref = sym->s_symtab_next) != NULL)
242 sym->s_symtab_next->s_symtab_ref = sym->s_symtab_ref; 242 sym->s_symtab_next->s_symtab_ref = sym->s_symtab_ref;
243 sym->s_symtab_next = NULL; 243 sym->s_symtab_next = NULL;
244} 244}
245 245
246static void 246static void
247symtab_remove_locals(void) 247symtab_remove_locals(void)
248{ 248{
249 249
250 for (size_t i = 0; i < HSHSIZ1; i++) { 250 for (size_t i = 0; i < HSHSIZ1; i++) {
251 for (sym_t *sym = symtab[i]; sym != NULL; ) { 251 for (sym_t *sym = symtab[i]; sym != NULL; ) {
252 sym_t *next = sym->s_symtab_next; 252 sym_t *next = sym->s_symtab_next;
253 if (sym->s_block_level >= 1) 253 if (sym->s_block_level >= 1)
254 symtab_remove(sym); 254 symtab_remove(sym);
255 sym = next; 255 sym = next;
256 } 256 }
257 } 257 }
258} 258}
259 259
260#ifdef DEBUG 260#ifdef DEBUG
261static int 261static int
262sym_by_name(const void *va, const void *vb) 262sym_by_name(const void *va, const void *vb)
263{ 263{
264 const sym_t *a = *(const sym_t *const *)va; 264 const sym_t *a = *(const sym_t *const *)va;
265 const sym_t *b = *(const sym_t *const *)vb; 265 const sym_t *b = *(const sym_t *const *)vb;
266 266
267 return strcmp(a->s_name, b->s_name); 267 return strcmp(a->s_name, b->s_name);
268} 268}
269 269
270struct syms { 270struct syms {
271 const sym_t **items; 271 const sym_t **items;
272 size_t len; 272 size_t len;
273 size_t cap; 273 size_t cap;
274}; 274};
275 275
276static void 276static void
277syms_add(struct syms *syms, const sym_t *sym) 277syms_add(struct syms *syms, const sym_t *sym)
278{ 278{
279 if (syms->len >= syms->cap) { 279 if (syms->len >= syms->cap) {
280 syms->cap *= 2; 280 syms->cap *= 2;
281 syms->items = xrealloc(syms->items, 281 syms->items = xrealloc(syms->items,
282 syms->cap * sizeof(syms->items[0])); 282 syms->cap * sizeof(syms->items[0]));
283 } 283 }
284 syms->items[syms->len++] = sym; 284 syms->items[syms->len++] = sym;
285} 285}
286 286
287void 287void
288debug_symtab(void) 288debug_symtab(void)
289{ 289{
290 struct syms syms = { xcalloc(64, sizeof(syms.items[0])), 0, 64 }; 290 struct syms syms = { xcalloc(64, sizeof(syms.items[0])), 0, 64 };
291 291
292 for (int level = -1;; level++) { 292 for (int level = -1;; level++) {
293 bool more = false; 293 bool more = false;
294 size_t n = sizeof(symtab) / sizeof(symtab[0]); 294 size_t n = sizeof(symtab) / sizeof(symtab[0]);
295 295
296 syms.len = 0; 296 syms.len = 0;
297 for (size_t i = 0; i < n; i++) { 297 for (size_t i = 0; i < n; i++) {
298 for (sym_t *sym = symtab[i]; sym != NULL;) { 298 for (sym_t *sym = symtab[i]; sym != NULL;) {
299 if (sym->s_block_level == level && 299 if (sym->s_block_level == level &&
300 sym->s_keyword == NULL) 300 sym->s_keyword == NULL)
301 syms_add(&syms, sym); 301 syms_add(&syms, sym);
302 if (sym->s_block_level > level) 302 if (sym->s_block_level > level)
303 more = true; 303 more = true;
304 sym = sym->s_symtab_next; 304 sym = sym->s_symtab_next;
305 } 305 }
306 } 306 }
307 307
308 if (syms.len > 0) { 308 if (syms.len > 0) {
309 debug_printf("symbol table level %d\n", level); 309 debug_printf("symbol table level %d\n", level);
310 debug_indent_inc(); 310 debug_indent_inc();
311 qsort(syms.items, syms.len, sizeof(syms.items[0]), 311 qsort(syms.items, syms.len, sizeof(syms.items[0]),
312 sym_by_name); 312 sym_by_name);
313 for (size_t i = 0; i < syms.len; i++) 313 for (size_t i = 0; i < syms.len; i++)
314 debug_sym("", syms.items[i], "\n"); 314 debug_sym("", syms.items[i], "\n");
315 debug_indent_dec(); 315 debug_indent_dec();
316 316
317 lint_assert(level != -1); 317 lint_assert(level != -1);
318 } 318 }
319 319
320 if (!more) 320 if (!more)
321 break; 321 break;
322 } 322 }
323 323
324 free(syms.items); 324 free(syms.items);
325} 325}
326#endif 326#endif
327 327
328static void 328static void
329add_keyword(const struct keyword *kw, bool leading, bool trailing) 329add_keyword(const struct keyword *kw, bool leading, bool trailing)
330{ 330{
331 331
332 const char *name; 332 const char *name;
333 if (!leading && !trailing) { 333 if (!leading && !trailing) {
334 name = kw->kw_name; 334 name = kw->kw_name;
335 } else { 335 } else {
336 char buf[256]; 336 char buf[256];
337 (void)snprintf(buf, sizeof(buf), "%s%s%s", 337 (void)snprintf(buf, sizeof(buf), "%s%s%s",
338 leading ? "__" : "", kw->kw_name, trailing ? "__" : ""); 338 leading ? "__" : "", kw->kw_name, trailing ? "__" : "");
339 name = xstrdup(buf); 339 name = xstrdup(buf);
340 } 340 }
341 341
342 sym_t *sym = block_zero_alloc(sizeof(*sym)); 342 sym_t *sym = block_zero_alloc(sizeof(*sym));
343 sym->s_name = name; 343 sym->s_name = name;
344 sym->s_keyword = kw; 344 sym->s_keyword = kw;
345 int tok = kw->kw_token; 345 int tok = kw->kw_token;
346 sym->u.s_keyword.sk_token = tok; 346 sym->u.s_keyword.sk_token = tok;
347 if (tok == T_TYPE || tok == T_STRUCT_OR_UNION) 347 if (tok == T_TYPE || tok == T_STRUCT_OR_UNION)
348 sym->u.s_keyword.sk_tspec = kw->kw_tspec; 348 sym->u.s_keyword.sk_tspec = kw->kw_tspec;
349 if (tok == T_SCLASS) 349 if (tok == T_SCLASS)
350 sym->s_scl = kw->kw_scl; 350 sym->s_scl = kw->kw_scl;
351 if (tok == T_QUAL) 351 if (tok == T_QUAL)
352 sym->u.s_keyword.sk_qualifier = kw->kw_tqual; 352 sym->u.s_keyword.sk_qualifier = kw->kw_tqual;
353 353
354 symtab_add(sym); 354 symtab_add(sym);
355} 355}
356 356
357static bool 357static bool
358is_keyword_known(const struct keyword *kw) 358is_keyword_known(const struct keyword *kw)
359{ 359{
360 360
361 if ((kw->kw_c90 || kw->kw_c99_or_c11) && !allow_c90) 361 if ((kw->kw_c90 || kw->kw_c99_or_c11) && !allow_c90)
362 return false; 362 return false;
363 363
364 /* 364 /*
365 * In the 1990s, GCC defined several keywords that were later 365 * In the 1990s, GCC defined several keywords that were later
366 * incorporated into C99, therefore in GCC mode, all C99 keywords are 366 * incorporated into C99, therefore in GCC mode, all C99 keywords are
367 * made available. The C11 keywords are made available as well, but 367 * made available. The C11 keywords are made available as well, but
368 * there are so few that they don't matter practically. 368 * there are so few that they don't matter practically.
369 */ 369 */
370 if (allow_gcc) 370 if (allow_gcc)
371 return true; 371 return true;
372 if (kw->kw_gcc) 372 if (kw->kw_gcc)
373 return false; 373 return false;
374 374
375 if (kw->kw_c99_or_c11 && !allow_c99) 375 if (kw->kw_c99_or_c11 && !allow_c99)
376 return false; 376 return false;
377 return true; 377 return true;
378} 378}
379 379
380/* Write all keywords to the symbol table. */ 380/* Write all keywords to the symbol table. */
381void 381void
382initscan(void) 382initscan(void)
383{ 383{
384 384
385 size_t n = sizeof(keywords) / sizeof(keywords[0]); 385 size_t n = sizeof(keywords) / sizeof(keywords[0]);
386 for (size_t i = 0; i < n; i++) { 386 for (size_t i = 0; i < n; i++) {
387 const struct keyword *kw = keywords + i; 387 const struct keyword *kw = keywords + i;
388 if (!is_keyword_known(kw)) 388 if (!is_keyword_known(kw))
389 continue; 389 continue;
390 if (kw->kw_plain) 390 if (kw->kw_plain)
391 add_keyword(kw, false, false); 391 add_keyword(kw, false, false);
392 if (kw->kw_leading) 392 if (kw->kw_leading)
393 add_keyword(kw, true, false); 393 add_keyword(kw, true, false);
394 if (kw->kw_both) 394 if (kw->kw_both)
395 add_keyword(kw, true, true); 395 add_keyword(kw, true, true);
396 } 396 }
397} 397}
398 398
399/* 399/*
400 * When scanning the remainder of a long token (see lex_input), read a byte 400 * When scanning the remainder of a long token (see lex_input), read a byte
401 * and return it as an unsigned char or as EOF. 401 * and return it as an unsigned char or as EOF.
402 * 402 *
403 * Increment the line counts if necessary. 403 * Increment the line counts if necessary.
404 */ 404 */
405static int 405static int
406read_byte(void) 406read_byte(void)
407{ 407{
408 int c; 408 int c;
409 409
410 if ((c = lex_input()) == EOF) 410 if ((c = lex_input()) == EOF)
411 return c; 411 return c;
412 if (c == '\0') 412 if (c == '\0')
413 return EOF; /* lex returns 0 on EOF. */ 413 return EOF; /* lex returns 0 on EOF. */
414 if (c == '\n') 414 if (c == '\n')
415 lex_next_line(); 415 lex_next_line();
416 return c; 416 return c;
417} 417}
418 418
419static int 419static int
420lex_keyword(sym_t *sym) 420lex_keyword(sym_t *sym)
421{ 421{
422 int tok = sym->u.s_keyword.sk_token; 422 int tok = sym->u.s_keyword.sk_token;
423 423
424 if (tok == T_SCLASS) 424 if (tok == T_SCLASS)
425 yylval.y_scl = sym->s_scl; 425 yylval.y_scl = sym->s_scl;
426 if (tok == T_TYPE || tok == T_STRUCT_OR_UNION) 426 if (tok == T_TYPE || tok == T_STRUCT_OR_UNION)
427 yylval.y_tspec = sym->u.s_keyword.sk_tspec; 427 yylval.y_tspec = sym->u.s_keyword.sk_tspec;
428 if (tok == T_QUAL) 428 if (tok == T_QUAL)
429 yylval.y_tqual = sym->u.s_keyword.sk_qualifier; 429 yylval.y_tqual = sym->u.s_keyword.sk_qualifier;
430 return tok; 430 return tok;
431} 431}
432 432
433/* 433/*
434 * Look up the definition of a name in the symbol table. This symbol must 434 * Look up the definition of a name in the symbol table. This symbol must
435 * either be a keyword or a symbol of the type required by symtyp (label, 435 * either be a keyword or a symbol of the type required by symtyp (label,
436 * member, tag, ...). 436 * member, tag, ...).
437 */ 437 */
438extern int 438extern int
439lex_name(const char *yytext, size_t yyleng) 439lex_name(const char *yytext, size_t yyleng)
440{ 440{
441 441
442 sym_t *sym = symtab_search(yytext); 442 sym_t *sym = symtab_search(yytext);
443 if (sym != NULL && sym->s_keyword != NULL) 443 if (sym != NULL && sym->s_keyword != NULL)
444 return lex_keyword(sym); 444 return lex_keyword(sym);
445 445
446 sbuf_t *sb = xmalloc(sizeof(*sb)); 446 sbuf_t *sb = xmalloc(sizeof(*sb));
447 sb->sb_len = yyleng; 447 sb->sb_len = yyleng;
448 sb->sb_sym = sym; 448 sb->sb_sym = sym;
449 yylval.y_name = sb; 449 yylval.y_name = sb;
450 450
451 if (sym != NULL) { 451 if (sym != NULL) {
452 lint_assert(block_level >= sym->s_block_level); 452 lint_assert(block_level >= sym->s_block_level);
453 sb->sb_name = sym->s_name; 453 sb->sb_name = sym->s_name;
454 return sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME; 454 return sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME;
455 } 455 }
456 456
457 char *name = block_zero_alloc(yyleng + 1); 457 char *name = block_zero_alloc(yyleng + 1);
458 (void)memcpy(name, yytext, yyleng + 1); 458 (void)memcpy(name, yytext, yyleng + 1);
459 sb->sb_name = name; 459 sb->sb_name = name;
460 return T_NAME; 460 return T_NAME;
461} 461}
462 462
463int 463int
464lex_integer_constant(const char *yytext, size_t yyleng, int base) 464lex_integer_constant(const char *yytext, size_t yyleng, int base)
465{ 465{
466 /* C11 6.4.4.1p5 */ 466 /* C11 6.4.4.1p5 */
467 static const tspec_t suffix_type[2][3] = { 467 static const tspec_t suffix_type[2][3] = {
468 { INT, LONG, QUAD, }, 468 { INT, LONG, QUAD, },
469 { UINT, ULONG, UQUAD, } 469 { UINT, ULONG, UQUAD, }
470 }; 470 };
471 471
472 const char *cp = yytext; 472 const char *cp = yytext;
473 size_t len = yyleng; 473 size_t len = yyleng;
474 474
475 /* skip 0[xX] or 0[bB] */ 475 /* skip 0[xX] or 0[bB] */
476 if (base == 16 || base == 2) { 476 if (base == 16 || base == 2) {
477 cp += 2; 477 cp += 2;
478 len -= 2; 478 len -= 2;
479 } 479 }
480 480
481 /* read suffixes */ 481 /* read suffixes */
482 unsigned l_suffix = 0, u_suffix = 0; 482 unsigned l_suffix = 0, u_suffix = 0;
483 for (;; len--) { 483 for (;; len--) {
484 char c = cp[len - 1]; 484 char c = cp[len - 1];
485 if (c == 'l' || c == 'L') 485 if (c == 'l' || c == 'L')
486 l_suffix++; 486 l_suffix++;
487 else if (c == 'u' || c == 'U') 487 else if (c == 'u' || c == 'U')
488 u_suffix++; 488 u_suffix++;
489 else 489 else
490 break; 490 break;
491 } 491 }
492 if (l_suffix > 2 || u_suffix > 1) { 492 if (l_suffix > 2 || u_suffix > 1) {
493 /* malformed integer constant */ 493 /* malformed integer constant */
494 warning(251); 494 warning(251);
495 if (l_suffix > 2) 495 if (l_suffix > 2)
496 l_suffix = 2; 496 l_suffix = 2;
497 if (u_suffix > 1) 497 if (u_suffix > 1)
498 u_suffix = 1; 498 u_suffix = 1;
499 } 499 }
500 if (!allow_c90 && u_suffix > 0) { 500 if (!allow_c90 && u_suffix > 0) {
501 /* suffix U is illegal in traditional C */ 501 /* suffix U is illegal in traditional C */
502 warning(97); 502 warning(97);
503 } 503 }
504 tspec_t typ = suffix_type[u_suffix][l_suffix]; 504 tspec_t typ = suffix_type[u_suffix][l_suffix];
505 505
506 bool warned = false; 506 bool warned = false;
507 errno = 0; 507 errno = 0;
508 char *eptr; 508 char *eptr;
509 uint64_t uq = (uint64_t)strtoull(cp, &eptr, base); 509 uint64_t uq = (uint64_t)strtoull(cp, &eptr, base);
510 lint_assert(eptr == cp + len); 510 lint_assert(eptr == cp + len);
511 if (errno != 0) { 511 if (errno != 0) {
512 /* integer constant out of range */ 512 /* integer constant out of range */
513 warning(252); 513 warning(252);
514 warned = true; 514 warned = true;
515 } 515 }
516 516
517 if (any_query_enabled && base == 8 && uq != 0) { 517 if (any_query_enabled && base == 8 && uq != 0) {
518 /* octal number '%.*s' */ 518 /* octal number '%.*s' */
519 query_message(8, (int)len, cp); 519 query_message(8, (int)len, cp);
520 } 520 }
521 521
522 /* 522 /*
523 * If the value is too big for the current type, we must choose 523 * If the value is too big for the current type, we must choose
524 * another type. 524 * another type.
525 */ 525 */
526 bool ansiu = false; 526 bool ansiu = false;
527 switch (typ) { 527 switch (typ) {
528 case INT: 528 case INT:
529 if (uq <= TARG_INT_MAX) { 529 if (uq <= TARG_INT_MAX) {
530 /* ok */ 530 /* ok */
531 } else if (uq <= TARG_UINT_MAX && base != 10) { 531 } else if (uq <= TARG_UINT_MAX && base != 10) {
532 typ = UINT; 532 typ = UINT;
533 } else if (uq <= TARG_LONG_MAX) { 533 } else if (uq <= TARG_LONG_MAX) {
534 typ = LONG; 534 typ = LONG;
535 } else { 535 } else {
536 typ = ULONG; 536 typ = ULONG;
537 if (uq > TARG_ULONG_MAX && !warned) { 537 if (uq > TARG_ULONG_MAX && !warned) {
538 /* integer constant out of range */ 538 /* integer constant out of range */
539 warning(252); 539 warning(252);
540 } 540 }
541 } 541 }
542 if (typ == UINT || typ == ULONG) { 542 if (typ == UINT || typ == ULONG) {
543 if (!allow_c90) { 543 if (!allow_c90) {
544 typ = LONG; 544 typ = LONG;
545 } else if (allow_trad) { 545 } else if (allow_trad) {
546 /* 546 /*
547 * Remember that the constant is unsigned 547 * Remember that the constant is unsigned
548 * only in ANSI C. 548 * only in ANSI C.
549 */ 549 */
550 ansiu = true; 550 ansiu = true;
551 } 551 }
552 } 552 }
553 break; 553 break;
554 case UINT: 554 case UINT:
555 if (uq > TARG_UINT_MAX) { 555 if (uq > TARG_UINT_MAX) {
556 typ = ULONG; 556 typ = ULONG;
557 if (uq > TARG_ULONG_MAX && !warned) { 557 if (uq > TARG_ULONG_MAX && !warned) {
558 /* integer constant out of range */ 558 /* integer constant out of range */
559 warning(252); 559 warning(252);
560 } 560 }
561 } 561 }
562 break; 562 break;
563 case LONG: 563 case LONG:
564 if (uq > TARG_LONG_MAX && allow_c90) { 564 if (uq > TARG_LONG_MAX && allow_c90) {
565 typ = ULONG; 565 typ = ULONG;
566 if (allow_trad) 566 if (allow_trad)
567 ansiu = true; 567 ansiu = true;
568 if (uq > TARG_ULONG_MAX && !warned) { 568 if (uq > TARG_ULONG_MAX && !warned) {
569 /* integer constant out of range */ 569 /* integer constant out of range */
570 warning(252); 570 warning(252);
571 } 571 }
572 } 572 }
573 break; 573 break;
574 case ULONG: 574 case ULONG:
575 if (uq > TARG_ULONG_MAX && !warned) { 575 if (uq > TARG_ULONG_MAX && !warned) {
576 /* integer constant out of range */ 576 /* integer constant out of range */
577 warning(252); 577 warning(252);
578 } 578 }
579 break; 579 break;
580 case QUAD: 580 case QUAD:
581 if (uq > TARG_QUAD_MAX && allow_c90) 581 if (uq > TARG_QUAD_MAX && allow_c90)
582 typ = UQUAD; 582 typ = UQUAD;
583 break; 583 break;
584 case UQUAD: 584 case UQUAD:
585 if (uq > TARG_UQUAD_MAX && !warned) { 585 if (uq > TARG_UQUAD_MAX && !warned) {
586 /* integer constant out of range */ 586 /* integer constant out of range */
587 warning(252); 587 warning(252);
588 } 588 }
589 break; 589 break;
590 default: 590 default:
591 break; 591 break;
592 } 592 }
593 593
594 uq = (uint64_t)convert_integer((int64_t)uq, typ, 0); 594 uq = (uint64_t)convert_integer((int64_t)uq, typ, 0);
595 595
596 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val)); 596 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val));
597 yylval.y_val->v_tspec = typ; 597 yylval.y_val->v_tspec = typ;
598 yylval.y_val->v_unsigned_since_c90 = ansiu; 598 yylval.y_val->v_unsigned_since_c90 = ansiu;
599 yylval.y_val->v_quad = (int64_t)uq; 599 yylval.y_val->v_quad = (int64_t)uq;
600 600
601 return T_CON; 601 return T_CON;
602} 602}
603 603
604/* 604/*
605 * Extend or truncate q to match t. If t is signed, sign-extend. 605 * Extend or truncate q to match t. If t is signed, sign-extend.
606 * 606 *
607 * len is the number of significant bits. If len is 0, len is set 607 * len is the number of significant bits. If len is 0, len is set
608 * to the width of type t. 608 * to the width of type t.
609 */ 609 */
610int64_t 610int64_t
611convert_integer(int64_t q, tspec_t t, unsigned int len) 611convert_integer(int64_t q, tspec_t t, unsigned int len)
612{ 612{
613 613
614 if (len == 0) 614 if (len == 0)
615 len = size_in_bits(t); 615 len = size_in_bits(t);
616 616
617 uint64_t vbits = value_bits(len); 617 uint64_t vbits = value_bits(len);
618 return t == PTR || is_uinteger(t) || ((q & bit(len - 1)) == 0) 618 return t == PTR || is_uinteger(t) || ((q & bit(len - 1)) == 0)
619 ? (int64_t)(q & vbits) 619 ? (int64_t)(q & vbits)
620 : (int64_t)(q | ~vbits); 620 : (int64_t)(q | ~vbits);
621} 621}
622 622
623int 623int
624lex_floating_constant(const char *yytext, size_t yyleng) 624lex_floating_constant(const char *yytext, size_t yyleng)
625{ 625{
626 const char *cp = yytext; 626 const char *cp = yytext;
627 size_t len = yyleng; 627 size_t len = yyleng;
628 628
629 if (cp[len - 1] == 'i') 629 if (cp[len - 1] == 'i')
630 len--; /* imaginary, do nothing for now */ 630 len--; /* imaginary, do nothing for now */
631 631
632 char c = cp[len - 1]; 632 char c = cp[len - 1];
633 tspec_t typ; 633 tspec_t typ;
634 if (c == 'f' || c == 'F') { 634 if (c == 'f' || c == 'F') {
635 typ = FLOAT; 635 typ = FLOAT;
636 len--; 636 len--;
637 } else if (c == 'l' || c == 'L') { 637 } else if (c == 'l' || c == 'L') {
638 typ = LDOUBLE; 638 typ = LDOUBLE;
639 len--; 639 len--;
640 } else 640 } else
641 typ = DOUBLE; 641 typ = DOUBLE;
642 642
643 if (!allow_c90 && typ != DOUBLE) { 643 if (!allow_c90 && typ != DOUBLE) {
644 /* suffixes F and L are illegal in traditional C */ 644 /* suffixes F and L are illegal in traditional C */
645 warning(98); 645 warning(98);
646 } 646 }
647 647
648 errno = 0; 648 errno = 0;
649 char *eptr; 649 char *eptr;
650 long double ld = strtold(cp, &eptr); 650 long double ld = strtold(cp, &eptr);
651 lint_assert(eptr == cp + len); 651 lint_assert(eptr == cp + len);
652 if (errno != 0) 652 if (errno != 0) {
653 /* floating-point constant out of range */ 653 /* floating-point constant out of range */
654 warning(248); 654 warning(248);
655 655 } else if (typ == FLOAT) {
656 if (typ == FLOAT) { 
657 ld = (float)ld; 656 ld = (float)ld;
658 if (isfinite(ld) == 0) { 657 if (isfinite(ld) == 0) {
659 /* floating-point constant out of range */ 658 /* floating-point constant out of range */
660 warning(248); 659 warning(248);
661 ld = ld > 0 ? FLT_MAX : -FLT_MAX; 660 ld = ld > 0 ? FLT_MAX : -FLT_MAX;
662 } 661 }
663 } else if (typ == DOUBLE) { 662 } else if (typ == DOUBLE) {
664 ld = (double)ld; 663 ld = (double)ld;
665 if (isfinite(ld) == 0) { 664 if (isfinite(ld) == 0) {
666 /* floating-point constant out of range */ 665 /* floating-point constant out of range */
667 warning(248); 666 warning(248);
668 ld = ld > 0 ? DBL_MAX : -DBL_MAX; 667 ld = ld > 0 ? DBL_MAX : -DBL_MAX;
669 } 668 }
670 } 669 }
671 670
672 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val)); 671 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val));
673 yylval.y_val->v_tspec = typ; 672 yylval.y_val->v_tspec = typ;
674 yylval.y_val->v_ldbl = ld; 673 yylval.y_val->v_ldbl = ld;
675 674
676 return T_CON; 675 return T_CON;
677} 676}
678 677
679int 678int
680lex_operator(int t, op_t o) 679lex_operator(int t, op_t o)
681{ 680{
682 681
683 yylval.y_op = o; 682 yylval.y_op = o;
684 return t; 683 return t;
685} 684}
686 685
687static int prev_byte = -1; 686static int prev_byte = -1;
688 687
689static int 688static int
690read_escaped_oct(int c) 689read_escaped_oct(int c)
691{ 690{
692 int n = 3; 691 int n = 3;
693 int value = 0; 692 int value = 0;
694 do { 693 do {
695 value = (value << 3) + (c - '0'); 694 value = (value << 3) + (c - '0');
696 c = read_byte(); 695 c = read_byte();
697 } while (--n > 0 && '0' <= c && c <= '7'); 696 } while (--n > 0 && '0' <= c && c <= '7');
698 prev_byte = c; 697 prev_byte = c;
699 if (value > TARG_UCHAR_MAX) { 698 if (value > TARG_UCHAR_MAX) {
700 /* character escape does not fit in character */ 699 /* character escape does not fit in character */
701 warning(76); 700 warning(76);
702 value &= CHAR_MASK; 701 value &= CHAR_MASK;
703 } 702 }
704 return value; 703 return value;
705} 704}
706 705
707static unsigned int 706static unsigned int
708read_escaped_hex(int c) 707read_escaped_hex(int c)
709{ 708{
710 if (!allow_c90) 709 if (!allow_c90)
711 /* \x undefined in traditional C */ 710 /* \x undefined in traditional C */
712 warning(82); 711 warning(82);
713 unsigned int value = 0; 712 unsigned int value = 0;
714 int state = 0; /* 0 = no digits, 1 = OK, 2 = overflow */ 713 int state = 0; /* 0 = no digits, 1 = OK, 2 = overflow */
715 while (c = read_byte(), isxdigit(c)) { 714 while (c = read_byte(), isxdigit(c)) {
716 c = isdigit(c) ? c - '0' : toupper(c) - 'A' + 10; 715 c = isdigit(c) ? c - '0' : toupper(c) - 'A' + 10;
717 value = (value << 4) + c; 716 value = (value << 4) + c;
718 if (state == 2) 717 if (state == 2)
719 continue; 718 continue;
720 if ((value & ~CHAR_MASK) != 0) { 719 if ((value & ~CHAR_MASK) != 0) {
721 /* overflow in hex escape */ 720 /* overflow in hex escape */
722 warning(75); 721 warning(75);
723 state = 2; 722 state = 2;
724 } else { 723 } else {
725 state = 1; 724 state = 1;
726 } 725 }
727 } 726 }
728 prev_byte = c; 727 prev_byte = c;
729 if (state == 0) { 728 if (state == 0) {
730 /* no hex digits follow \x */ 729 /* no hex digits follow \x */
731 error(74); 730 error(74);
732 } 731 }
733 if (state == 2) 732 if (state == 2)
734 value &= CHAR_MASK; 733 value &= CHAR_MASK;
735 return value; 734 return value;
736} 735}
737 736
738static int 737static int
739read_escaped_backslash(int delim) 738read_escaped_backslash(int delim)
740{ 739{
741 int c; 740 int c;
742 741
743 switch (c = read_byte()) { 742 switch (c = read_byte()) {
744 case '"': 743 case '"':
745 if (!allow_c90 && delim == '\'') 744 if (!allow_c90 && delim == '\'')
746 /* \" inside character constants undef... */ 745 /* \" inside character constants undef... */
747 warning(262); 746 warning(262);
748 return '"'; 747 return '"';
749 case '\'': 748 case '\'':
750 return '\''; 749 return '\'';
751 case '?': 750 case '?':
752 if (!allow_c90) 751 if (!allow_c90)
753 /* \? undefined in traditional C */ 752 /* \? undefined in traditional C */
754 warning(263); 753 warning(263);
755 return '?'; 754 return '?';
756 case '\\': 755 case '\\':
757 return '\\'; 756 return '\\';
758 case 'a': 757 case 'a':
759 if (!allow_c90) 758 if (!allow_c90)
760 /* \a undefined in traditional C */ 759 /* \a undefined in traditional C */
761 warning(81); 760 warning(81);
762 return '\a'; 761 return '\a';
763 case 'b': 762 case 'b':
764 return '\b'; 763 return '\b';
765 case 'f': 764 case 'f':
766 return '\f'; 765 return '\f';
767 case 'n': 766 case 'n':
768 return '\n'; 767 return '\n';
769 case 'r': 768 case 'r':
770 return '\r'; 769 return '\r';
771 case 't': 770 case 't':
772 return '\t'; 771 return '\t';
773 case 'v': 772 case 'v':
774 if (!allow_c90) 773 if (!allow_c90)
775 /* \v undefined in traditional C */ 774 /* \v undefined in traditional C */
776 warning(264); 775 warning(264);
777 return '\v'; 776 return '\v';
778 case '8': case '9': 777 case '8': case '9':
779 /* bad octal digit %c */ 778 /* bad octal digit %c */
780 warning(77, c); 779 warning(77, c);
781 /* FALLTHROUGH */ 780 /* FALLTHROUGH */
782 case '0': case '1': case '2': case '3': 781 case '0': case '1': case '2': case '3':
783 case '4': case '5': case '6': case '7': 782 case '4': case '5': case '6': case '7':
784 return read_escaped_oct(c); 783 return read_escaped_oct(c);
785 case 'x': 784 case 'x':
786 return (int)read_escaped_hex(c); 785 return (int)read_escaped_hex(c);
787 case '\n': 786 case '\n':
788 return -3; 787 return -3;
789 case EOF: 788 case EOF:
790 return -2; 789 return -2;
791 default: 790 default:
792 if (isprint(c)) { 791 if (isprint(c)) {
793 /* dubious escape \%c */ 792 /* dubious escape \%c */
794 warning(79, c); 793 warning(79, c);
795 } else { 794 } else {
796 /* dubious escape \%o */ 795 /* dubious escape \%o */
797 warning(80, c); 796 warning(80, c);
798 } 797 }
799 return c; 798 return c;
800 } 799 }
801} 800}
802 801
803/* 802/*
804 * Read a character which is part of a character constant or of a string 803 * Read a character which is part of a character constant or of a string
805 * and handle escapes. 804 * and handle escapes.
806 * 805 *
807 * 'delim' is '\'' for character constants and '"' for string literals. 806 * 'delim' is '\'' for character constants and '"' for string literals.
808 * 807 *
809 * Returns -1 if the end of the character constant or string is reached, 808 * Returns -1 if the end of the character constant or string is reached,
810 * -2 if the EOF is reached, and the character otherwise. 809 * -2 if the EOF is reached, and the character otherwise.
811 */ 810 */
812static int 811static int
813get_escaped_char(int delim) 812get_escaped_char(int delim)
814{ 813{
815 814
816 int c = prev_byte; 815 int c = prev_byte;
817 if (c != -1) 816 if (c != -1)
818 prev_byte = -1; 817 prev_byte = -1;
819 else 818 else
820 c = read_byte(); 819 c = read_byte();
821 820
822 if (c == delim) 821 if (c == delim)
823 return -1; 822 return -1;
824 switch (c) { 823 switch (c) {
825 case '\n': 824 case '\n':
826 if (!allow_c90) { 825 if (!allow_c90) {
827 /* newline in string or char constant */ 826 /* newline in string or char constant */
828 error(254); 827 error(254);
829 return -2; 828 return -2;
830 } 829 }
831 return c; 830 return c;
832 case '\0': 831 case '\0':
833 /* syntax error '%s' */ 832 /* syntax error '%s' */
834 error(249, "EOF or null byte in literal"); 833 error(249, "EOF or null byte in literal");
835 return -2; 834 return -2;
836 case EOF: 835 case EOF:
837 return -2; 836 return -2;
838 case '\\': 837 case '\\':
839 c = read_escaped_backslash(delim); 838 c = read_escaped_backslash(delim);
840 if (c == -3) 839 if (c == -3)
841 return get_escaped_char(delim); 840 return get_escaped_char(delim);
842 } 841 }
843 return c; 842 return c;
844} 843}
845 844
846/* Called if lex found a leading "'". */ 845/* Called if lex found a leading "'". */
847int 846int
848lex_character_constant(void) 847lex_character_constant(void)
849{ 848{
850 size_t n; 849 size_t n;
851 int val, c; 850 int val, c;
852 851
853 n = 0; 852 n = 0;
854 val = 0; 853 val = 0;
855 while ((c = get_escaped_char('\'')) >= 0) { 854 while ((c = get_escaped_char('\'')) >= 0) {
856 val = (int)((unsigned int)val << CHAR_SIZE) + c; 855 val = (int)((unsigned int)val << CHAR_SIZE) + c;
857 n++; 856 n++;
858 } 857 }
859 if (c == -2) { 858 if (c == -2) {
860 /* unterminated character constant */ 859 /* unterminated character constant */
861 error(253); 860 error(253);
862 } else if (n > sizeof(int) || (n > 1 && (pflag || hflag))) { 861 } else if (n > sizeof(int) || (n > 1 && (pflag || hflag))) {
863 /* 862 /*
864 * XXX: ^^ should rather be sizeof(TARG_INT). Luckily, 863 * XXX: ^^ should rather be sizeof(TARG_INT). Luckily,
865 * sizeof(int) is the same on all supported platforms. 864 * sizeof(int) is the same on all supported platforms.
866 */ 865 */
867 /* too many characters in character constant */ 866 /* too many characters in character constant */
868 error(71); 867 error(71);
869 } else if (n > 1) { 868 } else if (n > 1) {
870 /* multi-character character constant */ 869 /* multi-character character constant */
871 warning(294); 870 warning(294);
872 } else if (n == 0) { 871 } else if (n == 0) {
873 /* empty character constant */ 872 /* empty character constant */
874 error(73); 873 error(73);
875 } 874 }
876 if (n == 1) 875 if (n == 1)
877 val = (int)convert_integer(val, CHAR, CHAR_SIZE); 876 val = (int)convert_integer(val, CHAR, CHAR_SIZE);
878 877
879 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val)); 878 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val));
880 yylval.y_val->v_tspec = INT; 879 yylval.y_val->v_tspec = INT;
881 yylval.y_val->v_quad = val; 880 yylval.y_val->v_quad = val;
882 881
883 return T_CON; 882 return T_CON;
884} 883}
885 884
886/* 885/*
887 * Called if lex found a leading L\' 886 * Called if lex found a leading L\'
888 */ 887 */
889int 888int
890lex_wide_character_constant(void) 889lex_wide_character_constant(void)
891{ 890{
892 static char buf[MB_LEN_MAX + 1]; 891 static char buf[MB_LEN_MAX + 1];
893 size_t n, nmax; 892 size_t n, nmax;
894 int c; 893 int c;
895 wchar_t wc; 894 wchar_t wc;
896 895
897 nmax = MB_CUR_MAX; 896 nmax = MB_CUR_MAX;
898 897
899 n = 0; 898 n = 0;
900 while ((c = get_escaped_char('\'')) >= 0) { 899 while ((c = get_escaped_char('\'')) >= 0) {
901 if (n < nmax) 900 if (n < nmax)
902 buf[n] = (char)c; 901 buf[n] = (char)c;
903 n++; 902 n++;
904 } 903 }
905 904
906 wc = 0; 905 wc = 0;
907 906
908 if (c == -2) { 907 if (c == -2) {
909 /* unterminated character constant */ 908 /* unterminated character constant */
910 error(253); 909 error(253);
911 } else if (n == 0) { 910 } else if (n == 0) {
912 /* empty character constant */ 911 /* empty character constant */
913 error(73); 912 error(73);
914 } else if (n > nmax) { 913 } else if (n > nmax) {
915 n = nmax; 914 n = nmax;
916 /* too many characters in character constant */ 915 /* too many characters in character constant */
917 error(71); 916 error(71);
918 } else { 917 } else {
919 buf[n] = '\0'; 918 buf[n] = '\0';
920 (void)mbtowc(NULL, NULL, 0); 919 (void)mbtowc(NULL, NULL, 0);
921 if (mbtowc(&wc, buf, nmax) < 0) 920 if (mbtowc(&wc, buf, nmax) < 0)
922 /* invalid multibyte character */ 921 /* invalid multibyte character */
923 error(291); 922 error(291);
924 } 923 }
925 924
926 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val)); 925 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val));
927 yylval.y_val->v_tspec = WCHAR; 926 yylval.y_val->v_tspec = WCHAR;
928 yylval.y_val->v_quad = wc; 927 yylval.y_val->v_quad = wc;
929 928
930 return T_CON; 929 return T_CON;
931} 930}
932 931
933/* See https://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html */ 932/* See https://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html */
934static void 933static void
935parse_line_directive_flags(const char *p, 934parse_line_directive_flags(const char *p,
936 bool *is_begin, bool *is_end, bool *is_system) 935 bool *is_begin, bool *is_end, bool *is_system)
937{ 936{
938 937
939 *is_begin = false; 938 *is_begin = false;
940 *is_end = false; 939 *is_end = false;
941 *is_system = false; 940 *is_system = false;
942 941
943 while (*p != '\0') { 942 while (*p != '\0') {
944 const char *word_start, *word_end; 943 const char *word_start, *word_end;
945 944
946 while (ch_isspace(*p)) 945 while (ch_isspace(*p))
947 p++; 946 p++;
948 947
949 word_start = p; 948 word_start = p;
950 while (*p != '\0' && !ch_isspace(*p)) 949 while (*p != '\0' && !ch_isspace(*p))
951 p++; 950 p++;
952 word_end = p; 951 word_end = p;
953 952
954 if (word_end - word_start == 1 && word_start[0] == '1') 953 if (word_end - word_start == 1 && word_start[0] == '1')
955 *is_begin = true; 954 *is_begin = true;
956 if (word_end - word_start == 1 && word_start[0] == '2') 955 if (word_end - word_start == 1 && word_start[0] == '2')
957 *is_end = true; 956 *is_end = true;
958 if (word_end - word_start == 1 && word_start[0] == '3') 957 if (word_end - word_start == 1 && word_start[0] == '3')
959 *is_system = true; 958 *is_system = true;
960 /* Flag '4' is only interesting for C++. */ 959 /* Flag '4' is only interesting for C++. */
961 } 960 }
962} 961}
963 962
964/* 963/*
965 * Called for preprocessor directives. Currently implemented are: 964 * Called for preprocessor directives. Currently implemented are:
966 * # pragma [argument...] 965 * # pragma [argument...]
967 * # lineno 966 * # lineno
968 * # lineno "filename" 967 * # lineno "filename"
969 * # lineno "filename" GCC-flag... 968 * # lineno "filename" GCC-flag...
970 */ 969 */
971void 970void
972lex_directive(const char *yytext) 971lex_directive(const char *yytext)
973{ 972{
974 const char *cp, *fn; 973 const char *cp, *fn;
975 char c, *eptr; 974 char c, *eptr;
976 size_t fnl; 975 size_t fnl;
977 long ln; 976 long ln;
978 bool is_begin, is_end, is_system; 977 bool is_begin, is_end, is_system;
979 978
980 static bool first = true; 979 static bool first = true;
981 980
982 /* Go to first non-whitespace after # */ 981 /* Go to first non-whitespace after # */
983 for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++) 982 for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++)
984 continue; 983 continue;
985 984
986 if (!ch_isdigit(c)) { 985 if (!ch_isdigit(c)) {
987 if (strncmp(cp, "pragma", 6) == 0 && ch_isspace(cp[6])) 986 if (strncmp(cp, "pragma", 6) == 0 && ch_isspace(cp[6]))
988 return; 987 return;
989 error: 988 error:
990 /* undefined or invalid # directive */ 989 /* undefined or invalid # directive */
991 warning(255); 990 warning(255);
992 return; 991 return;
993 } 992 }
994 ln = strtol(--cp, &eptr, 10); 993 ln = strtol(--cp, &eptr, 10);
995 if (eptr == cp) 994 if (eptr == cp)
996 goto error; 995 goto error;
997 if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0') 996 if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0')
998 goto error; 997 goto error;
999 while ((c = *cp++) == ' ' || c == '\t') 998 while ((c = *cp++) == ' ' || c == '\t')
1000 continue; 999 continue;
1001 if (c != '\0') { 1000 if (c != '\0') {
1002 if (c != '"') 1001 if (c != '"')
1003 goto error; 1002 goto error;
1004 fn = cp; 1003 fn = cp;
1005 while ((c = *cp) != '"' && c != '\0') 1004 while ((c = *cp) != '"' && c != '\0')
1006 cp++; 1005 cp++;
1007 if (c != '"') 1006 if (c != '"')
1008 goto error; 1007 goto error;
1009 if ((fnl = cp++ - fn) > PATH_MAX) 1008 if ((fnl = cp++ - fn) > PATH_MAX)
1010 goto error; 1009 goto error;
1011 /* empty string means stdin */ 1010 /* empty string means stdin */
1012 if (fnl == 0) { 1011 if (fnl == 0) {
1013 fn = "{standard input}"; 1012 fn = "{standard input}";
1014 fnl = 16; /* strlen (fn) */ 1013 fnl = 16; /* strlen (fn) */
1015 } 1014 }
1016 curr_pos.p_file = record_filename(fn, fnl); 1015 curr_pos.p_file = record_filename(fn, fnl);
1017 /* 1016 /*
1018 * If this is the first directive, the name is the name 1017 * If this is the first directive, the name is the name
1019 * of the C source file as specified at the command line. 1018 * of the C source file as specified at the command line.
1020 * It is written to the output file. 1019 * It is written to the output file.
1021 */ 1020 */
1022 if (first) { 1021 if (first) {
1023 csrc_pos.p_file = curr_pos.p_file; 1022 csrc_pos.p_file = curr_pos.p_file;
1024 outsrc(transform_filename(curr_pos.p_file, 1023 outsrc(transform_filename(curr_pos.p_file,
1025 strlen(curr_pos.p_file))); 1024 strlen(curr_pos.p_file)));
1026 first = false; 1025 first = false;
1027 } 1026 }
1028 1027
1029 parse_line_directive_flags(cp, &is_begin, &is_end, &is_system); 1028 parse_line_directive_flags(cp, &is_begin, &is_end, &is_system);
1030 update_location(curr_pos.p_file, (int)ln, is_begin, is_end); 1029 update_location(curr_pos.p_file, (int)ln, is_begin, is_end);
1031 in_system_header = is_system; 1030 in_system_header = is_system;
1032 } 1031 }
1033 curr_pos.p_line = (int)ln - 1; 1032 curr_pos.p_line = (int)ln - 1;
1034 curr_pos.p_uniq = 0; 1033 curr_pos.p_uniq = 0;
1035 if (curr_pos.p_file == csrc_pos.p_file) { 1034 if (curr_pos.p_file == csrc_pos.p_file) {
1036 csrc_pos.p_line = (int)ln - 1; 1035 csrc_pos.p_line = (int)ln - 1;
1037 csrc_pos.p_uniq = 0; 1036 csrc_pos.p_uniq = 0;
1038 } 1037 }
1039} 1038}
1040 1039
1041/* 1040/*
1042 * Handle lint comments such as ARGSUSED. 1041 * Handle lint comments such as ARGSUSED.
1043 * 1042 *
1044 * If one of these comments is recognized, the argument, if any, is 1043 * If one of these comments is recognized, the argument, if any, is
1045 * parsed and a function which handles this comment is called. 1044 * parsed and a function which handles this comment is called.
1046 */ 1045 */
1047void 1046void
1048lex_comment(void) 1047lex_comment(void)
1049{ 1048{
1050 int c; 1049 int c;
1051 static const struct { 1050 static const struct {
1052 const char *keywd; 1051 const char *keywd;
1053 bool arg; 1052 bool arg;
1054 void (*func)(int); 1053 void (*func)(int);
1055 } keywtab[] = { 1054 } keywtab[] = {
1056 { "ARGSUSED", true, argsused }, 1055 { "ARGSUSED", true, argsused },
1057 { "BITFIELDTYPE", false, bitfieldtype }, 1056 { "BITFIELDTYPE", false, bitfieldtype },
1058 { "CONSTCOND", false, constcond }, 1057 { "CONSTCOND", false, constcond },
1059 { "CONSTANTCOND", false, constcond }, 1058 { "CONSTANTCOND", false, constcond },
1060 { "CONSTANTCONDITION", false, constcond }, 1059 { "CONSTANTCONDITION", false, constcond },
1061 { "FALLTHRU", false, fallthru }, 1060 { "FALLTHRU", false, fallthru },
1062 { "FALLTHROUGH", false, fallthru }, 1061 { "FALLTHROUGH", false, fallthru },
1063 { "FALL THROUGH", false, fallthru }, 1062 { "FALL THROUGH", false, fallthru },
1064 { "fallthrough", false, fallthru }, 1063 { "fallthrough", false, fallthru },
1065 { "LINTLIBRARY", false, lintlib }, 1064 { "LINTLIBRARY", false, lintlib },
1066 { "LINTED", true, linted }, 1065 { "LINTED", true, linted },
1067 { "LONGLONG", false, longlong }, 1066 { "LONGLONG", false, longlong },
1068 { "NOSTRICT", true, linted }, 1067 { "NOSTRICT", true, linted },
1069 { "NOTREACHED", false, not_reached }, 1068 { "NOTREACHED", false, not_reached },
1070 { "PRINTFLIKE", true, printflike }, 1069 { "PRINTFLIKE", true, printflike },
1071 { "PROTOLIB", true, protolib }, 1070 { "PROTOLIB", true, protolib },
1072 { "SCANFLIKE", true, scanflike }, 1071 { "SCANFLIKE", true, scanflike },
1073 { "VARARGS", true, varargs }, 1072 { "VARARGS", true, varargs },
1074 }; 1073 };
1075 char keywd[32]; 1074 char keywd[32];
1076 char arg[32]; 1075 char arg[32];
1077 size_t l, i; 1076 size_t l, i;
1078 int a; 1077 int a;
1079 1078
1080 bool seen_end_of_comment = false; 1079 bool seen_end_of_comment = false;
1081 1080
1082 /* Skip whitespace after the start of the comment */ 1081 /* Skip whitespace after the start of the comment */
1083 while (c = read_byte(), isspace(c)) 1082 while (c = read_byte(), isspace(c))
1084 continue; 1083 continue;
1085 1084
1086 /* Read the potential keyword to keywd */ 1085 /* Read the potential keyword to keywd */
1087 l = 0; 1086 l = 0;
1088 while (c != EOF && l < sizeof(keywd) - 1 && 1087 while (c != EOF && l < sizeof(keywd) - 1 &&
1089 (isalpha(c) || isspace(c))) { 1088 (isalpha(c) || isspace(c))) {
1090 if (islower(c) && l > 0 && ch_isupper(keywd[0])) 1089 if (islower(c) && l > 0 && ch_isupper(keywd[0]))
1091 break; 1090 break;
1092 keywd[l++] = (char)c; 1091 keywd[l++] = (char)c;
1093 c = read_byte(); 1092 c = read_byte();
1094 } 1093 }
1095 while (l > 0 && ch_isspace(keywd[l - 1])) 1094 while (l > 0 && ch_isspace(keywd[l - 1]))
1096 l--; 1095 l--;
1097 keywd[l] = '\0'; 1096 keywd[l] = '\0';
1098 1097
1099 /* look for the keyword */ 1098 /* look for the keyword */
1100 for (i = 0; i < sizeof(keywtab) / sizeof(keywtab[0]); i++) { 1099 for (i = 0; i < sizeof(keywtab) / sizeof(keywtab[0]); i++) {
1101 if (strcmp(keywtab[i].keywd, keywd) == 0) 1100 if (strcmp(keywtab[i].keywd, keywd) == 0)
1102 break; 1101 break;
1103 } 1102 }
1104 if (i == sizeof(keywtab) / sizeof(keywtab[0])) 1103 if (i == sizeof(keywtab) / sizeof(keywtab[0]))
1105 goto skip_rest; 1104 goto skip_rest;
1106 1105
1107 /* skip whitespace after the keyword */ 1106 /* skip whitespace after the keyword */
1108 while (isspace(c)) 1107 while (isspace(c))
1109 c = read_byte(); 1108 c = read_byte();
1110 1109
1111 /* read the argument, if the keyword accepts one and there is one */ 1110 /* read the argument, if the keyword accepts one and there is one */
1112 l = 0; 1111 l = 0;
1113 if (keywtab[i].arg) { 1112 if (keywtab[i].arg) {
1114 while (isdigit(c) && l < sizeof(arg) - 1) { 1113 while (isdigit(c) && l < sizeof(arg) - 1) {
1115 arg[l++] = (char)c; 1114 arg[l++] = (char)c;
1116 c = read_byte(); 1115 c = read_byte();
1117 } 1116 }
1118 } 1117 }
1119 arg[l] = '\0'; 1118 arg[l] = '\0';
1120 a = l != 0 ? atoi(arg) : -1; 1119 a = l != 0 ? atoi(arg) : -1;
1121 1120
1122 /* skip whitespace after the argument */ 1121 /* skip whitespace after the argument */
1123 while (isspace(c)) 1122 while (isspace(c))
1124 c = read_byte(); 1123 c = read_byte();
1125 1124
1126 seen_end_of_comment = c == '*' && (c = read_byte()) == '/'; 1125 seen_end_of_comment = c == '*' && (c = read_byte()) == '/';
1127 if (!seen_end_of_comment && keywtab[i].func != linted) 1126 if (!seen_end_of_comment && keywtab[i].func != linted)
1128 /* extra characters in lint comment */ 1127 /* extra characters in lint comment */
1129 warning(257); 1128 warning(257);
1130 1129
1131 if (keywtab[i].func != NULL) 1130 if (keywtab[i].func != NULL)
1132 keywtab[i].func(a); 1131 keywtab[i].func(a);
1133 1132
1134skip_rest: 1133skip_rest:
1135 while (!seen_end_of_comment) { 1134 while (!seen_end_of_comment) {
1136 int lc = c; 1135 int lc = c;
1137 if ((c = read_byte()) == EOF) { 1136 if ((c = read_byte()) == EOF) {
1138 /* unterminated comment */ 1137 /* unterminated comment */
1139 error(256); 1138 error(256);
1140 break; 1139 break;
1141 } 1140 }
1142 if (lc == '*' && c == '/') 1141 if (lc == '*' && c == '/')
1143 seen_end_of_comment = true; 1142 seen_end_of_comment = true;
1144 } 1143 }
1145} 1144}
1146 1145
1147void 1146void
1148lex_slash_slash_comment(void) 1147lex_slash_slash_comment(void)
1149{ 1148{
1150 int c; 1149 int c;
1151 1150
1152 if (!allow_c99 && !allow_gcc) 1151 if (!allow_c99 && !allow_gcc)
1153 /* %s does not support // comments */ 1152 /* %s does not support // comments */
1154 gnuism(312, allow_c90 ? "C90" : "traditional C"); 1153 gnuism(312, allow_c90 ? "C90" : "traditional C");
1155 1154
1156 while ((c = read_byte()) != EOF && c != '\n') 1155 while ((c = read_byte()) != EOF && c != '\n')
1157 continue; 1156 continue;
1158} 1157}
1159 1158
1160/* 1159/*
1161 * Clear flags for lint comments LINTED, LONGLONG and CONSTCOND. 1160 * Clear flags for lint comments LINTED, LONGLONG and CONSTCOND.
1162 * clear_warn_flags is called after function definitions and global and 1161 * clear_warn_flags is called after function definitions and global and
1163 * local declarations and definitions. It is also called between 1162 * local declarations and definitions. It is also called between
1164 * the controlling expression and the body of control statements 1163 * the controlling expression and the body of control statements
1165 * (if, switch, for, while). 1164 * (if, switch, for, while).
1166 */ 1165 */
1167void 1166void
1168clear_warn_flags(void) 1167clear_warn_flags(void)
1169{ 1168{
1170 1169
1171 lwarn = LWARN_ALL; 1170 lwarn = LWARN_ALL;
1172 quadflg = false; 1171 quadflg = false;
1173 constcond_flag = false; 1172 constcond_flag = false;
1174} 1173}
1175 1174
1176int 1175int
1177lex_string(void) 1176lex_string(void)
1178{ 1177{
1179 unsigned char *s; 1178 unsigned char *s;
1180 int c; 1179 int c;
1181 size_t len, max; 1180 size_t len, max;
1182 1181
1183 s = xmalloc(max = 64); 1182 s = xmalloc(max = 64);
1184 1183
1185 len = 0; 1184 len = 0;
1186 while ((c = get_escaped_char('"')) >= 0) { 1185 while ((c = get_escaped_char('"')) >= 0) {
1187 /* +1 to reserve space for a trailing NUL character */ 1186 /* +1 to reserve space for a trailing NUL character */
1188 if (len + 1 == max) 1187 if (len + 1 == max)
1189 s = xrealloc(s, max *= 2); 1188 s = xrealloc(s, max *= 2);
1190 s[len++] = (char)c; 1189 s[len++] = (char)c;
1191 } 1190 }
1192 s[len] = '\0'; 1191 s[len] = '\0';
1193 if (c == -2) 1192 if (c == -2)
1194 /* unterminated string constant */ 1193 /* unterminated string constant */
1195 error(258); 1194 error(258);
1196 1195
1197 strg_t *strg = xcalloc(1, sizeof(*strg)); 1196 strg_t *strg = xcalloc(1, sizeof(*strg));
1198 strg->st_char = true; 1197 strg->st_char = true;
1199 strg->st_len = len; 1198 strg->st_len = len;
1200 strg->st_mem = s; 1199 strg->st_mem = s;
1201 1200
1202 yylval.y_string = strg; 1201 yylval.y_string = strg;
1203 return T_STRING; 1202 return T_STRING;
1204} 1203}
1205 1204
1206int 1205int
1207lex_wide_string(void) 1206lex_wide_string(void)
1208{ 1207{
1209 int c, n; 1208 int c, n;
1210 1209
1211 size_t len = 0, max = 64; 1210 size_t len = 0, max = 64;
1212 char *s = xmalloc(max); 1211 char *s = xmalloc(max);
1213 while ((c = get_escaped_char('"')) >= 0) { 1212 while ((c = get_escaped_char('"')) >= 0) {
1214 /* +1 to save space for a trailing NUL character */ 1213 /* +1 to save space for a trailing NUL character */
1215 if (len + 1 >= max) 1214 if (len + 1 >= max)
1216 s = xrealloc(s, max *= 2); 1215 s = xrealloc(s, max *= 2);
1217 s[len++] = (char)c; 1216 s[len++] = (char)c;
1218 } 1217 }
1219 s[len] = '\0'; 1218 s[len] = '\0';
1220 if (c == -2) 1219 if (c == -2)
1221 /* unterminated string constant */ 1220 /* unterminated string constant */
1222 error(258); 1221 error(258);
1223 1222
1224 /* get length of wide-character string */ 1223 /* get length of wide-character string */
1225 (void)mblen(NULL, 0); 1224 (void)mblen(NULL, 0);
1226 size_t wlen = 0; 1225 size_t wlen = 0;
1227 for (size_t i = 0; i < len; i += n, wlen++) { 1226 for (size_t i = 0; i < len; i += n, wlen++) {
1228 if ((n = mblen(&s[i], MB_CUR_MAX)) == -1) { 1227 if ((n = mblen(&s[i], MB_CUR_MAX)) == -1) {
1229 /* invalid multibyte character */ 1228 /* invalid multibyte character */
1230 error(291); 1229 error(291);
1231 break; 1230 break;
1232 } 1231 }
1233 if (n == 0) 1232 if (n == 0)
1234 n = 1; 1233 n = 1;
1235 } 1234 }
1236 1235
1237 wchar_t *ws = xmalloc((wlen + 1) * sizeof(*ws)); 1236 wchar_t *ws = xmalloc((wlen + 1) * sizeof(*ws));
1238 size_t wi = 0; 1237 size_t wi = 0;
1239 /* convert from multibyte to wide char */ 1238 /* convert from multibyte to wide char */
1240 (void)mbtowc(NULL, NULL, 0); 1239 (void)mbtowc(NULL, NULL, 0);
1241 for (size_t i = 0; i < len; i += n, wi++) { 1240 for (size_t i = 0; i < len; i += n, wi++) {
1242 if ((n = mbtowc(&ws[wi], &s[i], MB_CUR_MAX)) == -1) 1241 if ((n = mbtowc(&ws[wi], &s[i], MB_CUR_MAX)) == -1)
1243 break; 1242 break;
1244 if (n == 0) 1243 if (n == 0)
1245 n = 1; 1244 n = 1;
1246 } 1245 }
1247 ws[wi] = 0; 1246 ws[wi] = 0;
1248 free(s); 1247 free(s);
1249 1248
1250 strg_t *strg = xcalloc(1, sizeof(*strg)); 1249 strg_t *strg = xcalloc(1, sizeof(*strg));
1251 strg->st_char = false; 1250 strg->st_char = false;
1252 strg->st_len = wlen; 1251 strg->st_len = wlen;
1253 strg->st_mem = ws; 1252 strg->st_mem = ws;
1254 1253
1255 yylval.y_string = strg; 1254 yylval.y_string = strg;
1256 return T_STRING; 1255 return T_STRING;
1257} 1256}
1258 1257
1259void 1258void
1260lex_next_line(void) 1259lex_next_line(void)
1261{ 1260{
1262 curr_pos.p_line++; 1261 curr_pos.p_line++;
1263 curr_pos.p_uniq = 0; 1262 curr_pos.p_uniq = 0;
1264 debug_step("parsing %s:%d", curr_pos.p_file, curr_pos.p_line); 1263 debug_step("parsing %s:%d", curr_pos.p_file, curr_pos.p_line);
1265 if (curr_pos.p_file == csrc_pos.p_file) { 1264 if (curr_pos.p_file == csrc_pos.p_file) {
1266 csrc_pos.p_line++; 1265 csrc_pos.p_line++;
1267 csrc_pos.p_uniq = 0; 1266 csrc_pos.p_uniq = 0;
1268 } 1267 }
1269} 1268}
1270 1269
1271void 1270void
1272lex_unknown_character(int c) 1271lex_unknown_character(int c)
1273{ 1272{
1274 1273
1275 /* unknown character \%o */ 1274 /* unknown character \%o */
1276 error(250, c); 1275 error(250, c);
1277} 1276}
1278 1277
1279/* 1278/*
1280 * The scanner does not create new symbol table entries for symbols it cannot 1279 * The scanner does not create new symbol table entries for symbols it cannot
1281 * find in the symbol table. This is to avoid putting undeclared symbols into 1280 * find in the symbol table. This is to avoid putting undeclared symbols into
1282 * the symbol table if a syntax error occurs. 1281 * the symbol table if a syntax error occurs.
1283 * 1282 *
1284 * getsym is called as soon as it is probably ok to put the symbol in the 1283 * getsym is called as soon as it is probably ok to put the symbol in the
1285 * symbol table. It is still possible that symbols are put in the symbol 1284 * symbol table. It is still possible that symbols are put in the symbol
1286 * table that are not completely declared due to syntax errors. To avoid too 1285 * table that are not completely declared due to syntax errors. To avoid too
1287 * many problems in this case, symbols get type 'int' in getsym. 1286 * many problems in this case, symbols get type 'int' in getsym.
1288 * 1287 *
1289 * XXX calls to getsym should be delayed until declare_1_* is called. 1288 * XXX calls to getsym should be delayed until declare_1_* is called.
1290 */ 1289 */
1291sym_t * 1290sym_t *
1292getsym(sbuf_t *sb) 1291getsym(sbuf_t *sb)
1293{ 1292{
1294 1293
1295 sym_t *sym = sb->sb_sym; 1294 sym_t *sym = sb->sb_sym;
1296 1295
1297 /* 1296 /*
1298 * During member declaration it is possible that name() looked 1297 * During member declaration it is possible that name() looked
1299 * for symbols of type FVFT, although it should have looked for 1298 * for symbols of type FVFT, although it should have looked for
1300 * symbols of type FTAG. Same can happen for labels. Both cases 1299 * symbols of type FTAG. Same can happen for labels. Both cases
1301 * are compensated here. 1300 * are compensated here.
1302 */ 1301 */
1303 if (symtyp == FMEMBER || symtyp == FLABEL) { 1302 if (symtyp == FMEMBER || symtyp == FLABEL) {
1304 if (sym == NULL || sym->s_kind == FVFT) 1303 if (sym == NULL || sym->s_kind == FVFT)
1305 sym = symtab_search(sb->sb_name); 1304 sym = symtab_search(sb->sb_name);
1306 } 1305 }
1307 1306
1308 if (sym != NULL) { 1307 if (sym != NULL) {
1309 lint_assert(sym->s_kind == symtyp); 1308 lint_assert(sym->s_kind == symtyp);
1310 symtyp = FVFT; 1309 symtyp = FVFT;
1311 free(sb); 1310 free(sb);
1312 return sym; 1311 return sym;
1313 } 1312 }
1314 1313
1315 /* create a new symbol table entry */ 1314 /* create a new symbol table entry */
1316 1315
1317 /* labels must always be allocated at level 1 (outermost block) */ 1316 /* labels must always be allocated at level 1 (outermost block) */
1318 dinfo_t *di; 1317 dinfo_t *di;
1319 if (symtyp == FLABEL) { 1318 if (symtyp == FLABEL) {
1320 sym = level_zero_alloc(1, sizeof(*sym)); 1319 sym = level_zero_alloc(1, sizeof(*sym));
1321 char *s = level_zero_alloc(1, sb->sb_len + 1); 1320 char *s = level_zero_alloc(1, sb->sb_len + 1);
1322 (void)memcpy(s, sb->sb_name, sb->sb_len + 1); 1321 (void)memcpy(s, sb->sb_name, sb->sb_len + 1);
1323 sym->s_name = s; 1322 sym->s_name = s;
1324 sym->s_block_level = 1; 1323 sym->s_block_level = 1;
1325 di = dcs; 1324 di = dcs;
1326 while (di->d_enclosing != NULL && 1325 while (di->d_enclosing != NULL &&
1327 di->d_enclosing->d_enclosing != NULL) 1326 di->d_enclosing->d_enclosing != NULL)
1328 di = di->d_enclosing; 1327 di = di->d_enclosing;
1329 lint_assert(di->d_kind == DK_AUTO); 1328 lint_assert(di->d_kind == DK_AUTO);
1330 } else { 1329 } else {
1331 sym = block_zero_alloc(sizeof(*sym)); 1330 sym = block_zero_alloc(sizeof(*sym));
1332 sym->s_name = sb->sb_name; 1331 sym->s_name = sb->sb_name;
1333 sym->s_block_level = block_level; 1332 sym->s_block_level = block_level;
1334 di = dcs; 1333 di = dcs;
1335 } 1334 }
1336 1335
1337 UNIQUE_CURR_POS(sym->s_def_pos); 1336 UNIQUE_CURR_POS(sym->s_def_pos);
1338 if ((sym->s_kind = symtyp) != FLABEL) 1337 if ((sym->s_kind = symtyp) != FLABEL)
1339 sym->s_type = gettyp(INT); 1338 sym->s_type = gettyp(INT);
1340 1339
1341 symtyp = FVFT; 1340 symtyp = FVFT;
1342 1341
1343 if (!in_gcc_attribute) { 1342 if (!in_gcc_attribute) {
1344 symtab_add(sym); 1343 symtab_add(sym);
1345 1344
1346 *di->d_ldlsym = sym; 1345 *di->d_ldlsym = sym;
1347 di->d_ldlsym = &sym->s_level_next; 1346 di->d_ldlsym = &sym->s_level_next;
1348 } 1347 }
1349 1348
1350 free(sb); 1349 free(sb);
1351 return sym; 1350 return sym;
1352} 1351}
1353 1352
1354/* 1353/*
1355 * Construct a temporary symbol. The symbol name starts with a digit to avoid 1354 * Construct a temporary symbol. The symbol name starts with a digit to avoid
1356 * name clashes with other identifiers. 1355 * name clashes with other identifiers.
1357 */ 1356 */
1358sym_t * 1357sym_t *
1359mktempsym(type_t *tp) 1358mktempsym(type_t *tp)
1360{ 1359{
1361 static unsigned n = 0; 1360 static unsigned n = 0;
1362 char *s = level_zero_alloc((size_t)block_level, 64); 1361 char *s = level_zero_alloc((size_t)block_level, 64);
1363 sym_t *sym = block_zero_alloc(sizeof(*sym)); 1362 sym_t *sym = block_zero_alloc(sizeof(*sym));
1364 scl_t scl; 1363 scl_t scl;
1365 1364
1366 (void)snprintf(s, 64, "%.8u_tmp", n++); 1365 (void)snprintf(s, 64, "%.8u_tmp", n++);
1367 1366
1368 scl = dcs->d_scl; 1367 scl = dcs->d_scl;
1369 if (scl == NOSCL) 1368 if (scl == NOSCL)
1370 scl = block_level > 0 ? AUTO : EXTERN; 1369 scl = block_level > 0 ? AUTO : EXTERN;
1371 1370
1372 sym->s_name = s; 1371 sym->s_name = s;
1373 sym->s_type = tp; 1372 sym->s_type = tp;
1374 sym->s_block_level = block_level; 1373 sym->s_block_level = block_level;
1375 sym->s_scl = scl; 1374 sym->s_scl = scl;
1376 sym->s_kind = FVFT; 1375 sym->s_kind = FVFT;
1377 sym->s_used = true; 1376 sym->s_used = true;
1378 sym->s_set = true; 1377 sym->s_set = true;
1379 1378
1380 symtab_add(sym); 1379 symtab_add(sym);
1381 1380
1382 *dcs->d_ldlsym = sym; 1381 *dcs->d_ldlsym = sym;
1383 dcs->d_ldlsym = &sym->s_level_next; 1382 dcs->d_ldlsym = &sym->s_level_next;
1384 1383
1385 return sym; 1384 return sym;
1386} 1385}
1387 1386
1388/* Remove a symbol forever from the symbol table. */ 1387/* Remove a symbol forever from the symbol table. */
1389void 1388void
1390rmsym(sym_t *sym) 1389rmsym(sym_t *sym)
1391{ 1390{
1392 1391
1393 debug_step("rmsym '%s' %s '%s'", 1392 debug_step("rmsym '%s' %s '%s'",
1394 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type)); 1393 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type));
1395 symtab_remove(sym); 1394 symtab_remove(sym);
1396 1395
1397 /* avoid that the symbol will later be put back to the symbol table */ 1396 /* avoid that the symbol will later be put back to the symbol table */
1398 sym->s_block_level = -1; 1397 sym->s_block_level = -1;
1399} 1398}
1400 1399
1401/* 1400/*
1402 * Remove all symbols from the symbol table that have the same level as the 1401 * Remove all symbols from the symbol table that have the same level as the
1403 * given symbol. 1402 * given symbol.
1404 */ 1403 */
1405void 1404void
1406rmsyms(sym_t *syms) 1405rmsyms(sym_t *syms)
1407{ 1406{
1408 sym_t *sym; 1407 sym_t *sym;
1409 1408
1410 /* Note the use of s_level_next instead of s_symtab_next. */ 1409 /* Note the use of s_level_next instead of s_symtab_next. */
1411 for (sym = syms; sym != NULL; sym = sym->s_level_next) { 1410 for (sym = syms; sym != NULL; sym = sym->s_level_next) {
1412 if (sym->s_block_level != -1) { 1411 if (sym->s_block_level != -1) {
1413 debug_step("rmsyms '%s' %s '%s'", 1412 debug_step("rmsyms '%s' %s '%s'",
1414 sym->s_name, symt_name(sym->s_kind), 1413 sym->s_name, symt_name(sym->s_kind),
1415 type_name(sym->s_type)); 1414 type_name(sym->s_type));
1416 symtab_remove(sym); 1415 symtab_remove(sym);
1417 sym->s_symtab_ref = NULL; 1416 sym->s_symtab_ref = NULL;
1418 } 1417 }
1419 } 1418 }
1420} 1419}
1421 1420
1422/* Put a symbol into the symbol table. */ 1421/* Put a symbol into the symbol table. */
1423void 1422void
1424inssym(int level, sym_t *sym) 1423inssym(int level, sym_t *sym)
1425{ 1424{
1426 1425
1427 debug_step("inssym '%s' %s '%s'", 1426 debug_step("inssym '%s' %s '%s'",
1428 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type)); 1427 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type));
1429 symtab_add(sym); 1428 symtab_add(sym);
1430 sym->s_block_level = level; 1429 sym->s_block_level = level;
1431 1430
1432 /* 1431 /*
1433 * Placing the inner symbols to the beginning of the list ensures 1432 * Placing the inner symbols to the beginning of the list ensures
1434 * that these symbols are preferred over symbols from the outer 1433 * that these symbols are preferred over symbols from the outer
1435 * blocks that happen to have the same name. 1434 * blocks that happen to have the same name.
1436 */ 1435 */
1437 const sym_t *next = sym->s_symtab_next; 1436 const sym_t *next = sym->s_symtab_next;
1438 if (next != NULL) 1437 if (next != NULL)
1439 lint_assert(sym->s_block_level >= next->s_block_level); 1438 lint_assert(sym->s_block_level >= next->s_block_level);
1440} 1439}
1441 1440
1442/* Called at level 0 after syntax errors. */ 1441/* Called at level 0 after syntax errors. */
1443void 1442void
1444clean_up_after_error(void) 1443clean_up_after_error(void)
1445{ 1444{
1446 1445
1447 symtab_remove_locals(); 1446 symtab_remove_locals();
1448 1447
1449 while (mem_block_level > 0) 1448 while (mem_block_level > 0)
1450 level_free_all(mem_block_level--); 1449 level_free_all(mem_block_level--);
1451} 1450}
1452 1451
1453/* Create a new symbol with the same name as an existing symbol. */ 1452/* Create a new symbol with the same name as an existing symbol. */
1454sym_t * 1453sym_t *
1455pushdown(const sym_t *sym) 1454pushdown(const sym_t *sym)
1456{ 1455{
1457 sym_t *nsym; 1456 sym_t *nsym;
1458 1457
1459 debug_step("pushdown '%s' %s '%s'", 1458 debug_step("pushdown '%s' %s '%s'",
1460 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type)); 1459 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type));
1461 nsym = block_zero_alloc(sizeof(*nsym)); 1460 nsym = block_zero_alloc(sizeof(*nsym));
1462 lint_assert(sym->s_block_level <= block_level); 1461 lint_assert(sym->s_block_level <= block_level);
1463 nsym->s_name = sym->s_name; 1462 nsym->s_name = sym->s_name;
1464 UNIQUE_CURR_POS(nsym->s_def_pos); 1463 UNIQUE_CURR_POS(nsym->s_def_pos);
1465 nsym->s_kind = sym->s_kind; 1464 nsym->s_kind = sym->s_kind;
1466 nsym->s_block_level = block_level; 1465 nsym->s_block_level = block_level;
1467 1466
1468 symtab_add(nsym); 1467 symtab_add(nsym);
1469 1468
1470 *dcs->d_ldlsym = nsym; 1469 *dcs->d_ldlsym = nsym;
1471 dcs->d_ldlsym = &nsym->s_level_next; 1470 dcs->d_ldlsym = &nsym->s_level_next;
1472 1471
1473 return nsym; 1472 return nsym;
1474} 1473}
1475 1474
1476/* 1475/*
1477 * Free any dynamically allocated memory referenced by 1476 * Free any dynamically allocated memory referenced by
1478 * the value stack or yylval. 1477 * the value stack or yylval.
1479 * The type of information in yylval is described by tok. 1478 * The type of information in yylval is described by tok.
1480 */ 1479 */
1481void 1480void
1482freeyyv(void *sp, int tok) 1481freeyyv(void *sp, int tok)
1483{ 1482{
1484 if (tok == T_NAME || tok == T_TYPENAME) { 1483 if (tok == T_NAME || tok == T_TYPENAME) {
1485 sbuf_t *sb = *(sbuf_t **)sp; 1484 sbuf_t *sb = *(sbuf_t **)sp;
1486 free(sb); 1485 free(sb);
1487 } else if (tok == T_CON) { 1486 } else if (tok == T_CON) {
1488 val_t *val = *(val_t **)sp; 1487 val_t *val = *(val_t **)sp;
1489 free(val); 1488 free(val);
1490 } else if (tok == T_STRING) { 1489 } else if (tok == T_STRING) {
1491 strg_t *strg = *(strg_t **)sp; 1490 strg_t *strg = *(strg_t **)sp;
1492 free(strg->st_mem); 1491 free(strg->st_mem);
1493 free(strg); 1492 free(strg);
1494 } 1493 }
1495} 1494}