Initial import from FreeBSD RELENG_4:
[games.git] / usr.bin / xlint / lint1 / cgram.y
1 %{
2 /*      $NetBSD: cgram.y,v 1.8 1995/10/02 17:31:35 jpo Exp $    */
3
4 /*
5  * Copyright (c) 1994, 1995 Jochen Pohl
6  * All Rights Reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by Jochen Pohl for
19  *      The NetBSD Project.
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.
22  *
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
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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
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
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 #ifndef lint
36 static char rcsid[] = "$NetBSD: cgram.y,v 1.8 1995/10/02 17:31:35 jpo Exp $";
37 #endif
38
39 #include <stdlib.h>
40 #include <limits.h>
41
42 #include "lint1.h"
43
44 /*
45  * Contains the level of current declaration. 0 is extern.
46  * Used for symbol table entries.
47  */
48 int     blklev;
49
50 /*
51  * level for memory allocation. Normaly the same as blklev.
52  * An exeption is the declaration of arguments in prototypes. Memory
53  * for these can't be freed after the declaration, but symbols must
54  * be removed from the symbol table after the declaration.
55  */
56 int     mblklev;
57
58 static  int     toicon __P((tnode_t *));
59 static  void    idecl __P((sym_t *, int));
60 static  void    ignuptorp __P((void));
61
62 %}
63
64 %union {
65         int     y_int;
66         val_t   *y_val;
67         sbuf_t  *y_sb;
68         sym_t   *y_sym;
69         op_t    y_op;
70         scl_t   y_scl;
71         tspec_t y_tspec;
72         tqual_t y_tqual;
73         type_t  *y_type;
74         tnode_t *y_tnode;
75         strg_t  *y_strg;
76         pqinf_t *y_pqinf;
77 };
78
79 %token                  T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN
80 %token  <y_op>          T_STROP
81 %token  <y_op>          T_UNOP
82 %token  <y_op>          T_INCDEC
83 %token                  T_SIZEOF
84 %token  <y_op>          T_MULT
85 %token  <y_op>          T_DIVOP
86 %token  <y_op>          T_ADDOP
87 %token  <y_op>          T_SHFTOP
88 %token  <y_op>          T_RELOP
89 %token  <y_op>          T_EQOP
90 %token  <y_op>          T_AND
91 %token  <y_op>          T_XOR
92 %token  <y_op>          T_OR
93 %token  <y_op>          T_LOGAND
94 %token  <y_op>          T_LOGOR
95 %token                  T_QUEST
96 %token                  T_COLON
97 %token  <y_op>          T_ASSIGN
98 %token  <y_op>          T_OPASS
99 %token                  T_COMMA
100 %token                  T_SEMI
101 %token                  T_ELLIPSE
102
103 /* storage classes (extern, static, auto, register and typedef) */
104 %token  <y_scl>         T_SCLASS
105
106 /* types (char, int, short, long, unsigned, signed, float, double, void) */
107 %token  <y_tspec>       T_TYPE
108
109 /* qualifiers (const, volatile) */
110 %token  <y_tqual>       T_QUAL
111
112 /* struct or union */
113 %token  <y_tspec>       T_SOU
114
115 /* enum */
116 %token                  T_ENUM
117
118 /* remaining keywords */
119 %token                  T_CASE
120 %token                  T_DEFAULT
121 %token                  T_IF
122 %token                  T_ELSE
123 %token                  T_SWITCH
124 %token                  T_DO
125 %token                  T_WHILE
126 %token                  T_FOR
127 %token                  T_GOTO
128 %token                  T_CONTINUE
129 %token                  T_BREAK
130 %token                  T_RETURN
131 %token                  T_ASM
132
133 %left   T_COMMA
134 %right  T_ASSIGN T_OPASS
135 %right  T_QUEST T_COLON
136 %left   T_LOGOR
137 %left   T_LOGAND
138 %left   T_OR
139 %left   T_XOR
140 %left   T_AND
141 %left   T_EQOP
142 %left   T_RELOP
143 %left   T_SHFTOP
144 %left   T_ADDOP
145 %left   T_MULT T_DIVOP
146 %right  T_UNOP T_INCDEC T_SIZEOF
147 %left   T_LPARN T_LBRACK T_STROP
148
149 %token  <y_sb>          T_NAME
150 %token  <y_sb>          T_TYPENAME
151 %token  <y_val>         T_CON
152 %token  <y_strg>        T_STRING
153
154 %type   <y_sym>         func_decl
155 %type   <y_sym>         notype_decl
156 %type   <y_sym>         type_decl
157 %type   <y_type>        typespec
158 %type   <y_type>        clrtyp_typespec
159 %type   <y_type>        notype_typespec
160 %type   <y_type>        struct_spec
161 %type   <y_type>        enum_spec
162 %type   <y_sym>         struct_tag
163 %type   <y_sym>         enum_tag
164 %type   <y_tspec>       struct
165 %type   <y_sym>         struct_declaration
166 %type   <y_sb>          identifier
167 %type   <y_sym>         member_declaration_list_with_rbrace
168 %type   <y_sym>         member_declaration_list
169 %type   <y_sym>         member_declaration
170 %type   <y_sym>         notype_member_decls
171 %type   <y_sym>         type_member_decls
172 %type   <y_sym>         notype_member_decl
173 %type   <y_sym>         type_member_decl
174 %type   <y_tnode>       constant
175 %type   <y_sym>         enum_declaration
176 %type   <y_sym>         enums_with_opt_comma
177 %type   <y_sym>         enums
178 %type   <y_sym>         enumerator
179 %type   <y_sym>         ename
180 %type   <y_sym>         notype_direct_decl
181 %type   <y_sym>         type_direct_decl
182 %type   <y_pqinf>       pointer
183 %type   <y_pqinf>       asterisk
184 %type   <y_sym>         param_decl
185 %type   <y_sym>         param_list
186 %type   <y_sym>         abs_decl_param_list
187 %type   <y_sym>         direct_param_decl
188 %type   <y_sym>         notype_param_decl
189 %type   <y_sym>         direct_notype_param_decl
190 %type   <y_pqinf>       type_qualifier_list
191 %type   <y_pqinf>       type_qualifier
192 %type   <y_sym>         identifier_list
193 %type   <y_sym>         abs_decl
194 %type   <y_sym>         direct_abs_decl
195 %type   <y_sym>         vararg_parameter_type_list
196 %type   <y_sym>         parameter_type_list
197 %type   <y_sym>         parameter_declaration
198 %type   <y_tnode>       expr
199 %type   <y_tnode>       term
200 %type   <y_tnode>       func_arg_list
201 %type   <y_op>          point_or_arrow
202 %type   <y_type>        type_name
203 %type   <y_sym>         abstract_declaration
204 %type   <y_tnode>       do_while_expr
205 %type   <y_tnode>       opt_expr
206 %type   <y_strg>        string
207 %type   <y_strg>        string2
208
209
210 %%
211
212 program:
213           /* empty */ {
214                 if (sflag) {
215                         /* empty translation unit */
216                         error(272);
217                 } else if (!tflag) {
218                         /* empty translation unit */
219                         warning(272);
220                 }
221           }
222         | translation_unit
223         ;
224
225 translation_unit:
226           ext_decl
227         | translation_unit ext_decl
228         ;
229
230 ext_decl:
231           func_def {
232                 glclup(0);
233                 clrwflgs();
234           }
235         | data_def {
236                 glclup(0);
237                 clrwflgs();
238           }
239         ;
240
241 data_def:
242           T_SEMI {
243                 if (sflag) {
244                         /* syntax error: empty declaration */
245                         error(0);
246                 } else if (!tflag) {
247                         /* syntax error: empty declaration */
248                         warning(0);
249                 }
250           }
251         | clrtyp deftyp notype_init_decls T_SEMI {
252                 if (sflag) {
253                         /* old style declaration; add "int" */
254                         error(1);
255                 } else if (!tflag) {
256                         /* old style declaration; add "int" */
257                         warning(1);
258                 }
259           }
260         | declmods deftyp T_SEMI {
261                 if (dcs->d_scl == TYPEDEF) {
262                         /* typedef declares no type name */
263                         warning(72);
264                 } else {
265                         /* empty declaration */
266                         warning(2);
267                 }
268           }
269         | declmods deftyp notype_init_decls T_SEMI
270         | declspecs deftyp T_SEMI {
271                 if (dcs->d_scl == TYPEDEF) {
272                         /* typedef declares no type name */
273                         warning(72);
274                 } else if (!dcs->d_nedecl) {
275                         /* empty declaration */
276                         warning(2);
277                 }
278           }
279         | declspecs deftyp type_init_decls T_SEMI
280         | error T_SEMI {
281                 globclup();             
282           }
283         | error T_RBRACE {
284                 globclup();
285           }
286         ;
287
288 func_def:
289           func_decl {
290                 if ($1->s_type->t_tspec != FUNC) {
291                         /* syntax error */
292                         error(249);
293                         YYERROR;
294                 }
295                 if ($1->s_type->t_typedef) {
296                         /* ()-less function definition */
297                         error(64);
298                         YYERROR;
299                 }
300                 funcdef($1);
301                 blklev++;
302                 pushdecl(ARG);
303           } opt_arg_declaration_list {
304                 popdecl();
305                 blklev--;
306                 cluparg();
307                 pushctrl(0);
308           } comp_stmnt {
309                 funcend();
310                 popctrl(0);
311           }
312         ;
313
314 func_decl:
315           clrtyp deftyp notype_decl {
316                 $$ = $3;
317           }
318         | declmods deftyp notype_decl {
319                 $$ = $3;
320           }
321         | declspecs deftyp type_decl {
322                 $$ = $3;
323           }
324         ;
325
326 opt_arg_declaration_list:
327           /* empty */
328         | arg_declaration_list
329         ;
330
331 arg_declaration_list:
332           arg_declaration
333         | arg_declaration_list arg_declaration
334         /* XXX or better "arg_declaration error" ? */
335         | error
336         ;
337
338 /*
339  * "arg_declaration" is separated from "declaration" because it
340  * needs other error handling.
341  */
342
343 arg_declaration:
344           declmods deftyp T_SEMI {
345                 /* empty declaration */
346                 warning(2);
347           }
348         | declmods deftyp notype_init_decls T_SEMI
349         | declspecs deftyp T_SEMI {
350                 if (!dcs->d_nedecl) {
351                         /* empty declaration */
352                         warning(2);
353                 } else {
354                         tspec_t ts = dcs->d_type->t_tspec;
355                         /* %s declared in argument declaration list */
356                         warning(3, ts == STRUCT ? "struct" :
357                                 (ts == UNION ? "union" : "enum"));
358                 }
359           }
360         | declspecs deftyp type_init_decls T_SEMI {
361                 if (dcs->d_nedecl) {
362                         tspec_t ts = dcs->d_type->t_tspec;
363                         /* %s declared in argument declaration list */
364                         warning(3, ts == STRUCT ? "struct" :
365                                 (ts == UNION ? "union" : "enum"));
366                 }
367           }
368         | declmods error
369         | declspecs error
370         ;
371
372 declaration:
373           declmods deftyp T_SEMI {
374                 if (dcs->d_scl == TYPEDEF) {
375                         /* typedef declares no type name */
376                         warning(72);
377                 } else {
378                         /* empty declaration */
379                         warning(2);
380                 }
381           }
382         | declmods deftyp notype_init_decls T_SEMI
383         | declspecs deftyp T_SEMI {
384                 if (dcs->d_scl == TYPEDEF) {
385                         /* typedef declares no type name */
386                         warning(72);
387                 } else if (!dcs->d_nedecl) {
388                         /* empty declaration */
389                         warning(2);
390                 }
391           }
392         | declspecs deftyp type_init_decls T_SEMI
393         | error T_SEMI
394         ;
395
396 clrtyp:
397           {
398                 clrtyp();
399           }
400         ;
401
402 deftyp:
403           /* empty */ {
404                 deftyp();
405           }
406         ;
407
408 declspecs:
409           clrtyp_typespec {
410                 addtype($1);
411           }
412         | declmods typespec {
413                 addtype($2);
414           }
415         | declspecs declmod
416         | declspecs notype_typespec {
417                 addtype($2);
418           }
419         ;
420
421 declmods:
422           clrtyp T_QUAL {
423                 addqual($2);
424           }
425         | clrtyp T_SCLASS {
426                 addscl($2);
427           }
428         | declmods declmod
429         ;
430
431 declmod:
432           T_QUAL {
433                 addqual($1);
434           }
435         | T_SCLASS {
436                 addscl($1);
437           }
438         ;
439
440 clrtyp_typespec:
441           clrtyp notype_typespec {
442                 $$ = $2;
443           }
444         | T_TYPENAME clrtyp {
445                 $$ = getsym($1)->s_type;
446           }
447         ;
448
449 typespec:
450           notype_typespec {
451                 $$ = $1;
452           }
453         | T_TYPENAME {
454                 $$ = getsym($1)->s_type;
455           }
456         ;
457
458 notype_typespec:
459           T_TYPE {
460                 $$ = gettyp($1);
461           }
462         | struct_spec {
463                 popdecl();
464                 $$ = $1;
465           }
466         | enum_spec {
467                 popdecl();
468                 $$ = $1;
469           }
470         ;
471
472 struct_spec:
473           struct struct_tag {
474                 /*
475                  * STDC requires that "struct a;" always introduces
476                  * a new tag if "a" is not declared at current level
477                  *
478                  * yychar is valid because otherwise the parser would
479                  * not been able to deceide if he must shift or reduce
480                  */
481                 $$ = mktag($2, $1, 0, yychar == T_SEMI);
482           }
483         | struct struct_tag {
484                 dcs->d_tagtyp = mktag($2, $1, 1, 0);
485           } struct_declaration {
486                 $$ = compltag(dcs->d_tagtyp, $4);
487           }
488         | struct {
489                 dcs->d_tagtyp = mktag(NULL, $1, 1, 0);
490           } struct_declaration {
491                 $$ = compltag(dcs->d_tagtyp, $3);
492           }
493         | struct error {
494                 symtyp = FVFT;
495                 $$ = gettyp(INT);
496           }
497         ;
498
499 struct:
500           T_SOU {
501                 symtyp = FTAG;
502                 pushdecl($1 == STRUCT ? MOS : MOU);
503                 dcs->d_offset = 0;
504                 dcs->d_stralign = CHAR_BIT;
505                 $$ = $1;
506           }
507         ;
508
509 struct_tag:
510           identifier {
511                 $$ = getsym($1);
512           }
513         ;
514
515 struct_declaration:
516           struct_decl_lbrace member_declaration_list_with_rbrace {
517                 $$ = $2;
518           }
519         ;
520
521 struct_decl_lbrace:
522           T_LBRACE {
523                 symtyp = FVFT;
524           }
525         ;
526
527 member_declaration_list_with_rbrace:
528           member_declaration_list T_SEMI T_RBRACE {
529                 $$ = $1;
530           }
531         | member_declaration_list T_RBRACE {
532                 if (sflag) {
533                         /* syntax req. ";" after last struct/union member */
534                         error(66);
535                 } else {
536                         /* syntax req. ";" after last struct/union member */
537                         warning(66);
538                 }
539                 $$ = $1;
540           }
541         | T_RBRACE {
542                 $$ = NULL;
543           }
544         ;
545
546 member_declaration_list:
547           member_declaration {
548                 $$ = $1;
549           }
550         | member_declaration_list T_SEMI member_declaration {
551                 $$ = lnklst($1, $3);
552           }
553         ;
554
555 member_declaration:
556           noclass_declmods deftyp {
557                 /* too late, i know, but getsym() compensates it */
558                 symtyp = FMOS;
559           } notype_member_decls {
560                 symtyp = FVFT;
561                 $$ = $4;
562           }
563         | noclass_declspecs deftyp {
564                 symtyp = FMOS;
565           } type_member_decls {
566                 symtyp = FVFT;
567                 $$ = $4;
568           }
569         | noclass_declmods deftyp {
570                 /* struct or union member must be named */
571                 warning(49);
572                 $$ = NULL;
573           }
574         | noclass_declspecs deftyp {
575                 /* struct or union member must be named */
576                 warning(49);
577                 $$ = NULL;
578           }
579         | error {
580                 symtyp = FVFT;
581                 $$ = NULL;
582           }
583         ;
584
585 noclass_declspecs:
586           clrtyp_typespec {
587                 addtype($1);
588           }
589         | noclass_declmods typespec {
590                 addtype($2);
591           }
592         | noclass_declspecs T_QUAL {
593                 addqual($2);
594           }
595         | noclass_declspecs notype_typespec {
596                 addtype($2);
597           }
598         ;
599
600 noclass_declmods:
601           clrtyp T_QUAL {
602                 addqual($2);
603           }
604         | noclass_declmods T_QUAL {
605                 addqual($2);
606           }
607         ;
608
609 notype_member_decls:
610           notype_member_decl {
611                 $$ = decl1str($1);
612           }
613         | notype_member_decls {
614                 symtyp = FMOS;
615           } T_COMMA type_member_decl {
616                 $$ = lnklst($1, decl1str($4));
617           }
618         ;
619
620 type_member_decls:
621           type_member_decl {
622                 $$ = decl1str($1);
623           }
624         | type_member_decls {
625                 symtyp = FMOS;
626           } T_COMMA type_member_decl {
627                 $$ = lnklst($1, decl1str($4));
628           }
629         ;
630
631 notype_member_decl:
632           notype_decl {
633                 $$ = $1;
634           }
635         | notype_decl T_COLON constant {
636                 $$ = bitfield($1, toicon($3));
637           }
638         | {
639                 symtyp = FVFT;
640           } T_COLON constant {
641                 $$ = bitfield(NULL, toicon($3));
642           }
643         ;
644
645 type_member_decl:
646           type_decl {
647                 $$ = $1;
648           }
649         | type_decl T_COLON constant {
650                 $$ = bitfield($1, toicon($3));
651           }
652         | {
653                 symtyp = FVFT;
654           } T_COLON constant {
655                 $$ = bitfield(NULL, toicon($3));
656           }
657         ;
658
659 enum_spec:
660           enum enum_tag {
661                 $$ = mktag($2, ENUM, 0, 0);
662           }
663         | enum enum_tag {
664                 dcs->d_tagtyp = mktag($2, ENUM, 1, 0);
665           } enum_declaration {
666                 $$ = compltag(dcs->d_tagtyp, $4);
667           }
668         | enum {
669                 dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0);
670           } enum_declaration {
671                 $$ = compltag(dcs->d_tagtyp, $3);
672           }
673         | enum error {
674                 symtyp = FVFT;
675                 $$ = gettyp(INT);
676           }
677         ;
678
679 enum:
680           T_ENUM {
681                 symtyp = FTAG;
682                 pushdecl(ENUMCON);
683           }
684         ;
685
686 enum_tag:
687           identifier {
688                 $$ = getsym($1);
689           }
690         ;
691
692 enum_declaration:
693           enum_decl_lbrace enums_with_opt_comma T_RBRACE {
694                 $$ = $2;
695           }
696         ;
697
698 enum_decl_lbrace:
699           T_LBRACE {
700                 symtyp = FVFT;
701                 enumval = 0;
702           }
703         ;
704
705 enums_with_opt_comma:
706           enums {
707                 $$ = $1;
708           }
709         | enums T_COMMA {
710                 if (sflag) {
711                         /* trailing "," prohibited in enum declaration */
712                         error(54);
713                 } else {
714                         /* trailing "," prohibited in enum declaration */
715                         warning(54);
716                 }
717                 $$ = $1;
718           }
719         ;
720
721 enums:
722           enumerator {
723                 $$ = $1;
724           }
725         | enums T_COMMA enumerator {
726                 $$ = lnklst($1, $3);
727           }
728         | error {
729                 $$ = NULL;
730           }
731         ;
732
733 enumerator:
734           ename {
735                 $$ = ename($1, enumval, 1);
736           }
737         | ename T_ASSIGN constant {
738                 $$ = ename($1, toicon($3), 0);
739           }
740         ;
741
742 ename:
743           identifier {
744                 $$ = getsym($1);
745           }
746         ;
747
748
749 notype_init_decls:
750           notype_init_decl
751         | notype_init_decls T_COMMA type_init_decl
752         ;
753
754 type_init_decls:
755           type_init_decl
756         | type_init_decls T_COMMA type_init_decl
757         ;
758
759 notype_init_decl:
760           notype_decl opt_asm_spec {
761                 idecl($1, 0);
762                 chksz($1);
763           }
764         | notype_decl opt_asm_spec {
765                 idecl($1, 1);
766           } T_ASSIGN initializer {
767                 chksz($1);
768           }
769         ;
770
771 type_init_decl:
772           type_decl opt_asm_spec {
773                 idecl($1, 0);
774                 chksz($1);
775           }
776         | type_decl opt_asm_spec {
777                 idecl($1, 1);
778           } T_ASSIGN initializer {
779                 chksz($1);
780           }
781         ;
782
783 notype_decl:
784           notype_direct_decl {
785                 $$ = $1;
786           }
787         | pointer notype_direct_decl {
788                 $$ = addptr($2, $1);
789           }
790         ;
791
792 notype_direct_decl:
793           T_NAME {
794                 $$ = dname(getsym($1));
795           }
796         | T_LPARN type_decl T_RPARN {
797                 $$ = $2;
798           }
799         | notype_direct_decl T_LBRACK T_RBRACK {
800                 $$ = addarray($1, 0, 0);
801           }
802         | notype_direct_decl T_LBRACK constant T_RBRACK {
803                 $$ = addarray($1, 1, toicon($3));
804           }
805         | notype_direct_decl param_list {
806                 $$ = addfunc($1, $2);
807                 popdecl();
808                 blklev--;
809           }
810         ;
811
812 type_decl:
813           type_direct_decl {
814                 $$ = $1;
815           }
816         | pointer type_direct_decl {
817                 $$ = addptr($2, $1);
818           }
819         ;
820
821 type_direct_decl:
822           identifier {
823                 $$ = dname(getsym($1));
824           }
825         | T_LPARN type_decl T_RPARN {
826                 $$ = $2;
827           }
828         | type_direct_decl T_LBRACK T_RBRACK {
829                 $$ = addarray($1, 0, 0);
830           }
831         | type_direct_decl T_LBRACK constant T_RBRACK {
832                 $$ = addarray($1, 1, toicon($3));
833           }
834         | type_direct_decl param_list {
835                 $$ = addfunc($1, $2);
836                 popdecl();
837                 blklev--;
838           }
839         ;
840
841 /*
842  * param_decl and notype_param_decl exist to avoid a conflict in
843  * argument lists. A typename enclosed in parens should always be
844  * treated as a typename, not an argument.
845  * "typedef int a; f(int (a));" is  "typedef int a; f(int foo(a));"
846  *                              not "typedef int a; f(int a);"
847  */
848 param_decl:
849           direct_param_decl {
850                 $$ = $1;
851           }
852         | pointer direct_param_decl {
853                 $$ = addptr($2, $1);
854           }
855         ;
856
857 direct_param_decl:
858           identifier {
859                 $$ = dname(getsym($1));
860           }
861         | T_LPARN notype_param_decl T_RPARN {
862                 $$ = $2;
863           }
864         | direct_param_decl T_LBRACK T_RBRACK {
865                 $$ = addarray($1, 0, 0);
866           }
867         | direct_param_decl T_LBRACK constant T_RBRACK {
868                 $$ = addarray($1, 1, toicon($3));
869           }
870         | direct_param_decl param_list {
871                 $$ = addfunc($1, $2);
872                 popdecl();
873                 blklev--;
874           }
875         ;
876
877 notype_param_decl:
878           direct_notype_param_decl {
879                 $$ = $1;
880           }
881         | pointer direct_notype_param_decl {
882                 $$ = addptr($2, $1);
883           }
884         ;
885
886 direct_notype_param_decl:
887           T_NAME {
888                 $$ = dname(getsym($1));
889           }
890         | T_LPARN notype_param_decl T_RPARN {
891                 $$ = $2;
892           }
893         | direct_notype_param_decl T_LBRACK T_RBRACK {
894                 $$ = addarray($1, 0, 0);
895           }
896         | direct_notype_param_decl T_LBRACK constant T_RBRACK {
897                 $$ = addarray($1, 1, toicon($3));
898           }
899         | direct_notype_param_decl param_list {
900                 $$ = addfunc($1, $2);
901                 popdecl();
902                 blklev--;
903           }
904         ;
905
906 pointer:
907           asterisk {
908                 $$ = $1;
909           }
910         | asterisk type_qualifier_list {
911                 $$ = mergepq($1, $2);
912           }
913         | asterisk pointer {
914                 $$ = mergepq($1, $2);
915           }
916         | asterisk type_qualifier_list pointer {
917                 $$ = mergepq(mergepq($1, $2), $3);
918           }
919         ;
920
921 asterisk:
922           T_MULT {
923                 $$ = xcalloc(1, sizeof (pqinf_t));
924                 $$->p_pcnt = 1;
925           }
926         ;
927
928 type_qualifier_list:
929           type_qualifier {
930                 $$ = $1;
931           }
932         | type_qualifier_list type_qualifier {
933                 $$ = mergepq($1, $2);
934           }
935         ;
936
937 type_qualifier:
938           T_QUAL {
939                 $$ = xcalloc(1, sizeof (pqinf_t));
940                 if ($1 == CONST) {
941                         $$->p_const = 1;
942                 } else {
943                         $$->p_volatile = 1;
944                 }
945           }
946         ;
947
948 param_list:
949           id_list_lparn identifier_list T_RPARN {
950                 $$ = $2;
951           }
952         | abs_decl_param_list {
953                 $$ = $1;
954           }
955         ;
956
957 id_list_lparn:
958           T_LPARN {
959                 blklev++;
960                 pushdecl(PARG);
961           }
962         ;
963
964 identifier_list:
965           T_NAME {
966                 $$ = iname(getsym($1));
967           }
968         | identifier_list T_COMMA T_NAME {
969                 $$ = lnklst($1, iname(getsym($3)));
970           }
971         | identifier_list error {
972                 $$ = $1;
973           }
974         ;
975
976 abs_decl_param_list:
977           abs_decl_lparn T_RPARN {
978                 $$ = NULL;
979           }
980         | abs_decl_lparn vararg_parameter_type_list T_RPARN {
981                 dcs->d_proto = 1;
982                 $$ = $2;
983           }
984         | abs_decl_lparn error T_RPARN {
985                 $$ = NULL;
986           }
987         ;
988
989 abs_decl_lparn:
990           T_LPARN {
991                 blklev++;
992                 pushdecl(PARG);
993           }
994         ;
995
996 vararg_parameter_type_list:
997           parameter_type_list {
998                 $$ = $1;
999           }
1000         | parameter_type_list T_COMMA T_ELLIPSE {
1001                 dcs->d_vararg = 1;
1002                 $$ = $1;
1003           }
1004         | T_ELLIPSE {
1005                 if (sflag) {
1006                         /* ANSI C requires formal parameter before "..." */
1007                         error(84);
1008                 } else if (!tflag) {
1009                         /* ANSI C requires formal parameter before "..." */
1010                         warning(84);
1011                 }
1012                 dcs->d_vararg = 1;
1013                 $$ = NULL;
1014           }
1015         ;
1016
1017 parameter_type_list:
1018           parameter_declaration opt_asm_spec {
1019                 $$ = $1;
1020           }
1021         | parameter_type_list T_COMMA parameter_declaration opt_asm_spec {
1022                 $$ = lnklst($1, $3);
1023           }
1024         ;
1025
1026 parameter_declaration:
1027           declmods deftyp {
1028                 $$ = decl1arg(aname(), 0);
1029           }
1030         | declspecs deftyp {
1031                 $$ = decl1arg(aname(), 0);
1032           }
1033         | declmods deftyp notype_param_decl {
1034                 $$ = decl1arg($3, 0);
1035           }
1036         /*
1037          * param_decl is needed because of following conflict:
1038          * "typedef int a; f(int (a));" could be parsed as
1039          * "function with argument a of type int", or
1040          * "function with an abstract argument of type function".
1041          * This grammar realizes the second case.
1042          */
1043         | declspecs deftyp param_decl {
1044                 $$ = decl1arg($3, 0);
1045           }
1046         | declmods deftyp abs_decl {
1047                 $$ = decl1arg($3, 0);
1048           }
1049         | declspecs deftyp abs_decl {
1050                 $$ = decl1arg($3, 0);
1051           }
1052         ;
1053
1054 opt_asm_spec:
1055           /* empty */
1056         | T_ASM T_LPARN T_STRING T_RPARN {
1057                 freeyyv(&$3, T_STRING);
1058           }
1059         ;
1060
1061 initializer:
1062           init_expr
1063         ;
1064
1065 init_expr:
1066           expr                          %prec T_COMMA {
1067                 mkinit($1);
1068           }
1069         | init_lbrace init_expr_list init_rbrace
1070         | init_lbrace init_expr_list T_COMMA init_rbrace
1071         | error
1072         ;
1073
1074 init_expr_list:
1075           init_expr                     %prec T_COMMA
1076         | init_expr_list T_COMMA init_expr
1077         ;
1078
1079 init_lbrace:
1080           T_LBRACE {
1081                 initlbr();
1082           }
1083         ;
1084
1085 init_rbrace:
1086           T_RBRACE {
1087                 initrbr();
1088           }
1089         ;
1090
1091 type_name:
1092           {
1093                 pushdecl(ABSTRACT);
1094           } abstract_declaration {
1095                 popdecl();
1096                 $$ = $2->s_type;
1097           }
1098         ;
1099
1100 abstract_declaration:
1101           noclass_declmods deftyp {
1102                 $$ = decl1abs(aname());
1103           }
1104         | noclass_declspecs deftyp {
1105                 $$ = decl1abs(aname());
1106           }
1107         | noclass_declmods deftyp abs_decl {
1108                 $$ = decl1abs($3);
1109           }
1110         | noclass_declspecs deftyp abs_decl {
1111                 $$ = decl1abs($3);
1112           }
1113         ;
1114
1115 abs_decl:
1116           pointer {
1117                 $$ = addptr(aname(), $1);
1118           }
1119         | direct_abs_decl {
1120                 $$ = $1;
1121           }
1122         | pointer direct_abs_decl {
1123                 $$ = addptr($2, $1);
1124           }
1125         ;
1126
1127 direct_abs_decl:
1128           T_LPARN abs_decl T_RPARN {
1129                 $$ = $2;
1130           }
1131         | T_LBRACK T_RBRACK {
1132                 $$ = addarray(aname(), 0, 0);
1133           }
1134         | T_LBRACK constant T_RBRACK {
1135                 $$ = addarray(aname(), 1, toicon($2));
1136           }
1137         | direct_abs_decl T_LBRACK T_RBRACK {
1138                 $$ = addarray($1, 0, 0);
1139           }
1140         | direct_abs_decl T_LBRACK constant T_RBRACK {
1141                 $$ = addarray($1, 1, toicon($3));
1142           }
1143         | abs_decl_param_list {
1144                 $$ = addfunc(aname(), $1);
1145                 popdecl();
1146                 blklev--;
1147           }
1148         | direct_abs_decl abs_decl_param_list {
1149                 $$ = addfunc($1, $2);
1150                 popdecl();
1151                 blklev--;
1152           }
1153         ;
1154
1155 stmnt:
1156           labeled_stmnt
1157         | expr_stmnt
1158         | comp_stmnt
1159         | selection_stmnt
1160         | iteration_stmnt
1161         | jump_stmnt {
1162                 ftflg = 0;
1163           }
1164         | asm_stmnt
1165         ;
1166
1167 labeled_stmnt:
1168           label stmnt
1169         ;
1170
1171 label:
1172           identifier T_COLON {
1173                 symtyp = FLAB;
1174                 label(T_NAME, getsym($1), NULL);
1175           }
1176         | T_CASE constant T_COLON {
1177                 label(T_CASE, NULL, $2);
1178                 ftflg = 1;
1179           }
1180         | T_DEFAULT T_COLON {
1181                 label(T_DEFAULT, NULL, NULL);
1182                 ftflg = 1;
1183           }
1184         ;
1185
1186 comp_stmnt:
1187           compstmnt_lbrace declaration_list opt_stmnt_list compstmnt_rbrace
1188         | compstmnt_lbrace opt_stmnt_list compstmnt_rbrace
1189         ;
1190
1191 compstmnt_lbrace:
1192           T_LBRACE {
1193                 blklev++;
1194                 mblklev++;
1195                 pushdecl(AUTO);
1196           }
1197         ;
1198
1199 compstmnt_rbrace:
1200           T_RBRACE {
1201                 popdecl();
1202                 freeblk();
1203                 mblklev--;
1204                 blklev--;
1205                 ftflg = 0;
1206           }
1207         ;
1208
1209 opt_stmnt_list:
1210           /* empty */
1211         | stmnt_list
1212         ;
1213
1214 stmnt_list:
1215           stmnt {
1216                 clrwflgs();
1217           }
1218         | stmnt_list stmnt {
1219                 clrwflgs();
1220           }
1221         | stmnt_list error T_SEMI {
1222                 clrwflgs();
1223           }
1224         ;
1225
1226 expr_stmnt:
1227           expr T_SEMI {
1228                 expr($1, 0, 0);
1229                 ftflg = 0;
1230           }
1231         | T_SEMI {
1232                 ftflg = 0;
1233           }
1234         ;
1235
1236 selection_stmnt:
1237           if_without_else {
1238                 if2();
1239                 if3(0);
1240           }
1241         | if_without_else T_ELSE {
1242                 if2();
1243           } stmnt {
1244                 if3(1);
1245           }
1246         | if_without_else T_ELSE error {
1247                 if3(0);
1248           }
1249         | switch_expr stmnt {
1250                 switch2();
1251           }
1252         | switch_expr error {
1253                 switch2();
1254           }
1255         ;
1256
1257 if_without_else:
1258           if_expr stmnt
1259         | if_expr error
1260         ;
1261
1262 if_expr:
1263           T_IF T_LPARN expr T_RPARN {
1264                 if1($3);
1265                 clrwflgs();
1266           }
1267         ;
1268
1269 switch_expr:
1270           T_SWITCH T_LPARN expr T_RPARN {
1271                 switch1($3);
1272                 clrwflgs();
1273           }
1274         ;
1275
1276 iteration_stmnt:
1277           while_expr stmnt {
1278                 while2();
1279           }
1280         | while_expr error {
1281                 while2();
1282           }
1283         | do stmnt do_while_expr {
1284                 do2($3);
1285                 ftflg = 0;
1286           }
1287         | do error {
1288                 do2(NULL);
1289           }
1290         | for_exprs stmnt {
1291                 for2();
1292           }
1293         | for_exprs error {
1294                 for2();
1295           }
1296         ;
1297
1298 while_expr:
1299           T_WHILE T_LPARN expr T_RPARN {
1300                 while1($3);
1301                 clrwflgs();
1302           }
1303         ;
1304
1305 do:
1306           T_DO {
1307                 do1();
1308           }
1309         ;
1310
1311 do_while_expr:
1312           T_WHILE T_LPARN expr T_RPARN T_SEMI {
1313                 $$ = $3;
1314           }
1315         ;
1316
1317 for_exprs:
1318           T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
1319                 for1($3, $5, $7);
1320                 clrwflgs();
1321           }
1322         ;
1323
1324 opt_expr:
1325           /* empty */ {
1326                 $$ = NULL;
1327           }
1328         | expr {
1329                 $$ = $1;
1330           }
1331         ;
1332
1333 jump_stmnt:
1334           goto identifier T_SEMI {
1335                 dogoto(getsym($2));
1336           }
1337         | goto error T_SEMI {
1338                 symtyp = FVFT;
1339           }
1340         | T_CONTINUE T_SEMI {
1341                 docont();
1342           }
1343         | T_BREAK T_SEMI {
1344                 dobreak();
1345           }
1346         | T_RETURN T_SEMI {
1347                 doreturn(NULL);
1348           }
1349         | T_RETURN expr T_SEMI {
1350                 doreturn($2);
1351           }
1352         ;
1353
1354 goto:
1355           T_GOTO {
1356                 symtyp = FLAB;
1357           }
1358         ;
1359
1360 asm_stmnt:
1361           T_ASM T_LPARN read_until_rparn T_SEMI {
1362                 setasm();
1363           }
1364         | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI {
1365                 setasm();
1366           }
1367         | T_ASM error
1368         ;
1369
1370 read_until_rparn:
1371           /* empty */ {
1372                 ignuptorp();
1373           }
1374         ;
1375
1376 declaration_list:
1377           declaration {
1378                 clrwflgs();
1379           }
1380         | declaration_list declaration {
1381                 clrwflgs();
1382           }
1383         ;
1384
1385 constant:
1386           expr                          %prec T_COMMA {
1387                   $$ = $1;
1388           }
1389         ;
1390
1391 expr:
1392           expr T_MULT expr {
1393                 $$ = build(MULT, $1, $3);
1394           }
1395         | expr T_DIVOP expr {
1396                 $$ = build($2, $1, $3);
1397           }
1398         | expr T_ADDOP expr {
1399                 $$ = build($2, $1, $3);
1400           }
1401         | expr T_SHFTOP expr {
1402                 $$ = build($2, $1, $3);
1403           }
1404         | expr T_RELOP expr {
1405                 $$ = build($2, $1, $3);
1406           }
1407         | expr T_EQOP expr {
1408                 $$ = build($2, $1, $3);
1409           }
1410         | expr T_AND expr {
1411                 $$ = build(AND, $1, $3);
1412           }
1413         | expr T_XOR expr {
1414                 $$ = build(XOR, $1, $3);
1415           }
1416         | expr T_OR expr {
1417                 $$ = build(OR, $1, $3);
1418           }
1419         | expr T_LOGAND expr {
1420                 $$ = build(LOGAND, $1, $3);
1421           }
1422         | expr T_LOGOR expr {
1423                 $$ = build(LOGOR, $1, $3);
1424           }
1425         | expr T_QUEST expr T_COLON expr {
1426                 $$ = build(QUEST, $1, build(COLON, $3, $5));
1427           }
1428         | expr T_ASSIGN expr {
1429                 $$ = build(ASSIGN, $1, $3);
1430           }
1431         | expr T_OPASS expr {
1432                 $$ = build($2, $1, $3);
1433           }
1434         | expr T_COMMA expr {
1435                 $$ = build(COMMA, $1, $3);
1436           }
1437         | term {
1438                 $$ = $1;
1439           }
1440         ;
1441
1442 term:
1443           T_NAME {
1444                 /* XXX realy neccessary? */
1445                 if (yychar < 0)
1446                         yychar = yylex();
1447                 $$ = getnnode(getsym($1), yychar);
1448           }
1449         | string {
1450                 $$ = getsnode($1);
1451           }
1452         | T_CON {
1453                 $$ = getcnode(gettyp($1->v_tspec), $1);
1454           }
1455         | T_LPARN expr T_RPARN {
1456                 if ($2 != NULL)
1457                         $2->tn_parn = 1;
1458                 $$ = $2;
1459           }
1460         | term T_INCDEC {
1461                 $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
1462           }
1463         | T_INCDEC term {
1464                 $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
1465           }
1466         | T_MULT term {
1467                 $$ = build(STAR, $2, NULL);
1468           }
1469         | T_AND term {
1470                 $$ = build(AMPER, $2, NULL);
1471           }
1472         | T_UNOP term {
1473                 $$ = build($1, $2, NULL);
1474           }
1475         | T_ADDOP term {
1476                 if (tflag && $1 == PLUS) {
1477                         /* unary + is illegal in traditional C */
1478                         warning(100);
1479                 }
1480                 $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
1481           }
1482         | term T_LBRACK expr T_RBRACK {
1483                 $$ = build(STAR, build(PLUS, $1, $3), NULL);
1484           }
1485         | term T_LPARN T_RPARN {
1486                 $$ = funccall($1, NULL);
1487           }
1488         | term T_LPARN func_arg_list T_RPARN {
1489                 $$ = funccall($1, $3);
1490           }
1491         | term point_or_arrow T_NAME {
1492                 if ($1 != NULL) {
1493                         sym_t   *msym;
1494                         /* XXX strmemb should be integrated in build() */
1495                         if ($2 == ARROW) {
1496                                 /* must to this before strmemb is called */
1497                                 $1 = cconv($1);
1498                         }
1499                         msym = strmemb($1, $2, getsym($3));
1500                         $$ = build($2, $1, getnnode(msym, 0));
1501                 } else {
1502                         $$ = NULL;
1503                 }
1504           }
1505         | T_SIZEOF term                                 %prec T_SIZEOF {
1506                 if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
1507                         chkmisc($2, 0, 0, 0, 0, 0, 1);
1508           }
1509         | T_SIZEOF T_LPARN type_name T_RPARN            %prec T_SIZEOF {
1510                 $$ = bldszof($3);
1511           }
1512         | T_LPARN type_name T_RPARN term                %prec T_UNOP {
1513                 $$ = cast($4, $2);
1514           }
1515         ;
1516
1517 string:
1518           T_STRING {
1519                 $$ = $1;
1520           }
1521         | T_STRING string2 {
1522                 $$ = catstrg($1, $2);
1523           }
1524         ;
1525
1526 string2:
1527          T_STRING {
1528                 if (tflag) {
1529                         /* concatenated strings are illegal in traditional C */
1530                         warning(219);
1531                 }
1532                 $$ = $1;
1533           }
1534         | string2 T_STRING {
1535                 $$ = catstrg($1, $2);
1536           }
1537         ;
1538
1539 func_arg_list:
1540           expr                                          %prec T_COMMA {
1541                 $$ = funcarg(NULL, $1);
1542           }
1543         | func_arg_list T_COMMA expr {
1544                 $$ = funcarg($1, $3);
1545           }
1546         ;
1547
1548 point_or_arrow:
1549           T_STROP {
1550                 symtyp = FMOS;
1551                 $$ = $1;
1552           }
1553         ;
1554
1555 identifier:
1556           T_NAME {
1557                 $$ = $1;
1558           }
1559         | T_TYPENAME {
1560                 $$ = $1;
1561           }
1562         ;
1563
1564 %%
1565
1566 /* ARGSUSED */
1567 int
1568 yyerror(msg)
1569         char    *msg;
1570 {
1571         error(249);
1572         if (++sytxerr >= 5)
1573                 norecover();
1574         return (0);
1575 }
1576
1577 /*
1578  * Gets a node for a constant and returns the value of this constant
1579  * as integer.
1580  * Is the node not constant or too large for int or of type float,
1581  * a warning will be printed.
1582  *
1583  * toicon() should be used only inside declarations. If it is used in
1584  * expressions, it frees the memory used for the expression.
1585  */
1586 static int
1587 toicon(tn)
1588         tnode_t *tn;
1589 {
1590         int     i;
1591         tspec_t t;
1592         val_t   *v;
1593
1594         v = constant(tn);
1595
1596         /*
1597          * Abstract declarations are used inside expression. To free
1598          * the memory would be a fatal error.
1599          */
1600         if (dcs->d_ctx != ABSTRACT)
1601                 tfreeblk();
1602
1603         if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
1604                 i = (int)v->v_ldbl;
1605                 /* integral constant expression expected */
1606                 error(55);
1607         } else {
1608                 i = (int)v->v_quad;
1609                 if (isutyp(t)) {
1610                         if ((u_quad_t)v->v_quad > INT_MAX) {
1611                                 /* integral constant too large */
1612                                 warning(56);
1613                         }
1614                 } else {
1615 #ifdef XXX_BROKEN_GCC
1616                         if (v->v_quad > INT_MAX) {
1617                                 /* integral constant too large */
1618                                 warning(56);
1619                         }
1620                         else if (v->v_quad < INT_MIN) {
1621                                 /* integral constant too large */
1622                                 warning(56);
1623                         }
1624 #else
1625                         if (v->v_quad > INT_MAX || v->v_quad < INT_MIN) {
1626                                 /* integral constant too large */
1627                                 warning(56);
1628                         }
1629 #endif
1630                 }
1631         }
1632         free(v);
1633         return (i);
1634 }
1635
1636 static void
1637 idecl(decl, initflg)
1638         sym_t   *decl;
1639         int     initflg;
1640 {
1641         initerr = 0;
1642         initsym = decl;
1643
1644         switch (dcs->d_ctx) {
1645         case EXTERN:
1646                 decl1ext(decl, initflg);
1647                 break;
1648         case ARG:
1649                 (void)decl1arg(decl, initflg);
1650                 break;
1651         case AUTO:
1652                 decl1loc(decl, initflg);
1653                 break;
1654         default:
1655                 lerror("idecl()");
1656         }
1657
1658         if (initflg && !initerr)
1659                 prepinit();
1660 }
1661
1662 /*
1663  * Discard all input tokens up to and including the next
1664  * unmatched right paren
1665  */
1666 void
1667 ignuptorp()
1668 {
1669         int     level;
1670
1671         if (yychar < 0)
1672                 yychar = yylex();
1673         freeyyv(&yylval, yychar);
1674
1675         level = 1;
1676         while (yychar != T_RPARN || --level > 0) {
1677                 if (yychar == T_LPARN) {
1678                         level++;
1679                 } else if (yychar <= 0) {
1680                         break;
1681                 }
1682                 freeyyv(&yylval, yychar = yylex());
1683         }
1684
1685         yyclearin;
1686 }