2 /* $NetBSD: cgram.y,v 1.47 2009/10/03 01:35:20 christos Exp $ */
5 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
6 * Copyright (c) 1994, 1995 Jochen Pohl
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Jochen Pohl for
21 * 4. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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
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
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include <sys/cdefs.h>
37 #if defined(__RCSID) && !defined(lint)
38 __RCSID
("$NetBSD: cgram.y,v 1.47 2009/10/03 01:35:20 christos Exp $");
49 * Contains the level of current declaration. 0 is extern.
50 * Used for symbol table entries.
55 * level for memory allocation. Normaly the same as blklev.
56 * An exeption is the declaration of arguments in prototypes. Memory
57 * for these can't be freed after the declaration, but symbols must
58 * be removed from the symbol table after the declaration.
63 * Save the no-warns state and restore it to avoid the problem where
64 * if (expr) { stmt } / * NOLINT * / stmt;
66 static int onowarn
= -1;
68 static int toicon
(tnode_t
*, int);
69 static void idecl
(sym_t
*, int, sbuf_t
*);
70 static void ignuptorp
(void);
73 static inline
void CLRWFLGS
(const char *file
, size_t line
);
74 static inline
void CLRWFLGS
(const char *file
, size_t line
)
76 printf
("%s, %d: clear flags %s %zu\n", curr_pos.p_file
,
77 curr_pos.p_line
, file
, line
);
82 static inline
void SAVE
(const char *file
, size_t line
);
83 static inline
void SAVE
(const char *file
, size_t line
)
87 printf
("%s, %d: save flags %s %zu = %d\n", curr_pos.p_file
,
88 curr_pos.p_line
, file
, line
, nowarn
);
92 static inline
void RESTORE
(const char *file
, size_t line
);
93 static inline
void RESTORE
(const char *file
, size_t line
)
97 printf
("%s, %d: restore flags %s %zu = %d\n", curr_pos.p_file
,
98 curr_pos.p_line
, file
, line
, nowarn
);
101 CLRWFLGS
(file
, line
);
104 #define CLRWFLGS(f, l) clrwflgs(), onowarn = -1
105 #define SAVE(f, l) onowarn = nowarn
106 #define RESTORE(f, l) (void)(onowarn == -1 ? (clrwflgs(), 0) : (nowarn = onowarn))
128 %token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN
129 %token
<y_op
> T_STROP
131 %token
<y_op
> T_INCDEC
135 %token
<y_op
> T_DIVOP
136 %token
<y_op
> T_ADDOP
137 %token
<y_op
> T_SHFTOP
138 %token
<y_op
> T_RELOP
143 %token
<y_op
> T_LOGAND
144 %token
<y_op
> T_LOGOR
147 %token
<y_op
> T_ASSIGN
148 %token
<y_op
> T_OPASS
155 /* storage classes (extern, static, auto, register and typedef) */
156 %token
<y_scl
> T_SCLASS
158 /* types (char, int, short, long, unsigned, signed, float, double, void) */
159 %token
<y_tspec
> T_TYPE
161 /* qualifiers (const, volatile) */
162 %token
<y_tqual
> T_QUAL
164 /* struct or union */
165 %token
<y_tspec
> T_SOU
170 /* remaining keywords */
184 %token T_SYMBOLRENAME
186 /* Type Attributes */
187 %token
<y_type
> T_ATTRIBUTE
188 %token
<y_type
> T_AT_ALIGNED
189 %token
<y_type
> T_AT_DEPRECATED
190 %token
<y_type
> T_AT_MAY_ALIAS
191 %token
<y_type
> T_AT_PACKED
192 %token
<y_type
> T_AT_TUINION
193 %token
<y_type
> T_AT_TUNION
194 %token
<y_type
> T_AT_UNUSED
199 %right T_ASSIGN T_OPASS
200 %right T_QUEST T_COLON
211 %right T_UNOP T_INCDEC T_SIZEOF T_ALIGNOF T_REAL T_IMAG
212 %left T_LPARN T_LBRACK T_STROP
215 %token
<y_sb
> T_TYPENAME
217 %token
<y_strg
> T_STRING
219 %type
<y_sym
> func_decl
220 %type
<y_sym
> notype_decl
221 %type
<y_sym
> type_decl
222 %type
<y_type
> typespec
223 %type
<y_type
> clrtyp_typespec
224 %type
<y_type
> notype_typespec
225 %type
<y_type
> struct_spec
226 %type
<y_type
> enum_spec
227 %type
<y_type
> type_attribute
228 %type
<y_type
> type_attribute_spec
229 %type
<y_sym
> struct_tag
230 %type
<y_sym
> enum_tag
231 %type
<y_tspec
> struct
232 %type
<y_sym
> struct_declaration
233 %type
<y_sb
> identifier
234 %type
<y_sym
> member_declaration_list_with_rbrace
235 %type
<y_sym
> member_declaration_list
236 %type
<y_sym
> member_declaration
237 %type
<y_sym
> notype_member_decls
238 %type
<y_sym
> type_member_decls
239 %type
<y_sym
> notype_member_decl
240 %type
<y_sym
> type_member_decl
241 %type
<y_tnode
> constant
242 %type
<y_sym
> enum_declaration
243 %type
<y_sym
> enums_with_opt_comma
245 %type
<y_sym
> enumerator
247 %type
<y_sym
> notype_direct_decl
248 %type
<y_sym
> type_direct_decl
249 %type
<y_pqinf
> pointer
250 %type
<y_pqinf
> asterisk
251 %type
<y_sym
> param_decl
252 %type
<y_sym
> param_list
253 %type
<y_sym
> abs_decl_param_list
254 %type
<y_sym
> direct_param_decl
255 %type
<y_sym
> notype_param_decl
256 %type
<y_sym
> direct_notype_param_decl
257 %type
<y_pqinf
> type_qualifier_list
258 %type
<y_pqinf
> type_qualifier
259 %type
<y_sym
> identifier_list
260 %type
<y_sym
> abs_decl
261 %type
<y_sym
> direct_abs_decl
262 %type
<y_sym
> vararg_parameter_type_list
263 %type
<y_sym
> parameter_type_list
264 %type
<y_sym
> parameter_declaration
266 %type
<y_tnode
> expr_stmnt_val
267 %type
<y_tnode
> expr_stmnt_list
269 %type
<y_tnode
> func_arg_list
270 %type
<y_op
> point_or_arrow
271 %type
<y_type
> type_name
272 %type
<y_sym
> abstract_declaration
273 %type
<y_tnode
> do_while_expr
274 %type
<y_tnode
> opt_expr
275 %type
<y_strg
> string
276 %type
<y_strg
> string2
277 %type
<y_sb
> opt_asm_or_symbolrename
278 %type
<y_range
> range
279 %type
<y_range
> lorange
287 /* empty translation unit */
290 /* empty translation unit */
299 | translation_unit ext_decl
306 CLRWFLGS
(__FILE__
, __LINE__
);
310 CLRWFLGS
(__FILE__
, __LINE__
);
317 /* syntax error: empty declaration */
320 /* syntax error: empty declaration */
324 | clrtyp deftyp notype_init_decls T_SEMI
{
326 /* old style declaration; add "int" */
329 /* old style declaration; add "int" */
333 | declmods deftyp T_SEMI
{
334 if
(dcs
->d_scl
== TYPEDEF
) {
335 /* typedef declares no type name */
338 /* empty declaration */
342 | declmods deftyp notype_init_decls T_SEMI
343 | declspecs deftyp T_SEMI
{
344 if
(dcs
->d_scl
== TYPEDEF
) {
345 /* typedef declares no type name */
347 } else if
(!dcs
->d_nedecl
) {
348 /* empty declaration */
352 | declspecs deftyp type_init_decls T_SEMI
363 if
($1->s_type
->t_tspec
!= FUNC
) {
368 if
($1->s_type
->t_typedef
) {
369 /* ()-less function definition */
378 } opt_arg_declaration_list
{
390 clrtyp deftyp notype_decl
{
393 | declmods deftyp notype_decl
{
396 | declspecs deftyp type_decl
{
401 opt_arg_declaration_list:
403 | arg_declaration_list
406 arg_declaration_list:
408 | arg_declaration_list arg_declaration
409 /* XXX or better "arg_declaration error" ? */
414 * "arg_declaration" is separated from "declaration" because it
415 * needs other error handling.
419 declmods deftyp T_SEMI
{
420 /* empty declaration */
423 | declmods deftyp notype_init_decls T_SEMI
424 | declspecs deftyp T_SEMI
{
425 if
(!dcs
->d_nedecl
) {
426 /* empty declaration */
429 tspec_t ts
= dcs
->d_type
->t_tspec
;
430 /* %s declared in argument declaration list */
431 warning
(3, ts
== STRUCT ?
"struct" :
432 (ts
== UNION ?
"union" : "enum"));
435 | declspecs deftyp type_init_decls T_SEMI
{
437 tspec_t ts
= dcs
->d_type
->t_tspec
;
438 /* %s declared in argument declaration list */
439 warning
(3, ts
== STRUCT ?
"struct" :
440 (ts
== UNION ?
"union" : "enum"));
448 declmods deftyp T_SEMI
{
449 if
(dcs
->d_scl
== TYPEDEF
) {
450 /* typedef declares no type name */
453 /* empty declaration */
457 | declmods deftyp notype_init_decls T_SEMI
458 | declspecs deftyp T_SEMI
{
459 if
(dcs
->d_scl
== TYPEDEF
) {
460 /* typedef declares no type name */
462 } else if
(!dcs
->d_nedecl
) {
463 /* empty declaration */
467 | declspecs deftyp type_init_decls T_SEMI
473 | T_AT_ALIGNED T_LPARN constant T_RPARN
483 T_ATTRIBUTE T_LPARN T_LPARN type_attribute_spec T_RPARN T_RPARN
505 | declmods typespec
{
508 | declspecs type_attribute
510 | declspecs notype_typespec
{
535 clrtyp notype_typespec
{
538 | T_TYPENAME clrtyp
{
539 $$
= getsym
($1)->s_type
;
548 $$
= getsym
($1)->s_type
;
569 * STDC requires that "struct a;" always introduces
570 * a new tag if "a" is not declared at current level
572 * yychar is valid because otherwise the parser would
573 * not been able to deceide if he must shift or reduce
575 $$
= mktag
($2, $1, 0, yychar == T_SEMI
);
577 |
struct struct_tag
{
578 dcs
->d_tagtyp
= mktag
($2, $1, 1, 0);
579 } struct_declaration
{
580 $$
= compltag
(dcs
->d_tagtyp
, $4);
583 dcs
->d_tagtyp
= mktag
(NULL
, $1, 1, 0);
584 } struct_declaration
{
585 $$
= compltag
(dcs
->d_tagtyp
, $3);
594 struct type_attribute
597 pushdecl
($1 == STRUCT ? MOS
: MOU
);
599 dcs
->d_stralign
= CHAR_BIT
;
611 struct_decl_lbrace member_declaration_list_with_rbrace
{
622 member_declaration_list_with_rbrace:
623 member_declaration_list T_SEMI T_RBRACE
{
626 | member_declaration_list T_RBRACE
{
628 /* syntax req. ";" after last struct/union member */
631 /* syntax req. ";" after last struct/union member */
641 member_declaration_list:
645 | member_declaration_list T_SEMI member_declaration
{
651 noclass_declmods deftyp
{
652 /* too late, i know, but getsym() compensates it */
654 } notype_member_decls
{
658 | noclass_declspecs deftyp
{
660 } type_member_decls
{
664 | noclass_declmods deftyp
{
665 /* struct or union member must be named */
669 | noclass_declspecs deftyp
{
670 /* struct or union member must be named */
684 | noclass_declmods typespec
{
687 | noclass_declspecs T_QUAL
{
690 | noclass_declspecs notype_typespec
{
693 | noclass_declspecs type_attribute
700 | noclass_declmods T_QUAL
{
709 | notype_member_decls
{
711 } T_COMMA type_member_decl
{
712 $$
= lnklst
($1, decl1str
($4));
720 | type_member_decls
{
722 } T_COMMA type_member_decl
{
723 $$
= lnklst
($1, decl1str
($4));
731 | notype_decl T_COLON constant
{
732 $$
= bitfield
($1, toicon
($3, 1));
737 $$
= bitfield
(NULL
, toicon
($3, 1));
745 | type_decl T_COLON constant
{
746 $$
= bitfield
($1, toicon
($3, 1));
751 $$
= bitfield
(NULL
, toicon
($3, 1));
757 $$
= mktag
($2, ENUM
, 0, 0);
760 dcs
->d_tagtyp
= mktag
($2, ENUM
, 1, 0);
762 $$
= compltag
(dcs
->d_tagtyp
, $4);
765 dcs
->d_tagtyp
= mktag
(NULL
, ENUM
, 1, 0);
767 $$
= compltag
(dcs
->d_tagtyp
, $3);
789 enum_decl_lbrace enums_with_opt_comma T_RBRACE
{
801 enums_with_opt_comma:
807 /* trailing "," prohibited in enum declaration */
810 /* trailing "," prohibited in enum declaration */
821 | enums T_COMMA enumerator
{
831 $$
= ename
($1, enumval
, 1);
833 | ename T_ASSIGN constant
{
834 $$
= ename
($1, toicon
($3, 1), 0);
847 | notype_init_decls T_COMMA type_init_decl
852 | type_init_decls T_COMMA type_init_decl
856 notype_decl opt_asm_or_symbolrename
{
860 | notype_decl opt_asm_or_symbolrename
{
862 } T_ASSIGN initializer
{
868 type_decl opt_asm_or_symbolrename
{
872 | type_decl opt_asm_or_symbolrename
{
874 } T_ASSIGN initializer
{
883 | pointer notype_direct_decl
{
890 $$
= dname
(getsym
($1));
892 | T_LPARN type_decl T_RPARN
{
895 | notype_direct_decl T_LBRACK T_RBRACK
{
896 $$
= addarray
($1, 0, 0);
898 | notype_direct_decl T_LBRACK constant T_RBRACK
{
899 $$
= addarray
($1, 1, toicon
($3, 0));
901 | notype_direct_decl param_list
{
902 $$
= addfunc
($1, $2);
906 | notype_direct_decl type_attribute
913 | pointer type_direct_decl
{
920 $$
= dname
(getsym
($1));
922 | T_LPARN type_decl T_RPARN
{
925 | type_direct_decl T_LBRACK T_RBRACK
{
926 $$
= addarray
($1, 0, 0);
928 | type_direct_decl T_LBRACK constant T_RBRACK
{
929 $$
= addarray
($1, 1, toicon
($3, 0));
931 | type_direct_decl param_list
{
932 $$
= addfunc
($1, $2);
936 | type_direct_decl type_attribute
940 * param_decl and notype_param_decl exist to avoid a conflict in
941 * argument lists. A typename enclosed in parens should always be
942 * treated as a typename, not an argument.
943 * "typedef int a; f(int (a));" is "typedef int a; f(int foo(a));"
944 * not "typedef int a; f(int a);"
950 | pointer direct_param_decl
{
957 $$
= dname
(getsym
($1));
959 | T_LPARN notype_param_decl T_RPARN
{
962 | direct_param_decl T_LBRACK T_RBRACK
{
963 $$
= addarray
($1, 0, 0);
965 | direct_param_decl T_LBRACK constant T_RBRACK
{
966 $$
= addarray
($1, 1, toicon
($3, 0));
968 | direct_param_decl param_list
{
969 $$
= addfunc
($1, $2);
976 direct_notype_param_decl
{
979 | pointer direct_notype_param_decl
{
984 direct_notype_param_decl:
986 $$
= dname
(getsym
($1));
988 | T_LPARN notype_param_decl T_RPARN
{
991 | direct_notype_param_decl T_LBRACK T_RBRACK
{
992 $$
= addarray
($1, 0, 0);
994 | direct_notype_param_decl T_LBRACK constant T_RBRACK
{
995 $$
= addarray
($1, 1, toicon
($3, 0));
997 | direct_notype_param_decl param_list
{
998 $$
= addfunc
($1, $2);
1008 | asterisk type_qualifier_list
{
1009 $$
= mergepq
($1, $2);
1011 | asterisk pointer
{
1012 $$
= mergepq
($1, $2);
1014 | asterisk type_qualifier_list pointer
{
1015 $$
= mergepq
(mergepq
($1, $2), $3);
1021 $$
= xcalloc
(1, sizeof
(pqinf_t
));
1026 type_qualifier_list:
1030 | type_qualifier_list type_qualifier
{
1031 $$
= mergepq
($1, $2);
1037 $$
= xcalloc
(1, sizeof
(pqinf_t
));
1047 id_list_lparn identifier_list T_RPARN
{
1050 | abs_decl_param_list
{
1064 $$
= iname
(getsym
($1));
1066 | identifier_list T_COMMA T_NAME
{
1067 $$
= lnklst
($1, iname
(getsym
($3)));
1069 | identifier_list
error {
1074 abs_decl_param_list:
1075 abs_decl_lparn T_RPARN
{
1078 | abs_decl_lparn vararg_parameter_type_list T_RPARN
{
1082 | abs_decl_lparn
error T_RPARN
{
1094 vararg_parameter_type_list:
1095 parameter_type_list
{
1098 | parameter_type_list T_COMMA T_ELLIPSE
{
1104 /* ANSI C requires formal parameter before "..." */
1106 } else if
(!tflag
) {
1107 /* ANSI C requires formal parameter before "..." */
1115 parameter_type_list:
1116 parameter_declaration
{
1119 | parameter_type_list T_COMMA parameter_declaration
{
1120 $$
= lnklst
($1, $3);
1124 parameter_declaration:
1126 $$
= decl1arg
(aname
(), 0);
1128 | declspecs deftyp
{
1129 $$
= decl1arg
(aname
(), 0);
1131 | declmods deftyp notype_param_decl
{
1132 $$
= decl1arg
($3, 0);
1135 * param_decl is needed because of following conflict:
1136 * "typedef int a; f(int (a));" could be parsed as
1137 * "function with argument a of type int", or
1138 * "function with an abstract argument of type function".
1139 * This grammar realizes the second case.
1141 | declspecs deftyp param_decl
{
1142 $$
= decl1arg
($3, 0);
1144 | declmods deftyp abs_decl
{
1145 $$
= decl1arg
($3, 0);
1147 | declspecs deftyp abs_decl
{
1148 $$
= decl1arg
($3, 0);
1152 opt_asm_or_symbolrename: /* expect only one */
1156 | T_ASM T_LPARN T_STRING T_RPARN
{
1157 freeyyv
(&$3, T_STRING
);
1160 | T_SYMBOLRENAME T_LPARN T_NAME T_RPARN
{
1170 expr %prec T_COMMA
{
1173 | init_by_name init_expr %prec T_COMMA
1174 | init_lbrace init_expr_list init_rbrace
1175 | init_lbrace init_expr_list T_COMMA init_rbrace
1180 init_expr %prec T_COMMA
1181 | init_expr_list T_COMMA init_expr
1185 constant T_ELLIPSE
{
1186 $$.lo
= toicon
($1, 1);
1191 $$.lo
= toicon
($1, 1);
1194 | lorange constant
{
1196 $$.hi
= toicon
($2, 1);
1201 T_LBRACK range T_RBRACK T_ASSIGN
{
1205 | point identifier T_ASSIGN
{
1210 | identifier T_COLON
{
1231 } abstract_declaration
{
1237 abstract_declaration:
1238 noclass_declmods deftyp
{
1239 $$
= decl1abs
(aname
());
1241 | noclass_declspecs deftyp
{
1242 $$
= decl1abs
(aname
());
1244 | noclass_declmods deftyp abs_decl
{
1247 | noclass_declspecs deftyp abs_decl
{
1254 $$
= addptr
(aname
(), $1);
1259 | pointer direct_abs_decl
{
1260 $$
= addptr
($2, $1);
1265 T_LPARN abs_decl T_RPARN
{
1268 | T_LBRACK T_RBRACK
{
1269 $$
= addarray
(aname
(), 0, 0);
1271 | T_LBRACK constant T_RBRACK
{
1272 $$
= addarray
(aname
(), 1, toicon
($2, 0));
1274 | direct_abs_decl T_LBRACK T_RBRACK
{
1275 $$
= addarray
($1, 0, 0);
1277 | direct_abs_decl T_LBRACK constant T_RBRACK
{
1278 $$
= addarray
($1, 1, toicon
($3, 0));
1280 | abs_decl_param_list
{
1281 $$
= addfunc
(aname
(), $1);
1285 | direct_abs_decl abs_decl_param_list
{
1286 $$
= addfunc
($1, $2);
1290 | direct_abs_decl type_attribute
1313 identifier T_COLON
{
1315 label
(T_NAME
, getsym
($1), NULL
);
1317 | T_CASE constant T_COLON
{
1318 label
(T_CASE
, NULL
, $2);
1321 | T_CASE constant T_ELLIPSE constant T_COLON
{
1322 /* XXX: We don't fill all cases */
1323 label
(T_CASE
, NULL
, $2);
1326 | T_DEFAULT T_COLON
{
1327 label
(T_DEFAULT
, NULL
, NULL
);
1333 comp_stmnt_lbrace declaration_list opt_stmnt_list comp_stmnt_rbrace
1334 | comp_stmnt_lbrace opt_stmnt_list comp_stmnt_rbrace
1362 | stmnt_list stmnt
{
1363 RESTORE
(__FILE__
, __LINE__
);
1365 | stmnt_list
error T_SEMI
1379 * The following two productions are used to implement
1380 * ({ [[decl-list] stmt-list] }).
1381 * XXX: This is not well tested.
1385 /* XXX: We should really do that only on the last name */
1386 if
($1->tn_op
== NAME
)
1387 $1->tn_sym
->s_used
= 1;
1394 $$
->tn_type
= gettyp
(VOID
);
1400 | expr_stmnt_list expr_stmnt_val
{
1407 SAVE
(__FILE__
, __LINE__
);
1411 | if_without_else T_ELSE
{
1412 SAVE
(__FILE__
, __LINE__
);
1415 CLRWFLGS
(__FILE__
, __LINE__
);
1418 | if_without_else T_ELSE
error {
1419 CLRWFLGS
(__FILE__
, __LINE__
);
1422 | switch_expr stmnt
{
1423 CLRWFLGS
(__FILE__
, __LINE__
);
1426 | switch_expr
error {
1427 CLRWFLGS
(__FILE__
, __LINE__
);
1438 T_IF T_LPARN expr T_RPARN
{
1440 CLRWFLGS
(__FILE__
, __LINE__
);
1445 T_SWITCH T_LPARN expr T_RPARN
{
1447 CLRWFLGS
(__FILE__
, __LINE__
);
1453 CLRWFLGS
(__FILE__
, __LINE__
);
1459 CLRWFLGS
(__FILE__
, __LINE__
);
1462 | while_expr
error {
1463 CLRWFLGS
(__FILE__
, __LINE__
);
1466 | do_stmnt do_while_expr
{
1471 CLRWFLGS
(__FILE__
, __LINE__
);
1475 CLRWFLGS
(__FILE__
, __LINE__
);
1479 CLRWFLGS
(__FILE__
, __LINE__
);
1485 T_WHILE T_LPARN expr T_RPARN
{
1487 CLRWFLGS
(__FILE__
, __LINE__
);
1498 T_WHILE T_LPARN expr T_RPARN T_SEMI
{
1504 T_FOR T_LPARN declspecs deftyp notype_init_decls T_SEMI opt_expr
1505 T_SEMI opt_expr T_RPARN
{
1508 CLRWFLGS
(__FILE__
, __LINE__
);
1510 | T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN
{
1512 CLRWFLGS
(__FILE__
, __LINE__
);
1526 goto identifier T_SEMI
{
1529 | goto
error T_SEMI
{
1532 | T_CONTINUE T_SEMI
{
1541 | T_RETURN expr T_SEMI
{
1553 T_ASM T_LPARN read_until_rparn T_SEMI
{
1556 | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI
{
1570 CLRWFLGS
(__FILE__
, __LINE__
);
1572 | declaration_list declaration
{
1573 CLRWFLGS
(__FILE__
, __LINE__
);
1578 expr %prec T_COMMA
{
1585 $$
= build
(MULT
, $1, $3);
1587 | expr T_DIVOP expr
{
1588 $$
= build
($2, $1, $3);
1590 | expr T_ADDOP expr
{
1591 $$
= build
($2, $1, $3);
1593 | expr T_SHFTOP expr
{
1594 $$
= build
($2, $1, $3);
1596 | expr T_RELOP expr
{
1597 $$
= build
($2, $1, $3);
1599 | expr T_EQOP expr
{
1600 $$
= build
($2, $1, $3);
1603 $$
= build
(AND
, $1, $3);
1606 $$
= build
(XOR
, $1, $3);
1609 $$
= build
(OR
, $1, $3);
1611 | expr T_LOGAND expr
{
1612 $$
= build
(LOGAND
, $1, $3);
1614 | expr T_LOGOR expr
{
1615 $$
= build
(LOGOR
, $1, $3);
1617 | expr T_QUEST expr T_COLON expr
{
1618 $$
= build
(QUEST
, $1, build
(COLON
, $3, $5));
1620 | expr T_ASSIGN expr
{
1621 $$
= build
(ASSIGN
, $1, $3);
1623 | expr T_OPASS expr
{
1624 $$
= build
($2, $1, $3);
1626 | expr T_COMMA expr
{
1627 $$
= build
(COMMA
, $1, $3);
1636 /* XXX really necessary? */
1639 $$
= getnnode
(getsym
($1), yychar);
1645 $$
= getcnode
(gettyp
($1->v_tspec
), $1);
1647 | T_LPARN expr T_RPARN
{
1652 | T_LPARN comp_stmnt_lbrace declaration_list expr_stmnt_list
{
1655 initsym
= mktempsym
(duptyp
($4->tn_type
));
1659 } comp_stmnt_rbrace T_RPARN
{
1660 $$
= getnnode
(initsym
, 0);
1662 | T_LPARN comp_stmnt_lbrace expr_stmnt_list
{
1665 initsym
= mktempsym
($3->tn_type
);
1669 } comp_stmnt_rbrace T_RPARN
{
1670 $$
= getnnode
(initsym
, 0);
1673 $$
= build
($2 == INC ? INCAFT
: DECAFT
, $1, NULL
);
1676 $$
= build
($1 == INC ? INCBEF
: DECBEF
, $2, NULL
);
1679 $$
= build
(STAR
, $2, NULL
);
1682 $$
= build
(AMPER
, $2, NULL
);
1685 $$
= build
($1, $2, NULL
);
1688 if
(tflag
&& $1 == PLUS
) {
1689 /* unary + is illegal in traditional C */
1692 $$
= build
($1 == PLUS ? UPLUS
: UMINUS
, $2, NULL
);
1694 | term T_LBRACK expr T_RBRACK
{
1695 $$
= build
(STAR
, build
(PLUS
, $1, $3), NULL
);
1697 | term T_LPARN T_RPARN
{
1698 $$
= funccall
($1, NULL
);
1700 | term T_LPARN func_arg_list T_RPARN
{
1701 $$
= funccall
($1, $3);
1703 | term point_or_arrow T_NAME
{
1706 /* XXX strmemb should be integrated in build() */
1708 /* must to this before strmemb is called */
1711 msym
= strmemb
($1, $2, getsym
($3));
1712 $$
= build
($2, $1, getnnode
(msym
, 0));
1718 $$
= build
(REAL
, $2, NULL
);
1721 $$
= build
(IMAG
, $2, NULL
);
1723 | T_REAL T_LPARN term T_RPARN
{
1724 $$
= build
(REAL
, $3, NULL
);
1726 | T_IMAG T_LPARN term T_RPARN
{
1727 $$
= build
(IMAG
, $3, NULL
);
1729 | T_SIZEOF term %prec T_SIZEOF
{
1730 if
(($$
= $2 == NULL ? NULL
: bldszof
($2->tn_type
)) != NULL
)
1731 chkmisc
($2, 0, 0, 0, 0, 0, 1);
1733 | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF
{
1736 | T_ALIGNOF T_LPARN type_name T_RPARN %prec T_ALIGNOF
{
1739 | T_LPARN type_name T_RPARN term %prec T_UNOP
{
1742 | T_LPARN type_name T_RPARN %prec T_UNOP
{
1743 sym_t
*tmp
= mktempsym
($2);
1744 idecl
(tmp
, 1, NULL
);
1745 } init_lbrace init_expr_list init_rbrace
{
1748 $$
= getnnode
(initsym
, 0);
1756 | T_STRING string2
{
1757 $$
= catstrg
($1, $2);
1764 /* concatenated strings are illegal in traditional C */
1769 | string2 T_STRING
{
1770 $$
= catstrg
($1, $2);
1775 expr %prec T_COMMA
{
1776 $$
= funcarg
(NULL
, $1);
1778 | func_arg_list T_COMMA expr
{
1779 $$
= funcarg
($1, $3);
1810 yyerror(const char *msg
)
1818 static __inline
int uq_gt
(uint64_t, uint64_t);
1819 static __inline
int q_gt
(int64_t, int64_t);
1822 uq_gt
(uint64_t a
, uint64_t b
)
1829 q_gt
(int64_t a
, int64_t b
)
1835 #define q_lt(a, b) q_gt(b, a)
1838 * Gets a node for a constant and returns the value of this constant
1840 * Is the node not constant or too large for int or of type float,
1841 * a warning will be printed.
1843 * toicon() should be used only inside declarations. If it is used in
1844 * expressions, it frees the memory used for the expression.
1847 toicon
(tnode_t
*tn
, int required
)
1853 v
= constant
(tn
, required
);
1856 * Abstract declarations are used inside expression. To free
1857 * the memory would be a fatal error.
1859 if
(dcs
->d_ctx
!= ABSTRACT
)
1862 if
((t
= v
->v_tspec
) == FLOAT || t
== DOUBLE || t
== LDOUBLE
) {
1864 /* integral constant expression expected */
1869 if
(uq_gt
((uint64_t)v
->v_quad
,
1870 (uint64_t)INT_MAX
)) {
1871 /* integral constant too large */
1875 if
(q_gt
(v
->v_quad
, (int64_t)INT_MAX
) ||
1876 q_lt
(v
->v_quad
, (int64_t)INT_MIN
)) {
1877 /* integral constant too large */
1887 idecl
(sym_t
*decl
, int initflg
, sbuf_t
*renaming
)
1894 switch
(dcs
->d_ctx
) {
1896 if
(renaming
!= NULL
) {
1897 if
(decl
->s_rename
!= NULL
)
1900 s
= getlblk
(1, renaming
->sb_len
+ 1);
1901 (void)memcpy
(s
, renaming
->sb_name
, renaming
->sb_len
+ 1);
1903 freeyyv
(&renaming
, T_NAME
);
1905 decl1ext
(decl
, initflg
);
1908 if
(renaming
!= NULL
) {
1909 /* symbol renaming can't be used on function arguments */
1911 freeyyv
(&renaming
, T_NAME
);
1914 (void)decl1arg
(decl
, initflg
);
1917 if
(renaming
!= NULL
) {
1918 /* symbol renaming can't be used on automatic variables */
1920 freeyyv
(&renaming
, T_NAME
);
1923 decl1loc
(decl
, initflg
);
1929 if
(initflg
&& !initerr
)
1934 * Discard all input tokens up to and including the next
1935 * unmatched right paren
1944 freeyyv
(&yylval, yychar);
1947 while
(yychar != T_RPARN ||
--level
> 0) {
1948 if
(yychar == T_LPARN
) {
1950 } else if
(yychar <= 0) {
1953 freeyyv
(&yylval, yychar = yylex());