Annotation of src/usr.bin/xlint/lint1/cgram.y, Revision 1.24
1.2 cgd 1: %{
1.24 ! thorpej 2: /* $NetBSD: cgram.y,v 1.23 2002/01/31 19:36:53 tv 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.24 ! thorpej 38: __RCSID("$NetBSD: cgram.y,v 1.23 2002/01/31 19:36:53 tv 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.20 lukem 67: static int toicon(tnode_t *);
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 {
684: $$ = bitfield($1, toicon($3));
685: }
686: | {
687: symtyp = FVFT;
688: } T_COLON constant {
689: $$ = bitfield(NULL, toicon($3));
690: }
691: ;
692:
693: type_member_decl:
694: type_decl {
695: $$ = $1;
696: }
697: | type_decl T_COLON constant {
698: $$ = bitfield($1, toicon($3));
699: }
700: | {
701: symtyp = FVFT;
702: } T_COLON constant {
703: $$ = bitfield(NULL, toicon($3));
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 {
786: $$ = ename($1, toicon($3), 0);
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 {
851: $$ = addarray($1, 1, toicon($3));
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 {
880: $$ = addarray($1, 1, toicon($3));
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 {
916: $$ = addarray($1, 1, toicon($3));
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 {
945: $$ = addarray($1, 1, toicon($3));
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: }
1123: | init_lbrace init_expr_list init_rbrace
1124: | init_lbrace init_expr_list T_COMMA init_rbrace
1125: | error
1126: ;
1127:
1128: init_expr_list:
1129: init_expr %prec T_COMMA
1130: | init_expr_list T_COMMA init_expr
1131: ;
1132:
1133: init_lbrace:
1134: T_LBRACE {
1135: initlbr();
1136: }
1137: ;
1138:
1139: init_rbrace:
1140: T_RBRACE {
1141: initrbr();
1142: }
1143: ;
1144:
1145: type_name:
1146: {
1147: pushdecl(ABSTRACT);
1148: } abstract_declaration {
1149: popdecl();
1150: $$ = $2->s_type;
1151: }
1152: ;
1153:
1154: abstract_declaration:
1155: noclass_declmods deftyp {
1156: $$ = decl1abs(aname());
1157: }
1158: | noclass_declspecs deftyp {
1159: $$ = decl1abs(aname());
1160: }
1161: | noclass_declmods deftyp abs_decl {
1162: $$ = decl1abs($3);
1163: }
1164: | noclass_declspecs deftyp abs_decl {
1165: $$ = decl1abs($3);
1166: }
1167: ;
1168:
1169: abs_decl:
1170: pointer {
1171: $$ = addptr(aname(), $1);
1172: }
1173: | direct_abs_decl {
1174: $$ = $1;
1175: }
1176: | pointer direct_abs_decl {
1177: $$ = addptr($2, $1);
1178: }
1179: ;
1180:
1181: direct_abs_decl:
1182: T_LPARN abs_decl T_RPARN {
1183: $$ = $2;
1184: }
1185: | T_LBRACK T_RBRACK {
1186: $$ = addarray(aname(), 0, 0);
1187: }
1188: | T_LBRACK constant T_RBRACK {
1189: $$ = addarray(aname(), 1, toicon($2));
1190: }
1191: | direct_abs_decl T_LBRACK T_RBRACK {
1192: $$ = addarray($1, 0, 0);
1193: }
1194: | direct_abs_decl T_LBRACK constant T_RBRACK {
1195: $$ = addarray($1, 1, toicon($3));
1196: }
1197: | abs_decl_param_list {
1198: $$ = addfunc(aname(), $1);
1199: popdecl();
1200: blklev--;
1201: }
1202: | direct_abs_decl abs_decl_param_list {
1203: $$ = addfunc($1, $2);
1204: popdecl();
1205: blklev--;
1206: }
1207: ;
1208:
1209: stmnt:
1210: labeled_stmnt
1211: | expr_stmnt
1212: | comp_stmnt
1213: | selection_stmnt
1214: | iteration_stmnt
1215: | jump_stmnt {
1216: ftflg = 0;
1217: }
1.6 jpo 1218: | asm_stmnt
1.1 cgd 1219: ;
1220:
1221: labeled_stmnt:
1222: label stmnt
1223: ;
1224:
1225: label:
1226: identifier T_COLON {
1227: symtyp = FLAB;
1228: label(T_NAME, getsym($1), NULL);
1229: }
1230: | T_CASE constant T_COLON {
1231: label(T_CASE, NULL, $2);
1232: ftflg = 1;
1233: }
1234: | T_DEFAULT T_COLON {
1235: label(T_DEFAULT, NULL, NULL);
1236: ftflg = 1;
1237: }
1238: ;
1239:
1240: comp_stmnt:
1241: compstmnt_lbrace declaration_list opt_stmnt_list compstmnt_rbrace
1242: | compstmnt_lbrace opt_stmnt_list compstmnt_rbrace
1243: ;
1244:
1245: compstmnt_lbrace:
1246: T_LBRACE {
1247: blklev++;
1248: mblklev++;
1249: pushdecl(AUTO);
1250: }
1251: ;
1252:
1253: compstmnt_rbrace:
1254: T_RBRACE {
1255: popdecl();
1256: freeblk();
1257: mblklev--;
1258: blklev--;
1259: ftflg = 0;
1260: }
1261: ;
1262:
1263: opt_stmnt_list:
1264: /* empty */
1265: | stmnt_list
1266: ;
1267:
1268: stmnt_list:
1.14 christos 1269: stmnt
1.7 jpo 1270: | stmnt_list stmnt {
1.15 christos 1271: RESTORE();
1.7 jpo 1272: }
1.15 christos 1273: | stmnt_list error T_SEMI
1.1 cgd 1274: ;
1275:
1276: expr_stmnt:
1277: expr T_SEMI {
1278: expr($1, 0, 0);
1279: ftflg = 0;
1280: }
1281: | T_SEMI {
1282: ftflg = 0;
1283: }
1284: ;
1285:
1286: selection_stmnt:
1287: if_without_else {
1.15 christos 1288: SAVE();
1.1 cgd 1289: if2();
1290: if3(0);
1291: }
1292: | if_without_else T_ELSE {
1.15 christos 1293: SAVE();
1.1 cgd 1294: if2();
1295: } stmnt {
1.15 christos 1296: CLRWFLGS();
1.1 cgd 1297: if3(1);
1298: }
1299: | if_without_else T_ELSE error {
1.15 christos 1300: CLRWFLGS();
1.1 cgd 1301: if3(0);
1302: }
1303: | switch_expr stmnt {
1.15 christos 1304: CLRWFLGS();
1.1 cgd 1305: switch2();
1306: }
1307: | switch_expr error {
1.15 christos 1308: CLRWFLGS();
1.1 cgd 1309: switch2();
1310: }
1311: ;
1312:
1313: if_without_else:
1314: if_expr stmnt
1315: | if_expr error
1316: ;
1317:
1318: if_expr:
1319: T_IF T_LPARN expr T_RPARN {
1320: if1($3);
1.15 christos 1321: CLRWFLGS();
1.1 cgd 1322: }
1323: ;
1324:
1325: switch_expr:
1326: T_SWITCH T_LPARN expr T_RPARN {
1327: switch1($3);
1.15 christos 1328: CLRWFLGS();
1.1 cgd 1329: }
1330: ;
1331:
1.14 christos 1332: do_stmnt:
1333: do stmnt {
1.15 christos 1334: CLRWFLGS();
1.14 christos 1335: }
1336: ;
1337:
1.1 cgd 1338: iteration_stmnt:
1339: while_expr stmnt {
1.15 christos 1340: CLRWFLGS();
1.1 cgd 1341: while2();
1342: }
1343: | while_expr error {
1.15 christos 1344: CLRWFLGS();
1.1 cgd 1345: while2();
1346: }
1.14 christos 1347: | do_stmnt do_while_expr {
1348: do2($2);
1.1 cgd 1349: ftflg = 0;
1350: }
1351: | do error {
1.15 christos 1352: CLRWFLGS();
1.1 cgd 1353: do2(NULL);
1354: }
1355: | for_exprs stmnt {
1.15 christos 1356: CLRWFLGS();
1.1 cgd 1357: for2();
1358: }
1359: | for_exprs error {
1.15 christos 1360: CLRWFLGS();
1.1 cgd 1361: for2();
1362: }
1363: ;
1364:
1365: while_expr:
1366: T_WHILE T_LPARN expr T_RPARN {
1367: while1($3);
1.15 christos 1368: CLRWFLGS();
1.1 cgd 1369: }
1370: ;
1371:
1372: do:
1373: T_DO {
1374: do1();
1375: }
1376: ;
1377:
1378: do_while_expr:
1379: T_WHILE T_LPARN expr T_RPARN T_SEMI {
1380: $$ = $3;
1381: }
1382: ;
1383:
1384: for_exprs:
1385: T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
1386: for1($3, $5, $7);
1.15 christos 1387: CLRWFLGS();
1.1 cgd 1388: }
1389: ;
1390:
1391: opt_expr:
1392: /* empty */ {
1393: $$ = NULL;
1394: }
1395: | expr {
1396: $$ = $1;
1397: }
1398: ;
1399:
1400: jump_stmnt:
1401: goto identifier T_SEMI {
1402: dogoto(getsym($2));
1403: }
1404: | goto error T_SEMI {
1405: symtyp = FVFT;
1406: }
1407: | T_CONTINUE T_SEMI {
1408: docont();
1409: }
1410: | T_BREAK T_SEMI {
1411: dobreak();
1412: }
1413: | T_RETURN T_SEMI {
1414: doreturn(NULL);
1415: }
1416: | T_RETURN expr T_SEMI {
1417: doreturn($2);
1418: }
1419: ;
1420:
1421: goto:
1422: T_GOTO {
1423: symtyp = FLAB;
1424: }
1425: ;
1426:
1.6 jpo 1427: asm_stmnt:
1.8 jpo 1428: T_ASM T_LPARN read_until_rparn T_SEMI {
1429: setasm();
1430: }
1431: | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI {
1432: setasm();
1433: }
1434: | T_ASM error
1.6 jpo 1435: ;
1436:
1437: read_until_rparn:
1438: /* empty */ {
1439: ignuptorp();
1440: }
1441: ;
1442:
1.1 cgd 1443: declaration_list:
1.7 jpo 1444: declaration {
1.15 christos 1445: CLRWFLGS();
1.7 jpo 1446: }
1447: | declaration_list declaration {
1.15 christos 1448: CLRWFLGS();
1.7 jpo 1449: }
1.1 cgd 1450: ;
1451:
1452: constant:
1453: expr %prec T_COMMA {
1454: $$ = $1;
1455: }
1456: ;
1457:
1458: expr:
1459: expr T_MULT expr {
1460: $$ = build(MULT, $1, $3);
1461: }
1462: | expr T_DIVOP expr {
1463: $$ = build($2, $1, $3);
1464: }
1465: | expr T_ADDOP expr {
1466: $$ = build($2, $1, $3);
1467: }
1468: | expr T_SHFTOP expr {
1469: $$ = build($2, $1, $3);
1470: }
1471: | expr T_RELOP expr {
1472: $$ = build($2, $1, $3);
1473: }
1474: | expr T_EQOP expr {
1475: $$ = build($2, $1, $3);
1476: }
1477: | expr T_AND expr {
1478: $$ = build(AND, $1, $3);
1479: }
1480: | expr T_XOR expr {
1481: $$ = build(XOR, $1, $3);
1482: }
1483: | expr T_OR expr {
1484: $$ = build(OR, $1, $3);
1485: }
1486: | expr T_LOGAND expr {
1487: $$ = build(LOGAND, $1, $3);
1488: }
1489: | expr T_LOGOR expr {
1490: $$ = build(LOGOR, $1, $3);
1491: }
1492: | expr T_QUEST expr T_COLON expr {
1493: $$ = build(QUEST, $1, build(COLON, $3, $5));
1494: }
1495: | expr T_ASSIGN expr {
1496: $$ = build(ASSIGN, $1, $3);
1497: }
1498: | expr T_OPASS expr {
1499: $$ = build($2, $1, $3);
1500: }
1501: | expr T_COMMA expr {
1502: $$ = build(COMMA, $1, $3);
1503: }
1504: | term {
1505: $$ = $1;
1506: }
1507: ;
1508:
1509: term:
1510: T_NAME {
1.21 wiz 1511: /* XXX really necessary? */
1.1 cgd 1512: if (yychar < 0)
1513: yychar = yylex();
1514: $$ = getnnode(getsym($1), yychar);
1515: }
1516: | string {
1517: $$ = getsnode($1);
1518: }
1519: | T_CON {
1520: $$ = getcnode(gettyp($1->v_tspec), $1);
1521: }
1522: | T_LPARN expr T_RPARN {
1523: if ($2 != NULL)
1524: $2->tn_parn = 1;
1525: $$ = $2;
1526: }
1527: | term T_INCDEC {
1528: $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
1529: }
1530: | T_INCDEC term {
1531: $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
1532: }
1533: | T_MULT term {
1534: $$ = build(STAR, $2, NULL);
1535: }
1536: | T_AND term {
1537: $$ = build(AMPER, $2, NULL);
1538: }
1539: | T_UNOP term {
1540: $$ = build($1, $2, NULL);
1541: }
1542: | T_ADDOP term {
1543: if (tflag && $1 == PLUS) {
1544: /* unary + is illegal in traditional C */
1545: warning(100);
1546: }
1547: $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
1548: }
1549: | term T_LBRACK expr T_RBRACK {
1550: $$ = build(STAR, build(PLUS, $1, $3), NULL);
1551: }
1552: | term T_LPARN T_RPARN {
1553: $$ = funccall($1, NULL);
1554: }
1555: | term T_LPARN func_arg_list T_RPARN {
1556: $$ = funccall($1, $3);
1557: }
1558: | term point_or_arrow T_NAME {
1559: if ($1 != NULL) {
1560: sym_t *msym;
1561: /* XXX strmemb should be integrated in build() */
1562: if ($2 == ARROW) {
1563: /* must to this before strmemb is called */
1564: $1 = cconv($1);
1565: }
1566: msym = strmemb($1, $2, getsym($3));
1567: $$ = build($2, $1, getnnode(msym, 0));
1568: } else {
1569: $$ = NULL;
1570: }
1571: }
1572: | T_SIZEOF term %prec T_SIZEOF {
1573: if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
1574: chkmisc($2, 0, 0, 0, 0, 0, 1);
1575: }
1576: | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF {
1577: $$ = bldszof($3);
1578: }
1579: | T_LPARN type_name T_RPARN term %prec T_UNOP {
1580: $$ = cast($4, $2);
1581: }
1582: ;
1583:
1584: string:
1585: T_STRING {
1586: $$ = $1;
1587: }
1588: | T_STRING string2 {
1589: $$ = catstrg($1, $2);
1590: }
1591: ;
1592:
1593: string2:
1594: T_STRING {
1595: if (tflag) {
1596: /* concatenated strings are illegal in traditional C */
1597: warning(219);
1598: }
1599: $$ = $1;
1600: }
1601: | string2 T_STRING {
1602: $$ = catstrg($1, $2);
1603: }
1604: ;
1605:
1606: func_arg_list:
1607: expr %prec T_COMMA {
1608: $$ = funcarg(NULL, $1);
1609: }
1610: | func_arg_list T_COMMA expr {
1611: $$ = funcarg($1, $3);
1612: }
1613: ;
1614:
1615: point_or_arrow:
1616: T_STROP {
1617: symtyp = FMOS;
1618: $$ = $1;
1619: }
1620: ;
1621:
1622: identifier:
1623: T_NAME {
1624: $$ = $1;
1625: }
1626: | T_TYPENAME {
1627: $$ = $1;
1628: }
1629: ;
1630:
1631: %%
1632:
1633: /* ARGSUSED */
1634: int
1.20 lukem 1635: yyerror(char *msg)
1.1 cgd 1636: {
1.20 lukem 1637:
1.1 cgd 1638: error(249);
1639: if (++sytxerr >= 5)
1640: norecover();
1641: return (0);
1642: }
1643:
1.24 ! thorpej 1644: static inline int uq_gt(uint64_t, uint64_t);
! 1645: static inline int q_gt(int64_t, int64_t);
1.10 mycroft 1646:
1647: static inline int
1.24 ! thorpej 1648: uq_gt(uint64_t a, uint64_t b)
1.10 mycroft 1649: {
1650:
1651: return (a > b);
1652: }
1653:
1654: static inline int
1.24 ! thorpej 1655: q_gt(int64_t a, int64_t b)
1.10 mycroft 1656: {
1657:
1658: return (a > b);
1659: }
1660:
1661: #define q_lt(a, b) q_gt(b, a)
1662:
1.1 cgd 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
1.20 lukem 1673: toicon(tnode_t *tn)
1.1 cgd 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: */
1.3 jpo 1685: if (dcs->d_ctx != ABSTRACT)
1.1 cgd 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)) {
1.24 ! thorpej 1695: if (uq_gt((uint64_t)v->v_quad,
! 1696: (uint64_t)INT_MAX)) {
1.1 cgd 1697: /* integral constant too large */
1698: warning(56);
1699: }
1700: } else {
1.24 ! thorpej 1701: if (q_gt(v->v_quad, (int64_t)INT_MAX) ||
! 1702: q_lt(v->v_quad, (int64_t)INT_MIN)) {
1.1 cgd 1703: /* integral constant too large */
1704: warning(56);
1705: }
1706: }
1707: }
1708: free(v);
1709: return (i);
1710: }
1711:
1712: static void
1.20 lukem 1713: idecl(sym_t *decl, int initflg, sbuf_t *rename)
1.1 cgd 1714: {
1.11 cgd 1715: char *s;
1716:
1.1 cgd 1717: initerr = 0;
1718: initsym = decl;
1719:
1.3 jpo 1720: switch (dcs->d_ctx) {
1.1 cgd 1721: case EXTERN:
1.11 cgd 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: }
1.1 cgd 1731: decl1ext(decl, initflg);
1732: break;
1733: case ARG:
1.11 cgd 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: }
1.1 cgd 1740: (void)decl1arg(decl, initflg);
1741: break;
1742: case AUTO:
1.11 cgd 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: }
1.1 cgd 1749: decl1loc(decl, initflg);
1750: break;
1751: default:
1.11 cgd 1752: lerror("idecl() 2");
1.1 cgd 1753: }
1754:
1755: if (initflg && !initerr)
1756: prepinit();
1.6 jpo 1757: }
1758:
1759: /*
1760: * Discard all input tokens up to and including the next
1761: * unmatched right paren
1762: */
1.22 thorpej 1763: static void
1.20 lukem 1764: ignuptorp(void)
1.6 jpo 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;
1.1 cgd 1783: }
CVSweb <webmaster@jp.NetBSD.org>