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