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