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