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