| @@ -1,15 +1,15 @@ | | | @@ -1,15 +1,15 @@ |
1 | %{ | | 1 | %{ |
2 | /* $NetBSD: scan.l,v 1.54 2014/02/18 22:01:36 christos Exp $ */ | | 2 | /* $NetBSD: scan.l,v 1.55 2014/04/18 00:23:46 christos Exp $ */ |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. | | 5 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. |
6 | * Copyright (c) 1994, 1995 Jochen Pohl | | 6 | * Copyright (c) 1994, 1995 Jochen Pohl |
7 | * All Rights Reserved. | | 7 | * All Rights Reserved. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
15 | * notice, this list of conditions and the following disclaimer in the | | 15 | * notice, this list of conditions and the following disclaimer in the |
| @@ -25,51 +25,54 @@ | | | @@ -25,51 +25,54 @@ |
25 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 25 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
26 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 26 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
27 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 27 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
29 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 29 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
34 | */ | | 34 | */ |
35 | | | 35 | |
36 | #include <sys/cdefs.h> | | 36 | #include <sys/cdefs.h> |
37 | #if defined(__RCSID) && !defined(lint) | | 37 | #if defined(__RCSID) && !defined(lint) |
38 | __RCSID("$NetBSD: scan.l,v 1.54 2014/02/18 22:01:36 christos Exp $"); | | 38 | __RCSID("$NetBSD: scan.l,v 1.55 2014/04/18 00:23:46 christos Exp $"); |
39 | #endif | | 39 | #endif |
40 | | | 40 | |
41 | #include <stdlib.h> | | 41 | #include <stdlib.h> |
42 | #include <string.h> | | 42 | #include <string.h> |
43 | #include <limits.h> | | 43 | #include <limits.h> |
44 | #include <float.h> | | 44 | #include <float.h> |
45 | #include <ctype.h> | | 45 | #include <ctype.h> |
46 | #include <errno.h> | | 46 | #include <errno.h> |
47 | #include <math.h> | | 47 | #include <math.h> |
48 | | | 48 | |
49 | #include "lint1.h" | | 49 | #include "lint1.h" |
50 | #include "cgram.h" | | 50 | #include "cgram.h" |
51 | | | 51 | |
52 | #define CHAR_MASK (~(~0 << CHAR_BIT)) | | 52 | #define CHAR_MASK (~(~0 << CHAR_BIT)) |
53 | | | 53 | |
54 | /* Current position (its also updated when an included file is parsed) */ | | 54 | /* Current position (its also updated when an included file is parsed) */ |
55 | pos_t curr_pos = { 1, "", 0 }; | | 55 | pos_t curr_pos = { 1, "", 0 }; |
56 | | | 56 | |
57 | /* | | 57 | /* |
58 | * Current position in C source (not updated when an included file is | | 58 | * Current position in C source (not updated when an included file is |
59 | * parsed). | | 59 | * parsed). |
60 | */ | | 60 | */ |
61 | pos_t csrc_pos = { 1, "", 0 }; | | 61 | pos_t csrc_pos = { 1, "", 0 }; |
62 | | | 62 | |
| | | 63 | /* Are we parsing a gcc attribute? */ |
| | | 64 | int attron; |
| | | 65 | |
63 | static void incline(void); | | 66 | static void incline(void); |
64 | static void badchar(int); | | 67 | static void badchar(int); |
65 | static sbuf_t *allocsb(void); | | 68 | static sbuf_t *allocsb(void); |
66 | static void freesb(sbuf_t *); | | 69 | static void freesb(sbuf_t *); |
67 | static int inpc(void); | | 70 | static int inpc(void); |
68 | static int hash(const char *); | | 71 | static int hash(const char *); |
69 | static sym_t *search(sbuf_t *); | | 72 | static sym_t *search(sbuf_t *); |
70 | static int name(void); | | 73 | static int name(void); |
71 | static int keyw(sym_t *); | | 74 | static int keyw(sym_t *); |
72 | static int icon(int); | | 75 | static int icon(int); |
73 | static int fcon(void); | | 76 | static int fcon(void); |
74 | static int operator(int, op_t); | | 77 | static int operator(int, op_t); |
75 | static int ccon(void); | | 78 | static int ccon(void); |
| @@ -183,101 +186,115 @@ badchar(int c) | | | @@ -183,101 +186,115 @@ badchar(int c) |
183 | error(250, c); | | 186 | error(250, c); |
184 | } | | 187 | } |
185 | | | 188 | |
186 | /* | | 189 | /* |
187 | * Keywords. | | 190 | * Keywords. |
188 | * During initialisation they are written to the symbol table. | | 191 | * During initialisation they are written to the symbol table. |
189 | */ | | 192 | */ |
190 | static struct kwtab { | | 193 | static struct kwtab { |
191 | const char *kw_name; /* keyword */ | | 194 | const char *kw_name; /* keyword */ |
192 | int kw_token; /* token returned by yylex() */ | | 195 | int kw_token; /* token returned by yylex() */ |
193 | scl_t kw_scl; /* storage class if kw_token T_SCLASS */ | | 196 | scl_t kw_scl; /* storage class if kw_token T_SCLASS */ |
194 | tspec_t kw_tspec; /* type spec. if kw_token T_TYPE or T_SOU */ | | 197 | tspec_t kw_tspec; /* type spec. if kw_token T_TYPE or T_SOU */ |
195 | tqual_t kw_tqual; /* type qual. fi kw_token T_QUAL */ | | 198 | tqual_t kw_tqual; /* type qual. fi kw_token T_QUAL */ |
196 | u_int kw_c89; /* c89 keyword */ | | 199 | u_int kw_c89 : 1; /* c89 keyword */ |
197 | u_int kw_c99; /* c99 keyword */ | | 200 | u_int kw_c99 : 1; /* c99 keyword */ |
198 | u_int kw_gcc; /* GCC keyword */ | | 201 | u_int kw_gcc : 1; /* GCC keyword */ |
| | | 202 | u_int kw_attr : 1; /* GCC attribute, keyword */ |
199 | } kwtab[] = { | | 203 | } kwtab[] = { |
200 | { "__alignof__", T_ALIGNOF, 0, 0, 0, 0, 0, 0 }, | | 204 | { "__alignof__", T_ALIGNOF, 0, 0, 0, 0, 0, 0, 0 }, |
201 | { "__attribute__",T_ATTRIBUTE, 0, 0, 0, 0, 0, 1 }, | | 205 | { "__attribute__",T_ATTRIBUTE, 0, 0, 0, 0, 0, 1, 0 }, |
202 | { "attribute", T_ATTRIBUTE, 0, 0, 0, 0, 0, 1 }, | | 206 | { "attribute", T_ATTRIBUTE, 0, 0, 0, 0, 0, 1, 0 }, |
203 | { "__packed__", T_AT_PACKED, 0, 0, 0, 0, 0, 1 }, | | 207 | { "__packed__", T_AT_PACKED, 0, 0, 0, 0, 0, 1, 1 }, |
204 | { "packed", T_AT_PACKED, 0, 0, 0, 0, 0, 1 }, | | 208 | { "packed", T_AT_PACKED, 0, 0, 0, 0, 0, 1, 1 }, |
205 | { "__aligned__",T_AT_ALIGNED, 0, 0, 0, 0, 0, 1 }, | | 209 | { "__aligned__",T_AT_ALIGNED, 0, 0, 0, 0, 0, 1, 1 }, |
206 | { "aligned", T_AT_ALIGNED, 0, 0, 0, 0, 0, 1 }, | | 210 | { "aligned", T_AT_ALIGNED, 0, 0, 0, 0, 0, 1, 1 }, |
207 | { "__transparent_union__",T_AT_TUNION,0,0, 0, 0, 0, 1 }, | | 211 | { "__transparent_union__",T_AT_TUNION,0,0, 0, 0, 0, 1, 1 }, |
208 | { "transparent_union",T_AT_TUNION,0, 0, 0, 0, 0, 1 }, | | 212 | { "transparent_union",T_AT_TUNION,0, 0, 0, 0, 0, 1, 1 }, |
209 | { "__unused__", T_AT_UNUSED, 0, 0, 0, 0, 0, 1 }, | | 213 | { "__unused__", T_AT_UNUSED, 0, 0, 0, 0, 0, 1, 1 }, |
210 | { "unused", T_AT_UNUSED, 0, 0, 0, 0, 0, 1 }, | | 214 | { "unused", T_AT_UNUSED, 0, 0, 0, 0, 0, 1, 1 }, |
211 | { "__deprecated__",T_AT_DEPRECATED,0, 0, 0, 0, 0, 1 }, | | 215 | { "__deprecated__",T_AT_DEPRECATED,0, 0, 0, 0, 0, 1, 1 }, |
212 | { "deprecated", T_AT_DEPRECATED,0, 0, 0, 0, 0, 1 }, | | 216 | { "deprecated", T_AT_DEPRECATED,0, 0, 0, 0, 0, 1, 1 }, |
213 | { "__may_alias__",T_AT_MAY_ALIAS,0, 0, 0, 0, 0, 1 }, | | 217 | { "__may_alias__",T_AT_MAY_ALIAS,0, 0, 0, 0, 0, 1, 1 }, |
214 | { "may_alias", T_AT_MAY_ALIAS, 0, 0, 0, 0, 0, 1 }, | | 218 | { "may_alias", T_AT_MAY_ALIAS, 0, 0, 0, 0, 0, 1, 1 }, |
215 | { "asm", T_ASM, 0, 0, 0, 0, 0, 1 }, | | 219 | { "format", T_AT_FORMAT, 0, 0, 0, 0, 0, 1, 1 }, |
216 | { "__asm", T_ASM, 0, 0, 0, 0, 0, 0 }, | | 220 | { "__format__", T_AT_FORMAT, 0, 0, 0, 0, 0, 1, 1 }, |
217 | { "__asm__", T_ASM, 0, 0, 0, 0, 0, 0 }, | | 221 | { "printf", T_AT_FORMAT_PRINTF,0, 0, 0, 0, 0, 1, 1 }, |
218 | { "auto", T_SCLASS, AUTO, 0, 0, 0, 0, 0 }, | | 222 | { "__printf__", T_AT_FORMAT_PRINTF,0, 0, 0, 0, 0, 1, 1 }, |
219 | { "break", T_BREAK, 0, 0, 0, 0, 0, 0 }, | | 223 | { "scanf", T_AT_FORMAT_SCANF,0, 0, 0, 0, 0, 1, 1 }, |
220 | { "_Bool", T_TYPE, 0, BOOL, 0, 0, 1, 0 }, | | 224 | { "__scanf__", T_AT_FORMAT_SCANF,0, 0, 0, 0, 0, 1, 1 }, |
221 | { "case", T_CASE, 0, 0, 0, 0, 0, 0 }, | | 225 | { "strftime", T_AT_FORMAT_SCANF,0, 0, 0, 0, 0, 1, 1 }, |
222 | { "char", T_TYPE, 0, CHAR, 0, 0, 0, 0 }, | | 226 | { "__strftime__",T_AT_FORMAT_STRFTIME,0,0, 0, 0, 0, 1, 1 }, |
223 | { "const", T_QUAL, 0, 0, CONST, 1, 0, 0 }, | | 227 | { "pure", T_AT_PURE, 0, 0, 0, 0, 0, 1, 1 }, |
224 | { "_Complex", T_TYPE, 0, COMPLEX,0, 0, 1, 0 }, | | 228 | { "__pure__", T_AT_PURE, 0, 0, 0, 0, 0, 1, 1 }, |
225 | { "__const__", T_QUAL, 0, 0, CONST, 0, 0, 0 }, | | 229 | { "noreturn", T_AT_NORETURN, 0, 0, 0, 0, 0, 1, 1 }, |
226 | { "__const", T_QUAL, 0, 0, CONST, 0, 0, 0 }, | | 230 | { "__noreturn__",T_AT_NORETURN, 0, 0, 0, 0, 0, 1, 1 }, |
227 | { "continue", T_CONTINUE, 0, 0, 0, 0, 0, 0 }, | | 231 | { "asm", T_ASM, 0, 0, 0, 0, 0, 1, 1 }, |
228 | { "default", T_DEFAULT, 0, 0, 0, 0, 0, 0 }, | | 232 | { "__asm", T_ASM, 0, 0, 0, 0, 0, 0, 0 }, |
229 | { "do", T_DO, 0, 0, 0, 0, 0, 0 }, | | 233 | { "__asm__", T_ASM, 0, 0, 0, 0, 0, 0, 0 }, |
230 | { "double", T_TYPE, 0, DOUBLE, 0, 0, 0, 0 }, | | 234 | { "auto", T_SCLASS, AUTO, 0, 0, 0, 0, 0, 0 }, |
231 | { "else", T_ELSE, 0, 0, 0, 0, 0, 0 }, | | 235 | { "break", T_BREAK, 0, 0, 0, 0, 0, 0, 0 }, |
232 | { "enum", T_ENUM, 0, 0, 0, 0, 0, 0 }, | | 236 | { "_Bool", T_TYPE, 0, BOOL, 0, 0, 1, 0, 0 }, |
233 | { "__extension__", T_EXTENSION, 0, 0, 0, 0, 0, 1 }, | | 237 | { "case", T_CASE, 0, 0, 0, 0, 0, 0, 0 }, |
234 | { "extern", T_SCLASS, EXTERN, 0, 0, 0, 0, 0 }, | | 238 | { "char", T_TYPE, 0, CHAR, 0, 0, 0, 0, 0 }, |
235 | { "float", T_TYPE, 0, FLOAT, 0, 0, 0, 0 }, | | 239 | { "const", T_QUAL, 0, 0, CONST, 1, 0, 0, 0 }, |
236 | { "for", T_FOR, 0, 0, 0, 0, 0, 0 }, | | 240 | { "_Complex", T_TYPE, 0, COMPLEX,0, 0, 1, 0, 0 }, |
237 | { "goto", T_GOTO, 0, 0, 0, 0, 0, 0 }, | | 241 | { "__const__", T_QUAL, 0, 0, CONST, 0, 0, 0, 0 }, |
238 | { "if", T_IF, 0, 0, 0, 0, 0, 0 }, | | 242 | { "__const", T_QUAL, 0, 0, CONST, 0, 0, 0, 0 }, |
239 | { "__imag__", T_IMAG, 0, 0, 0, 0, 1, 0 }, | | 243 | { "continue", T_CONTINUE, 0, 0, 0, 0, 0, 0, 0 }, |
240 | { "inline", T_SCLASS, INLINE, 0, 0, 0, 1, 0 }, | | 244 | { "default", T_DEFAULT, 0, 0, 0, 0, 0, 0, 0 }, |
241 | { "__inline__", T_SCLASS, INLINE, 0, 0, 0, 0, 0 }, | | 245 | { "do", T_DO, 0, 0, 0, 0, 0, 0, 0 }, |
242 | { "__inline", T_SCLASS, INLINE, 0, 0, 0, 0, 0 }, | | 246 | { "double", T_TYPE, 0, DOUBLE, 0, 0, 0, 0, 0 }, |
243 | { "int", T_TYPE, 0, INT, 0, 0, 0, 0 }, | | 247 | { "else", T_ELSE, 0, 0, 0, 0, 0, 0, 0 }, |
244 | { "__symbolrename", T_SYMBOLRENAME, 0, 0, 0, 0, 0, 0 }, | | 248 | { "enum", T_ENUM, 0, 0, 0, 0, 0, 0, 0 }, |
245 | { "long", T_TYPE, 0, LONG, 0, 0, 0, 0 }, | | 249 | { "__extension__", T_EXTENSION, 0, 0, 0, 0, 0, 1, 0 }, |
246 | { "__real__", T_REAL, 0, 0, 0, 0, 1, 0 }, | | 250 | { "extern", T_SCLASS, EXTERN, 0, 0, 0, 0, 0, 0 }, |
247 | { "register", T_SCLASS, REG, 0, 0, 0, 0, 0 }, | | 251 | { "float", T_TYPE, 0, FLOAT, 0, 0, 0, 0, 0 }, |
248 | { "restrict", T_QUAL, 0, 0, RESTRICT, 0, 1, 0 }, | | 252 | { "for", T_FOR, 0, 0, 0, 0, 0, 0, 0 }, |
249 | { "return", T_RETURN, 0, 0, 0, 0, 0, 0 }, | | 253 | { "goto", T_GOTO, 0, 0, 0, 0, 0, 0, 0 }, |
250 | { "__packed", T_PACKED, 0, 0, 0, 0, 0, 0 }, | | 254 | { "if", T_IF, 0, 0, 0, 0, 0, 0, 0 }, |
251 | { "short", T_TYPE, 0, SHORT, 0, 0, 0, 0 }, | | 255 | { "__imag__", T_IMAG, 0, 0, 0, 0, 1, 0, 0 }, |
252 | { "signed", T_TYPE, 0, SIGNED, 0, 1, 0, 0 }, | | 256 | { "inline", T_SCLASS, INLINE, 0, 0, 0, 1, 0, 0 }, |
253 | { "__signed__", T_TYPE, 0, SIGNED, 0, 0, 0, 0 }, | | 257 | { "__inline__", T_SCLASS, INLINE, 0, 0, 0, 0, 0, 0 }, |
254 | { "__signed", T_TYPE, 0, SIGNED, 0, 0, 0, 0 }, | | 258 | { "__inline", T_SCLASS, INLINE, 0, 0, 0, 0, 0, 0 }, |
255 | { "sizeof", T_SIZEOF, 0, 0, 0, 0, 0, 0 }, | | 259 | { "int", T_TYPE, 0, INT, 0, 0, 0, 0, 0 }, |
256 | { "static", T_SCLASS, STATIC, 0, 0, 0, 0, 0 }, | | 260 | { "__symbolrename", T_SYMBOLRENAME, 0, 0, 0, 0, 0, 0, 0 }, |
257 | { "struct", T_SOU, 0, STRUCT, 0, 0, 0, 0 }, | | 261 | { "long", T_TYPE, 0, LONG, 0, 0, 0, 0, 0 }, |
258 | { "switch", T_SWITCH, 0, 0, 0, 0, 0, 0 }, | | 262 | { "__real__", T_REAL, 0, 0, 0, 0, 1, 0, 0 }, |
259 | { "typedef", T_SCLASS, TYPEDEF, 0, 0, 0, 0, 0 }, | | 263 | { "register", T_SCLASS, REG, 0, 0, 0, 0, 0, 0 }, |
260 | { "typeof", T_TYPEOF, 0, 0, 0, 0, 0, 1 }, | | 264 | { "__restrict__",T_QUAL, 0, 0, RESTRICT, 0, 1, 0, 0 }, |
261 | { "__typeof", T_TYPEOF, 0, 0, 0, 0, 0, 1 }, | | 265 | { "restrict", T_QUAL, 0, 0, RESTRICT, 0, 1, 0, 0 }, |
262 | { "__typeof__", T_TYPEOF, 0, 0, 0, 0, 0, 1 }, | | 266 | { "return", T_RETURN, 0, 0, 0, 0, 0, 0, 0 }, |
263 | { "union", T_SOU, 0, UNION, 0, 0, 0, 0 }, | | 267 | { "__packed", T_PACKED, 0, 0, 0, 0, 0, 0, 0 }, |
264 | { "unsigned", T_TYPE, 0, UNSIGN, 0, 0, 0, 0 }, | | 268 | { "short", T_TYPE, 0, SHORT, 0, 0, 0, 0, 0 }, |
265 | { "void", T_TYPE, 0, VOID, 0, 0, 0, 0 }, | | 269 | { "signed", T_TYPE, 0, SIGNED, 0, 1, 0, 0, 0 }, |
266 | { "volatile", T_QUAL, 0, 0, VOLATILE, 1, 0, 0 }, | | 270 | { "__signed__", T_TYPE, 0, SIGNED, 0, 0, 0, 0, 0 }, |
267 | { "__volatile__", T_QUAL, 0, 0, VOLATILE, 0, 0, 0 }, | | 271 | { "__signed", T_TYPE, 0, SIGNED, 0, 0, 0, 0, 0 }, |
268 | { "__volatile", T_QUAL, 0, 0, VOLATILE, 0, 0, 0 }, | | 272 | { "sizeof", T_SIZEOF, 0, 0, 0, 0, 0, 0, 0 }, |
269 | { "while", T_WHILE, 0, 0, 0, 0, 0, 0 }, | | 273 | { "static", T_SCLASS, STATIC, 0, 0, 0, 0, 0, 0 }, |
270 | { NULL, 0, 0, 0, 0, 0, 0, 0 } | | 274 | { "struct", T_SOU, 0, STRUCT, 0, 0, 0, 0, 0 }, |
| | | 275 | { "switch", T_SWITCH, 0, 0, 0, 0, 0, 0, 0 }, |
| | | 276 | { "typedef", T_SCLASS, TYPEDEF, 0, 0, 0, 0, 0, 0 }, |
| | | 277 | { "typeof", T_TYPEOF, 0, 0, 0, 0, 0, 1, 0 }, |
| | | 278 | { "__typeof", T_TYPEOF, 0, 0, 0, 0, 0, 1, 0 }, |
| | | 279 | { "__typeof__", T_TYPEOF, 0, 0, 0, 0, 0, 1, 0 }, |
| | | 280 | { "union", T_SOU, 0, UNION, 0, 0, 0, 0, 0 }, |
| | | 281 | { "unsigned", T_TYPE, 0, UNSIGN, 0, 0, 0, 0, 0 }, |
| | | 282 | { "void", T_TYPE, 0, VOID, 0, 0, 0, 0, 0 }, |
| | | 283 | { "volatile", T_QUAL, 0, 0, VOLATILE, 1, 0, 0, 0 }, |
| | | 284 | { "__volatile__", T_QUAL, 0, 0, VOLATILE, 0, 0, 0, 0 }, |
| | | 285 | { "__volatile", T_QUAL, 0, 0, VOLATILE, 0, 0, 0, 0 }, |
| | | 286 | { "while", T_WHILE, 0, 0, 0, 0, 0, 0, 0 }, |
| | | 287 | { NULL, 0, 0, 0, 0, 0, 0, 0, 0 } |
271 | }; | | 288 | }; |
272 | | | 289 | |
273 | /* Symbol table */ | | 290 | /* Symbol table */ |
274 | static sym_t *symtab[HSHSIZ1]; | | 291 | static sym_t *symtab[HSHSIZ1]; |
275 | | | 292 | |
276 | /* bit i of the entry with index i is set */ | | 293 | /* bit i of the entry with index i is set */ |
277 | uint64_t qbmasks[sizeof(uint64_t) * CHAR_BIT]; | | 294 | uint64_t qbmasks[sizeof(uint64_t) * CHAR_BIT]; |
278 | | | 295 | |
279 | /* least significant i bits are set in the entry with index i */ | | 296 | /* least significant i bits are set in the entry with index i */ |
280 | uint64_t qlmasks[sizeof(uint64_t) * CHAR_BIT + 1]; | | 297 | uint64_t qlmasks[sizeof(uint64_t) * CHAR_BIT + 1]; |
281 | | | 298 | |
282 | /* least significant i bits are not set in the entry with index i */ | | 299 | /* least significant i bits are not set in the entry with index i */ |
283 | uint64_t qumasks[sizeof(uint64_t) * CHAR_BIT + 1]; | | 300 | uint64_t qumasks[sizeof(uint64_t) * CHAR_BIT + 1]; |
| @@ -300,27 +317,27 @@ initscan(void) | | | @@ -300,27 +317,27 @@ initscan(void) |
300 | sym_t *sym; | | 317 | sym_t *sym; |
301 | size_t h, i; | | 318 | size_t h, i; |
302 | uint64_t uq; | | 319 | uint64_t uq; |
303 | | | 320 | |
304 | for (kw = kwtab; kw->kw_name != NULL; kw++) { | | 321 | for (kw = kwtab; kw->kw_name != NULL; kw++) { |
305 | if ((kw->kw_c89 || kw->kw_c99) && tflag) | | 322 | if ((kw->kw_c89 || kw->kw_c99) && tflag) |
306 | continue; | | 323 | continue; |
307 | if (kw->kw_c99 && !(Sflag || gflag)) | | 324 | if (kw->kw_c99 && !(Sflag || gflag)) |
308 | continue; | | 325 | continue; |
309 | if (kw->kw_gcc && !gflag) | | 326 | if (kw->kw_gcc && !gflag) |
310 | continue; | | 327 | continue; |
311 | sym = getblk(sizeof (sym_t)); | | 328 | sym = getblk(sizeof (sym_t)); |
312 | sym->s_name = kw->kw_name; | | 329 | sym->s_name = kw->kw_name; |
313 | sym->s_keyw = 1; | | 330 | sym->s_keyw = kw; |
314 | sym->s_value.v_quad = kw->kw_token; | | 331 | sym->s_value.v_quad = kw->kw_token; |
315 | if (kw->kw_token == T_TYPE || kw->kw_token == T_SOU) { | | 332 | if (kw->kw_token == T_TYPE || kw->kw_token == T_SOU) { |
316 | sym->s_tspec = kw->kw_tspec; | | 333 | sym->s_tspec = kw->kw_tspec; |
317 | } else if (kw->kw_token == T_SCLASS) { | | 334 | } else if (kw->kw_token == T_SCLASS) { |
318 | sym->s_scl = kw->kw_scl; | | 335 | sym->s_scl = kw->kw_scl; |
319 | } else if (kw->kw_token == T_QUAL) { | | 336 | } else if (kw->kw_token == T_QUAL) { |
320 | sym->s_tqual = kw->kw_tqual; | | 337 | sym->s_tqual = kw->kw_tqual; |
321 | } | | 338 | } |
322 | h = hash(sym->s_name); | | 339 | h = hash(sym->s_name); |
323 | if ((sym->s_link = symtab[h]) != NULL) | | 340 | if ((sym->s_link = symtab[h]) != NULL) |
324 | symtab[h]->s_rlink = &sym->s_link; | | 341 | symtab[h]->s_rlink = &sym->s_link; |
325 | sym->s_rlink = &symtab[h]; | | 342 | sym->s_rlink = &symtab[h]; |
326 | symtab[h] = sym; | | 343 | symtab[h] = sym; |
| @@ -337,40 +354,46 @@ initscan(void) | | | @@ -337,40 +354,46 @@ initscan(void) |
337 | qlmasks[i] = ~(uint64_t)0; | | 354 | qlmasks[i] = ~(uint64_t)0; |
338 | } | | 355 | } |
339 | | | 356 | |
340 | /* | | 357 | /* |
341 | * Get a free sbuf structure, if possible from the free list | | 358 | * Get a free sbuf structure, if possible from the free list |
342 | */ | | 359 | */ |
343 | static sbuf_t * | | 360 | static sbuf_t * |
344 | allocsb(void) | | 361 | allocsb(void) |
345 | { | | 362 | { |
346 | sbuf_t *sb; | | 363 | sbuf_t *sb; |
347 | | | 364 | |
348 | if ((sb = sbfrlst) != NULL) { | | 365 | if ((sb = sbfrlst) != NULL) { |
349 | sbfrlst = sb->sb_nxt; | | 366 | sbfrlst = sb->sb_nxt; |
| | | 367 | #ifdef BLKDEBUG |
| | | 368 | (void)memset(sb, 0, sizeof (*sb)); |
| | | 369 | #else |
| | | 370 | sb->sb_nxt = NULL; |
| | | 371 | #endif |
350 | } else { | | 372 | } else { |
351 | sb = xmalloc(sizeof (sbuf_t)); | | 373 | sb = xmalloc(sizeof (sbuf_t)); |
| | | 374 | (void)memset(sb, 0, sizeof (*sb)); |
352 | } | | 375 | } |
353 | (void)memset(sb, 0, sizeof (*sb)); | | | |
354 | return (sb); | | 376 | return (sb); |
355 | } | | 377 | } |
356 | | | 378 | |
357 | /* | | 379 | /* |
358 | * Put a sbuf structure to the free list | | 380 | * Put a sbuf structure to the free list |
359 | */ | | 381 | */ |
360 | static void | | 382 | static void |
361 | freesb(sbuf_t *sb) | | 383 | freesb(sbuf_t *sb) |
362 | { | | 384 | { |
363 | | | 385 | |
| | | 386 | (void)memset(sb, ZERO, sizeof (*sb)); |
364 | sb->sb_nxt = sbfrlst; | | 387 | sb->sb_nxt = sbfrlst; |
365 | sbfrlst = sb; | | 388 | sbfrlst = sb; |
366 | } | | 389 | } |
367 | | | 390 | |
368 | /* | | 391 | /* |
369 | * Read a character and ensure that it is positive (except EOF). | | 392 | * Read a character and ensure that it is positive (except EOF). |
370 | * Increment line count(s) if necessary. | | 393 | * Increment line count(s) if necessary. |
371 | */ | | 394 | */ |
372 | static int | | 395 | static int |
373 | inpc(void) | | 396 | inpc(void) |
374 | { | | 397 | { |
375 | int c; | | 398 | int c; |
376 | | | 399 | |
| @@ -411,28 +434,31 @@ hash(const char *s) | | | @@ -411,28 +434,31 @@ hash(const char *s) |
411 | static int | | 434 | static int |
412 | name(void) | | 435 | name(void) |
413 | { | | 436 | { |
414 | char *s; | | 437 | char *s; |
415 | sbuf_t *sb; | | 438 | sbuf_t *sb; |
416 | sym_t *sym; | | 439 | sym_t *sym; |
417 | int tok; | | 440 | int tok; |
418 | | | 441 | |
419 | sb = allocsb(); | | 442 | sb = allocsb(); |
420 | sb->sb_name = yytext; | | 443 | sb->sb_name = yytext; |
421 | sb->sb_len = yyleng; | | 444 | sb->sb_len = yyleng; |
422 | sb->sb_hash = hash(yytext); | | 445 | sb->sb_hash = hash(yytext); |
423 | if ((sym = search(sb)) != NULL && sym->s_keyw) { | | 446 | if ((sym = search(sb)) != NULL && sym->s_keyw) { |
424 | freesb(sb); | | 447 | struct kwtab *kw = sym->s_keyw; |
425 | return (keyw(sym)); | | 448 | if (!kw->kw_attr || attron) { |
| | | 449 | freesb(sb); |
| | | 450 | return (keyw(sym)); |
| | | 451 | } |
426 | } | | 452 | } |
427 | | | 453 | |
428 | sb->sb_sym = sym; | | 454 | sb->sb_sym = sym; |
429 | | | 455 | |
430 | if (sym != NULL) { | | 456 | if (sym != NULL) { |
431 | if (blklev < sym->s_blklev) | | 457 | if (blklev < sym->s_blklev) |
432 | LERROR("name()"); | | 458 | LERROR("name()"); |
433 | sb->sb_name = sym->s_name; | | 459 | sb->sb_name = sym->s_name; |
434 | sb->sb_len = strlen(sym->s_name); | | 460 | sb->sb_len = strlen(sym->s_name); |
435 | tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME; | | 461 | tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME; |
436 | } else { | | 462 | } else { |
437 | s = getblk(yyleng + 1); | | 463 | s = getblk(yyleng + 1); |
438 | (void)memcpy(s, yytext, yyleng + 1); | | 464 | (void)memcpy(s, yytext, yyleng + 1); |