112099Sjoerg%{ 2281168Spfg/* $NetBSD: cgram.y,v 1.40 2008/04/25 17:18:24 christos Exp $ */ 312099Sjoerg 412099Sjoerg/* 591592Smarkm * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 612099Sjoerg * Copyright (c) 1994, 1995 Jochen Pohl 712099Sjoerg * All Rights Reserved. 812099Sjoerg * 912099Sjoerg * Redistribution and use in source and binary forms, with or without 1012099Sjoerg * modification, are permitted provided that the following conditions 1112099Sjoerg * are met: 1212099Sjoerg * 1. Redistributions of source code must retain the above copyright 1312099Sjoerg * notice, this list of conditions and the following disclaimer. 1412099Sjoerg * 2. Redistributions in binary form must reproduce the above copyright 1512099Sjoerg * notice, this list of conditions and the following disclaimer in the 1612099Sjoerg * documentation and/or other materials provided with the distribution. 1712099Sjoerg * 3. All advertising materials mentioning features or use of this software 1812099Sjoerg * must display the following acknowledgement: 1912099Sjoerg * This product includes software developed by Jochen Pohl for 2012099Sjoerg * The NetBSD Project. 2112099Sjoerg * 4. The name of the author may not be used to endorse or promote products 2212099Sjoerg * derived from this software without specific prior written permission. 2312099Sjoerg * 2412099Sjoerg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2512099Sjoerg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2612099Sjoerg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2712099Sjoerg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2812099Sjoerg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2912099Sjoerg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3012099Sjoerg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3112099Sjoerg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3212099Sjoerg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3312099Sjoerg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3412099Sjoerg */ 3512099Sjoerg 3691592Smarkm#include <sys/cdefs.h> 3791592Smarkm#if defined(__RCSID) && !defined(lint) 38281168Spfg__RCSID("$NetBSD: cgram.y,v 1.40 2008/04/25 17:18:24 christos Exp $"); 3912099Sjoerg#endif 4091592Smarkm__FBSDID("$FreeBSD: releng/10.2/usr.bin/xlint/lint1/cgram.y 281168 2015-04-06 19:56:27Z pfg $"); 4112099Sjoerg 4212099Sjoerg#include <stdlib.h> 4391592Smarkm#include <string.h> 4412099Sjoerg#include <limits.h> 4512099Sjoerg 4612099Sjoerg#include "lint1.h" 4712099Sjoerg 4812099Sjoerg/* 4912099Sjoerg * Contains the level of current declaration. 0 is extern. 5012099Sjoerg * Used for symbol table entries. 5112099Sjoerg */ 5212099Sjoergint blklev; 5312099Sjoerg 5412099Sjoerg/* 5512099Sjoerg * level for memory allocation. Normaly the same as blklev. 5612099Sjoerg * An exeption is the declaration of arguments in prototypes. Memory 5712099Sjoerg * for these can't be freed after the declaration, but symbols must 5812099Sjoerg * be removed from the symbol table after the declaration. 5912099Sjoerg */ 6012099Sjoergint mblklev; 6112099Sjoerg 6291592Smarkm/* 6391592Smarkm * Save the no-warns state and restore it to avoid the problem where 6491592Smarkm * if (expr) { stmt } / * NOLINT * / stmt; 6591592Smarkm */ 6691592Smarkmstatic int onowarn = -1; 6712099Sjoerg 68281168Spfgstatic int toicon(tnode_t *, int); 6991592Smarkmstatic void idecl(sym_t *, int, sbuf_t *); 7091592Smarkmstatic void ignuptorp(void); 7191592Smarkm 7291592Smarkm#ifdef DEBUG 73281168Spfgstatic inline void CLRWFLGS(void); 74281168Spfgstatic inline void CLRWFLGS(void) 7591592Smarkm{ 7691592Smarkm printf("%s, %d: clear flags %s %d\n", curr_pos.p_file, 7791592Smarkm curr_pos.p_line, __FILE__, __LINE__); 7891592Smarkm clrwflgs(); 7991592Smarkm onowarn = -1; 8091592Smarkm} 8191592Smarkm 82281168Spfgstatic inline void SAVE(void); 83281168Spfgstatic inline void SAVE(void) 8491592Smarkm{ 8591592Smarkm if (onowarn != -1) 8691592Smarkm abort(); 8791592Smarkm printf("%s, %d: save flags %s %d = %d\n", curr_pos.p_file, 8891592Smarkm curr_pos.p_line, __FILE__, __LINE__, nowarn); 8991592Smarkm onowarn = nowarn; 9091592Smarkm} 9191592Smarkm 92281168Spfgstatic inline void RESTORE(void); 93281168Spfgstatic inline void RESTORE(void) 9491592Smarkm{ 9591592Smarkm if (onowarn != -1) { 9691592Smarkm nowarn = onowarn; 9791592Smarkm printf("%s, %d: restore flags %s %d = %d\n", curr_pos.p_file, 9891592Smarkm curr_pos.p_line, __FILE__, __LINE__, nowarn); 9991592Smarkm onowarn = -1; 10091592Smarkm } else 10191592Smarkm CLRWFLGS(); 10291592Smarkm} 10391592Smarkm#else 10491592Smarkm#define CLRWFLGS() clrwflgs(), onowarn = -1 10591592Smarkm#define SAVE() onowarn = nowarn 10691592Smarkm#define RESTORE() (void)(onowarn == -1 ? (clrwflgs(), 0) : (nowarn = onowarn)) 10791592Smarkm#endif 10812099Sjoerg%} 10912099Sjoerg 110281168Spfg%expect 1 111281168Spfg 11212099Sjoerg%union { 11312099Sjoerg int y_int; 11412099Sjoerg val_t *y_val; 11512099Sjoerg sbuf_t *y_sb; 11612099Sjoerg sym_t *y_sym; 11712099Sjoerg op_t y_op; 11812099Sjoerg scl_t y_scl; 11912099Sjoerg tspec_t y_tspec; 12012099Sjoerg tqual_t y_tqual; 12112099Sjoerg type_t *y_type; 12212099Sjoerg tnode_t *y_tnode; 123281168Spfg range_t y_range; 12412099Sjoerg strg_t *y_strg; 12512099Sjoerg pqinf_t *y_pqinf; 12612099Sjoerg}; 12712099Sjoerg 12812099Sjoerg%token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN 12912099Sjoerg%token <y_op> T_STROP 13012099Sjoerg%token <y_op> T_UNOP 13112099Sjoerg%token <y_op> T_INCDEC 13212099Sjoerg%token T_SIZEOF 13312099Sjoerg%token <y_op> T_MULT 13412099Sjoerg%token <y_op> T_DIVOP 13512099Sjoerg%token <y_op> T_ADDOP 13612099Sjoerg%token <y_op> T_SHFTOP 13712099Sjoerg%token <y_op> T_RELOP 13812099Sjoerg%token <y_op> T_EQOP 13912099Sjoerg%token <y_op> T_AND 14012099Sjoerg%token <y_op> T_XOR 14112099Sjoerg%token <y_op> T_OR 14212099Sjoerg%token <y_op> T_LOGAND 14312099Sjoerg%token <y_op> T_LOGOR 14412099Sjoerg%token T_QUEST 14512099Sjoerg%token T_COLON 14612099Sjoerg%token <y_op> T_ASSIGN 14712099Sjoerg%token <y_op> T_OPASS 14812099Sjoerg%token T_COMMA 14912099Sjoerg%token T_SEMI 15012099Sjoerg%token T_ELLIPSE 15112099Sjoerg 15212099Sjoerg/* storage classes (extern, static, auto, register and typedef) */ 15312099Sjoerg%token <y_scl> T_SCLASS 15412099Sjoerg 15512099Sjoerg/* types (char, int, short, long, unsigned, signed, float, double, void) */ 15612099Sjoerg%token <y_tspec> T_TYPE 15712099Sjoerg 15812099Sjoerg/* qualifiers (const, volatile) */ 15912099Sjoerg%token <y_tqual> T_QUAL 16012099Sjoerg 16112099Sjoerg/* struct or union */ 16212099Sjoerg%token <y_tspec> T_SOU 16312099Sjoerg 16412099Sjoerg/* enum */ 16512099Sjoerg%token T_ENUM 16612099Sjoerg 16712099Sjoerg/* remaining keywords */ 16812099Sjoerg%token T_CASE 16912099Sjoerg%token T_DEFAULT 17012099Sjoerg%token T_IF 17112099Sjoerg%token T_ELSE 17212099Sjoerg%token T_SWITCH 17312099Sjoerg%token T_DO 17412099Sjoerg%token T_WHILE 17512099Sjoerg%token T_FOR 17612099Sjoerg%token T_GOTO 17712099Sjoerg%token T_CONTINUE 17812099Sjoerg%token T_BREAK 17912099Sjoerg%token T_RETURN 18012099Sjoerg%token T_ASM 18191592Smarkm%token T_SYMBOLRENAME 18212099Sjoerg 18312099Sjoerg%left T_COMMA 18412099Sjoerg%right T_ASSIGN T_OPASS 18512099Sjoerg%right T_QUEST T_COLON 18612099Sjoerg%left T_LOGOR 18712099Sjoerg%left T_LOGAND 18812099Sjoerg%left T_OR 18912099Sjoerg%left T_XOR 19012099Sjoerg%left T_AND 19112099Sjoerg%left T_EQOP 19212099Sjoerg%left T_RELOP 19312099Sjoerg%left T_SHFTOP 19412099Sjoerg%left T_ADDOP 19512099Sjoerg%left T_MULT T_DIVOP 19612099Sjoerg%right T_UNOP T_INCDEC T_SIZEOF 19712099Sjoerg%left T_LPARN T_LBRACK T_STROP 19812099Sjoerg 19912099Sjoerg%token <y_sb> T_NAME 20012099Sjoerg%token <y_sb> T_TYPENAME 20112099Sjoerg%token <y_val> T_CON 20212099Sjoerg%token <y_strg> T_STRING 20312099Sjoerg 20412099Sjoerg%type <y_sym> func_decl 20512099Sjoerg%type <y_sym> notype_decl 20612099Sjoerg%type <y_sym> type_decl 20712099Sjoerg%type <y_type> typespec 20812099Sjoerg%type <y_type> clrtyp_typespec 20912099Sjoerg%type <y_type> notype_typespec 21012099Sjoerg%type <y_type> struct_spec 21112099Sjoerg%type <y_type> enum_spec 21212099Sjoerg%type <y_sym> struct_tag 21312099Sjoerg%type <y_sym> enum_tag 21412099Sjoerg%type <y_tspec> struct 21512099Sjoerg%type <y_sym> struct_declaration 21612099Sjoerg%type <y_sb> identifier 21712099Sjoerg%type <y_sym> member_declaration_list_with_rbrace 21812099Sjoerg%type <y_sym> member_declaration_list 21912099Sjoerg%type <y_sym> member_declaration 22012099Sjoerg%type <y_sym> notype_member_decls 22112099Sjoerg%type <y_sym> type_member_decls 22212099Sjoerg%type <y_sym> notype_member_decl 22312099Sjoerg%type <y_sym> type_member_decl 22412099Sjoerg%type <y_tnode> constant 22512099Sjoerg%type <y_sym> enum_declaration 22612099Sjoerg%type <y_sym> enums_with_opt_comma 22712099Sjoerg%type <y_sym> enums 22812099Sjoerg%type <y_sym> enumerator 22912099Sjoerg%type <y_sym> ename 23012099Sjoerg%type <y_sym> notype_direct_decl 23112099Sjoerg%type <y_sym> type_direct_decl 23212099Sjoerg%type <y_pqinf> pointer 23312099Sjoerg%type <y_pqinf> asterisk 23412099Sjoerg%type <y_sym> param_decl 23512099Sjoerg%type <y_sym> param_list 23612099Sjoerg%type <y_sym> abs_decl_param_list 23712099Sjoerg%type <y_sym> direct_param_decl 23812099Sjoerg%type <y_sym> notype_param_decl 23912099Sjoerg%type <y_sym> direct_notype_param_decl 24012099Sjoerg%type <y_pqinf> type_qualifier_list 24112099Sjoerg%type <y_pqinf> type_qualifier 24212099Sjoerg%type <y_sym> identifier_list 24312099Sjoerg%type <y_sym> abs_decl 24412099Sjoerg%type <y_sym> direct_abs_decl 24512099Sjoerg%type <y_sym> vararg_parameter_type_list 24612099Sjoerg%type <y_sym> parameter_type_list 24712099Sjoerg%type <y_sym> parameter_declaration 24812099Sjoerg%type <y_tnode> expr 249281168Spfg%type <y_tnode> expr_stmnt_val 250281168Spfg%type <y_tnode> expr_stmnt_list 25112099Sjoerg%type <y_tnode> term 25212099Sjoerg%type <y_tnode> func_arg_list 25312099Sjoerg%type <y_op> point_or_arrow 25412099Sjoerg%type <y_type> type_name 25512099Sjoerg%type <y_sym> abstract_declaration 25612099Sjoerg%type <y_tnode> do_while_expr 25712099Sjoerg%type <y_tnode> opt_expr 25812099Sjoerg%type <y_strg> string 25912099Sjoerg%type <y_strg> string2 26091592Smarkm%type <y_sb> opt_asm_or_symbolrename 261281168Spfg%type <y_range> range 262281168Spfg%type <y_range> lorange 26312099Sjoerg 26412099Sjoerg 26512099Sjoerg%% 26612099Sjoerg 26712099Sjoergprogram: 26812099Sjoerg /* empty */ { 26912099Sjoerg if (sflag) { 27012099Sjoerg /* empty translation unit */ 27112099Sjoerg error(272); 27212099Sjoerg } else if (!tflag) { 27312099Sjoerg /* empty translation unit */ 27412099Sjoerg warning(272); 27512099Sjoerg } 27612099Sjoerg } 27712099Sjoerg | translation_unit 27812099Sjoerg ; 27912099Sjoerg 28012099Sjoergtranslation_unit: 28112099Sjoerg ext_decl 28212099Sjoerg | translation_unit ext_decl 28312099Sjoerg ; 28412099Sjoerg 28512099Sjoergext_decl: 28691592Smarkm asm_stmnt 28791592Smarkm | func_def { 28812099Sjoerg glclup(0); 28991592Smarkm CLRWFLGS(); 29012099Sjoerg } 29112099Sjoerg | data_def { 29212099Sjoerg glclup(0); 29391592Smarkm CLRWFLGS(); 29412099Sjoerg } 29512099Sjoerg ; 29612099Sjoerg 29712099Sjoergdata_def: 29812099Sjoerg T_SEMI { 29912099Sjoerg if (sflag) { 30012099Sjoerg /* syntax error: empty declaration */ 30112099Sjoerg error(0); 30212099Sjoerg } else if (!tflag) { 30312099Sjoerg /* syntax error: empty declaration */ 30412099Sjoerg warning(0); 30512099Sjoerg } 30612099Sjoerg } 30712099Sjoerg | clrtyp deftyp notype_init_decls T_SEMI { 30812099Sjoerg if (sflag) { 30912099Sjoerg /* old style declaration; add "int" */ 31012099Sjoerg error(1); 31112099Sjoerg } else if (!tflag) { 31212099Sjoerg /* old style declaration; add "int" */ 31312099Sjoerg warning(1); 31412099Sjoerg } 31512099Sjoerg } 31612099Sjoerg | declmods deftyp T_SEMI { 31712099Sjoerg if (dcs->d_scl == TYPEDEF) { 31812099Sjoerg /* typedef declares no type name */ 31912099Sjoerg warning(72); 32012099Sjoerg } else { 32112099Sjoerg /* empty declaration */ 32212099Sjoerg warning(2); 32312099Sjoerg } 32412099Sjoerg } 32512099Sjoerg | declmods deftyp notype_init_decls T_SEMI 32612099Sjoerg | declspecs deftyp T_SEMI { 32712099Sjoerg if (dcs->d_scl == TYPEDEF) { 32812099Sjoerg /* typedef declares no type name */ 32912099Sjoerg warning(72); 33012099Sjoerg } else if (!dcs->d_nedecl) { 33112099Sjoerg /* empty declaration */ 33212099Sjoerg warning(2); 33312099Sjoerg } 33412099Sjoerg } 33512099Sjoerg | declspecs deftyp type_init_decls T_SEMI 33612099Sjoerg | error T_SEMI { 33791592Smarkm globclup(); 33812099Sjoerg } 33912099Sjoerg | error T_RBRACE { 34012099Sjoerg globclup(); 34112099Sjoerg } 34212099Sjoerg ; 34312099Sjoerg 34412099Sjoergfunc_def: 34512099Sjoerg func_decl { 34612099Sjoerg if ($1->s_type->t_tspec != FUNC) { 34712099Sjoerg /* syntax error */ 34812099Sjoerg error(249); 34912099Sjoerg YYERROR; 35012099Sjoerg } 35112099Sjoerg if ($1->s_type->t_typedef) { 35212099Sjoerg /* ()-less function definition */ 35312099Sjoerg error(64); 35412099Sjoerg YYERROR; 35512099Sjoerg } 35612099Sjoerg funcdef($1); 35712099Sjoerg blklev++; 35812099Sjoerg pushdecl(ARG); 35912099Sjoerg } opt_arg_declaration_list { 36012099Sjoerg popdecl(); 36112099Sjoerg blklev--; 36212099Sjoerg cluparg(); 36312099Sjoerg pushctrl(0); 36412099Sjoerg } comp_stmnt { 36512099Sjoerg funcend(); 36612099Sjoerg popctrl(0); 36712099Sjoerg } 36812099Sjoerg ; 36912099Sjoerg 37012099Sjoergfunc_decl: 37112099Sjoerg clrtyp deftyp notype_decl { 37212099Sjoerg $$ = $3; 37312099Sjoerg } 37412099Sjoerg | declmods deftyp notype_decl { 37512099Sjoerg $$ = $3; 37612099Sjoerg } 37712099Sjoerg | declspecs deftyp type_decl { 37812099Sjoerg $$ = $3; 37912099Sjoerg } 38012099Sjoerg ; 38112099Sjoerg 38212099Sjoergopt_arg_declaration_list: 38312099Sjoerg /* empty */ 38412099Sjoerg | arg_declaration_list 38512099Sjoerg ; 38612099Sjoerg 38712099Sjoergarg_declaration_list: 38812099Sjoerg arg_declaration 38912099Sjoerg | arg_declaration_list arg_declaration 39012099Sjoerg /* XXX or better "arg_declaration error" ? */ 39112099Sjoerg | error 39212099Sjoerg ; 39312099Sjoerg 39412099Sjoerg/* 39512099Sjoerg * "arg_declaration" is separated from "declaration" because it 39612099Sjoerg * needs other error handling. 39712099Sjoerg */ 39812099Sjoerg 39912099Sjoergarg_declaration: 40012099Sjoerg declmods deftyp T_SEMI { 40112099Sjoerg /* empty declaration */ 40212099Sjoerg warning(2); 40312099Sjoerg } 40412099Sjoerg | declmods deftyp notype_init_decls T_SEMI 40512099Sjoerg | declspecs deftyp T_SEMI { 40612099Sjoerg if (!dcs->d_nedecl) { 40712099Sjoerg /* empty declaration */ 40812099Sjoerg warning(2); 40912099Sjoerg } else { 41012099Sjoerg tspec_t ts = dcs->d_type->t_tspec; 41112099Sjoerg /* %s declared in argument declaration list */ 41212099Sjoerg warning(3, ts == STRUCT ? "struct" : 41312099Sjoerg (ts == UNION ? "union" : "enum")); 41412099Sjoerg } 41512099Sjoerg } 41612099Sjoerg | declspecs deftyp type_init_decls T_SEMI { 41712099Sjoerg if (dcs->d_nedecl) { 41812099Sjoerg tspec_t ts = dcs->d_type->t_tspec; 41912099Sjoerg /* %s declared in argument declaration list */ 42012099Sjoerg warning(3, ts == STRUCT ? "struct" : 42112099Sjoerg (ts == UNION ? "union" : "enum")); 42212099Sjoerg } 42312099Sjoerg } 42412099Sjoerg | declmods error 42512099Sjoerg | declspecs error 42612099Sjoerg ; 42712099Sjoerg 42812099Sjoergdeclaration: 42912099Sjoerg declmods deftyp T_SEMI { 43012099Sjoerg if (dcs->d_scl == TYPEDEF) { 43112099Sjoerg /* typedef declares no type name */ 43212099Sjoerg warning(72); 43312099Sjoerg } else { 43412099Sjoerg /* empty declaration */ 43512099Sjoerg warning(2); 43612099Sjoerg } 43712099Sjoerg } 43812099Sjoerg | declmods deftyp notype_init_decls T_SEMI 43912099Sjoerg | declspecs deftyp T_SEMI { 44012099Sjoerg if (dcs->d_scl == TYPEDEF) { 44112099Sjoerg /* typedef declares no type name */ 44212099Sjoerg warning(72); 44312099Sjoerg } else if (!dcs->d_nedecl) { 44412099Sjoerg /* empty declaration */ 44512099Sjoerg warning(2); 44612099Sjoerg } 44712099Sjoerg } 44812099Sjoerg | declspecs deftyp type_init_decls T_SEMI 44912099Sjoerg | error T_SEMI 45012099Sjoerg ; 45112099Sjoerg 45212099Sjoergclrtyp: 45312099Sjoerg { 45412099Sjoerg clrtyp(); 45512099Sjoerg } 45612099Sjoerg ; 45712099Sjoerg 45812099Sjoergdeftyp: 45912099Sjoerg /* empty */ { 46012099Sjoerg deftyp(); 46112099Sjoerg } 46212099Sjoerg ; 46312099Sjoerg 46412099Sjoergdeclspecs: 46512099Sjoerg clrtyp_typespec { 46612099Sjoerg addtype($1); 46712099Sjoerg } 46812099Sjoerg | declmods typespec { 46912099Sjoerg addtype($2); 47012099Sjoerg } 47112099Sjoerg | declspecs declmod 47212099Sjoerg | declspecs notype_typespec { 47312099Sjoerg addtype($2); 47412099Sjoerg } 47512099Sjoerg ; 47612099Sjoerg 47712099Sjoergdeclmods: 47812099Sjoerg clrtyp T_QUAL { 47912099Sjoerg addqual($2); 48012099Sjoerg } 48112099Sjoerg | clrtyp T_SCLASS { 48212099Sjoerg addscl($2); 48312099Sjoerg } 48412099Sjoerg | declmods declmod 48512099Sjoerg ; 48612099Sjoerg 48712099Sjoergdeclmod: 48812099Sjoerg T_QUAL { 48912099Sjoerg addqual($1); 49012099Sjoerg } 49112099Sjoerg | T_SCLASS { 49212099Sjoerg addscl($1); 49312099Sjoerg } 49412099Sjoerg ; 49512099Sjoerg 49612099Sjoergclrtyp_typespec: 49712099Sjoerg clrtyp notype_typespec { 49812099Sjoerg $$ = $2; 49912099Sjoerg } 50012099Sjoerg | T_TYPENAME clrtyp { 50112099Sjoerg $$ = getsym($1)->s_type; 50212099Sjoerg } 50312099Sjoerg ; 50412099Sjoerg 50512099Sjoergtypespec: 50612099Sjoerg notype_typespec { 50712099Sjoerg $$ = $1; 50812099Sjoerg } 50912099Sjoerg | T_TYPENAME { 51012099Sjoerg $$ = getsym($1)->s_type; 51112099Sjoerg } 51212099Sjoerg ; 51312099Sjoerg 51412099Sjoergnotype_typespec: 51512099Sjoerg T_TYPE { 51612099Sjoerg $$ = gettyp($1); 51712099Sjoerg } 51812099Sjoerg | struct_spec { 51912099Sjoerg popdecl(); 52012099Sjoerg $$ = $1; 52112099Sjoerg } 52212099Sjoerg | enum_spec { 52312099Sjoerg popdecl(); 52412099Sjoerg $$ = $1; 52512099Sjoerg } 52612099Sjoerg ; 52712099Sjoerg 52812099Sjoergstruct_spec: 52912099Sjoerg struct struct_tag { 53012099Sjoerg /* 53112099Sjoerg * STDC requires that "struct a;" always introduces 53212099Sjoerg * a new tag if "a" is not declared at current level 53312099Sjoerg * 53412099Sjoerg * yychar is valid because otherwise the parser would 53512099Sjoerg * not been able to deceide if he must shift or reduce 53612099Sjoerg */ 53712099Sjoerg $$ = mktag($2, $1, 0, yychar == T_SEMI); 53812099Sjoerg } 53912099Sjoerg | struct struct_tag { 54012099Sjoerg dcs->d_tagtyp = mktag($2, $1, 1, 0); 54112099Sjoerg } struct_declaration { 54212099Sjoerg $$ = compltag(dcs->d_tagtyp, $4); 54312099Sjoerg } 54412099Sjoerg | struct { 54512099Sjoerg dcs->d_tagtyp = mktag(NULL, $1, 1, 0); 54612099Sjoerg } struct_declaration { 54712099Sjoerg $$ = compltag(dcs->d_tagtyp, $3); 54812099Sjoerg } 54912099Sjoerg | struct error { 55012099Sjoerg symtyp = FVFT; 55112099Sjoerg $$ = gettyp(INT); 55212099Sjoerg } 55312099Sjoerg ; 55412099Sjoerg 55512099Sjoergstruct: 55612099Sjoerg T_SOU { 55712099Sjoerg symtyp = FTAG; 55812099Sjoerg pushdecl($1 == STRUCT ? MOS : MOU); 55912099Sjoerg dcs->d_offset = 0; 56012099Sjoerg dcs->d_stralign = CHAR_BIT; 56112099Sjoerg $$ = $1; 56212099Sjoerg } 56312099Sjoerg ; 56412099Sjoerg 56512099Sjoergstruct_tag: 56612099Sjoerg identifier { 56712099Sjoerg $$ = getsym($1); 56812099Sjoerg } 56912099Sjoerg ; 57012099Sjoerg 57112099Sjoergstruct_declaration: 57212099Sjoerg struct_decl_lbrace member_declaration_list_with_rbrace { 57312099Sjoerg $$ = $2; 57412099Sjoerg } 57512099Sjoerg ; 57612099Sjoerg 57712099Sjoergstruct_decl_lbrace: 57812099Sjoerg T_LBRACE { 57912099Sjoerg symtyp = FVFT; 58012099Sjoerg } 58112099Sjoerg ; 58212099Sjoerg 58312099Sjoergmember_declaration_list_with_rbrace: 58412099Sjoerg member_declaration_list T_SEMI T_RBRACE { 58512099Sjoerg $$ = $1; 58612099Sjoerg } 58712099Sjoerg | member_declaration_list T_RBRACE { 58812099Sjoerg if (sflag) { 58912099Sjoerg /* syntax req. ";" after last struct/union member */ 59012099Sjoerg error(66); 59112099Sjoerg } else { 59212099Sjoerg /* syntax req. ";" after last struct/union member */ 59312099Sjoerg warning(66); 59412099Sjoerg } 59512099Sjoerg $$ = $1; 59612099Sjoerg } 59712099Sjoerg | T_RBRACE { 59812099Sjoerg $$ = NULL; 59912099Sjoerg } 60012099Sjoerg ; 60112099Sjoerg 60212099Sjoergmember_declaration_list: 60312099Sjoerg member_declaration { 60412099Sjoerg $$ = $1; 60512099Sjoerg } 60612099Sjoerg | member_declaration_list T_SEMI member_declaration { 60712099Sjoerg $$ = lnklst($1, $3); 60812099Sjoerg } 60912099Sjoerg ; 61012099Sjoerg 61112099Sjoergmember_declaration: 61212099Sjoerg noclass_declmods deftyp { 61312099Sjoerg /* too late, i know, but getsym() compensates it */ 61412099Sjoerg symtyp = FMOS; 61512099Sjoerg } notype_member_decls { 61612099Sjoerg symtyp = FVFT; 61712099Sjoerg $$ = $4; 61812099Sjoerg } 61912099Sjoerg | noclass_declspecs deftyp { 62012099Sjoerg symtyp = FMOS; 62112099Sjoerg } type_member_decls { 62212099Sjoerg symtyp = FVFT; 62312099Sjoerg $$ = $4; 62412099Sjoerg } 62512099Sjoerg | noclass_declmods deftyp { 62612099Sjoerg /* struct or union member must be named */ 62712099Sjoerg warning(49); 62812099Sjoerg $$ = NULL; 62912099Sjoerg } 63012099Sjoerg | noclass_declspecs deftyp { 63112099Sjoerg /* struct or union member must be named */ 63212099Sjoerg warning(49); 63312099Sjoerg $$ = NULL; 63412099Sjoerg } 63512099Sjoerg | error { 63612099Sjoerg symtyp = FVFT; 63712099Sjoerg $$ = NULL; 63812099Sjoerg } 63912099Sjoerg ; 64012099Sjoerg 64112099Sjoergnoclass_declspecs: 64212099Sjoerg clrtyp_typespec { 64312099Sjoerg addtype($1); 64412099Sjoerg } 64512099Sjoerg | noclass_declmods typespec { 64612099Sjoerg addtype($2); 64712099Sjoerg } 64812099Sjoerg | noclass_declspecs T_QUAL { 64912099Sjoerg addqual($2); 65012099Sjoerg } 65112099Sjoerg | noclass_declspecs notype_typespec { 65212099Sjoerg addtype($2); 65312099Sjoerg } 65412099Sjoerg ; 65512099Sjoerg 65612099Sjoergnoclass_declmods: 65712099Sjoerg clrtyp T_QUAL { 65812099Sjoerg addqual($2); 65912099Sjoerg } 66012099Sjoerg | noclass_declmods T_QUAL { 66112099Sjoerg addqual($2); 66212099Sjoerg } 66312099Sjoerg ; 66412099Sjoerg 66512099Sjoergnotype_member_decls: 66612099Sjoerg notype_member_decl { 66712099Sjoerg $$ = decl1str($1); 66812099Sjoerg } 66912099Sjoerg | notype_member_decls { 67012099Sjoerg symtyp = FMOS; 67112099Sjoerg } T_COMMA type_member_decl { 67212099Sjoerg $$ = lnklst($1, decl1str($4)); 67312099Sjoerg } 67412099Sjoerg ; 67512099Sjoerg 67612099Sjoergtype_member_decls: 67712099Sjoerg type_member_decl { 67812099Sjoerg $$ = decl1str($1); 67912099Sjoerg } 68012099Sjoerg | type_member_decls { 68112099Sjoerg symtyp = FMOS; 68212099Sjoerg } T_COMMA type_member_decl { 68312099Sjoerg $$ = lnklst($1, decl1str($4)); 68412099Sjoerg } 68512099Sjoerg ; 68612099Sjoerg 68712099Sjoergnotype_member_decl: 68812099Sjoerg notype_decl { 68912099Sjoerg $$ = $1; 69012099Sjoerg } 69112099Sjoerg | notype_decl T_COLON constant { 692281168Spfg $$ = bitfield($1, toicon($3, 1)); 69312099Sjoerg } 69412099Sjoerg | { 69512099Sjoerg symtyp = FVFT; 69612099Sjoerg } T_COLON constant { 697281168Spfg $$ = bitfield(NULL, toicon($3, 1)); 69812099Sjoerg } 69912099Sjoerg ; 70012099Sjoerg 70112099Sjoergtype_member_decl: 70212099Sjoerg type_decl { 70312099Sjoerg $$ = $1; 70412099Sjoerg } 70512099Sjoerg | type_decl T_COLON constant { 706281168Spfg $$ = bitfield($1, toicon($3, 1)); 70712099Sjoerg } 70812099Sjoerg | { 70912099Sjoerg symtyp = FVFT; 71012099Sjoerg } T_COLON constant { 711281168Spfg $$ = bitfield(NULL, toicon($3, 1)); 71212099Sjoerg } 71312099Sjoerg ; 71412099Sjoerg 71512099Sjoergenum_spec: 71612099Sjoerg enum enum_tag { 71712099Sjoerg $$ = mktag($2, ENUM, 0, 0); 71812099Sjoerg } 71912099Sjoerg | enum enum_tag { 72012099Sjoerg dcs->d_tagtyp = mktag($2, ENUM, 1, 0); 72112099Sjoerg } enum_declaration { 72212099Sjoerg $$ = compltag(dcs->d_tagtyp, $4); 72312099Sjoerg } 72412099Sjoerg | enum { 72512099Sjoerg dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0); 72612099Sjoerg } enum_declaration { 72712099Sjoerg $$ = compltag(dcs->d_tagtyp, $3); 72812099Sjoerg } 72912099Sjoerg | enum error { 73012099Sjoerg symtyp = FVFT; 73112099Sjoerg $$ = gettyp(INT); 73212099Sjoerg } 73312099Sjoerg ; 73412099Sjoerg 73512099Sjoergenum: 73612099Sjoerg T_ENUM { 73712099Sjoerg symtyp = FTAG; 73812099Sjoerg pushdecl(ENUMCON); 73912099Sjoerg } 74012099Sjoerg ; 74112099Sjoerg 74212099Sjoergenum_tag: 74312099Sjoerg identifier { 74412099Sjoerg $$ = getsym($1); 74512099Sjoerg } 74612099Sjoerg ; 74712099Sjoerg 74812099Sjoergenum_declaration: 74912099Sjoerg enum_decl_lbrace enums_with_opt_comma T_RBRACE { 75012099Sjoerg $$ = $2; 75112099Sjoerg } 75212099Sjoerg ; 75312099Sjoerg 75412099Sjoergenum_decl_lbrace: 75512099Sjoerg T_LBRACE { 75612099Sjoerg symtyp = FVFT; 75712099Sjoerg enumval = 0; 75812099Sjoerg } 75912099Sjoerg ; 76012099Sjoerg 76112099Sjoergenums_with_opt_comma: 76212099Sjoerg enums { 76312099Sjoerg $$ = $1; 76412099Sjoerg } 76512099Sjoerg | enums T_COMMA { 76612099Sjoerg if (sflag) { 76712099Sjoerg /* trailing "," prohibited in enum declaration */ 76812099Sjoerg error(54); 76912099Sjoerg } else { 77012099Sjoerg /* trailing "," prohibited in enum declaration */ 77191592Smarkm (void)gnuism(54); 77212099Sjoerg } 77312099Sjoerg $$ = $1; 77412099Sjoerg } 77512099Sjoerg ; 77612099Sjoerg 77712099Sjoergenums: 77812099Sjoerg enumerator { 77912099Sjoerg $$ = $1; 78012099Sjoerg } 78112099Sjoerg | enums T_COMMA enumerator { 78212099Sjoerg $$ = lnklst($1, $3); 78312099Sjoerg } 78412099Sjoerg | error { 78512099Sjoerg $$ = NULL; 78612099Sjoerg } 78712099Sjoerg ; 78812099Sjoerg 78912099Sjoergenumerator: 79012099Sjoerg ename { 79112099Sjoerg $$ = ename($1, enumval, 1); 79212099Sjoerg } 79312099Sjoerg | ename T_ASSIGN constant { 794281168Spfg $$ = ename($1, toicon($3, 1), 0); 79512099Sjoerg } 79612099Sjoerg ; 79712099Sjoerg 79812099Sjoergename: 79912099Sjoerg identifier { 80012099Sjoerg $$ = getsym($1); 80112099Sjoerg } 80212099Sjoerg ; 80312099Sjoerg 80412099Sjoerg 80512099Sjoergnotype_init_decls: 80612099Sjoerg notype_init_decl 80712099Sjoerg | notype_init_decls T_COMMA type_init_decl 80812099Sjoerg ; 80912099Sjoerg 81012099Sjoergtype_init_decls: 81112099Sjoerg type_init_decl 81212099Sjoerg | type_init_decls T_COMMA type_init_decl 81312099Sjoerg ; 81412099Sjoerg 81512099Sjoergnotype_init_decl: 81691592Smarkm notype_decl opt_asm_or_symbolrename { 81791592Smarkm idecl($1, 0, $2); 81812099Sjoerg chksz($1); 81912099Sjoerg } 82091592Smarkm | notype_decl opt_asm_or_symbolrename { 82191592Smarkm idecl($1, 1, $2); 82212099Sjoerg } T_ASSIGN initializer { 82312099Sjoerg chksz($1); 82412099Sjoerg } 82512099Sjoerg ; 82612099Sjoerg 82712099Sjoergtype_init_decl: 82891592Smarkm type_decl opt_asm_or_symbolrename { 82991592Smarkm idecl($1, 0, $2); 83012099Sjoerg chksz($1); 83112099Sjoerg } 83291592Smarkm | type_decl opt_asm_or_symbolrename { 83391592Smarkm idecl($1, 1, $2); 83412099Sjoerg } T_ASSIGN initializer { 83512099Sjoerg chksz($1); 83612099Sjoerg } 83712099Sjoerg ; 83812099Sjoerg 83912099Sjoergnotype_decl: 84012099Sjoerg notype_direct_decl { 84112099Sjoerg $$ = $1; 84212099Sjoerg } 84312099Sjoerg | pointer notype_direct_decl { 84412099Sjoerg $$ = addptr($2, $1); 84512099Sjoerg } 84612099Sjoerg ; 84712099Sjoerg 84812099Sjoergnotype_direct_decl: 84912099Sjoerg T_NAME { 85012099Sjoerg $$ = dname(getsym($1)); 85112099Sjoerg } 85212099Sjoerg | T_LPARN type_decl T_RPARN { 85312099Sjoerg $$ = $2; 85412099Sjoerg } 85512099Sjoerg | notype_direct_decl T_LBRACK T_RBRACK { 85612099Sjoerg $$ = addarray($1, 0, 0); 85712099Sjoerg } 85812099Sjoerg | notype_direct_decl T_LBRACK constant T_RBRACK { 859281168Spfg $$ = addarray($1, 1, toicon($3, 0)); 86012099Sjoerg } 86112099Sjoerg | notype_direct_decl param_list { 86212099Sjoerg $$ = addfunc($1, $2); 86312099Sjoerg popdecl(); 86412099Sjoerg blklev--; 86512099Sjoerg } 86612099Sjoerg ; 86712099Sjoerg 86812099Sjoergtype_decl: 86912099Sjoerg type_direct_decl { 87012099Sjoerg $$ = $1; 87112099Sjoerg } 87212099Sjoerg | pointer type_direct_decl { 87312099Sjoerg $$ = addptr($2, $1); 87412099Sjoerg } 87512099Sjoerg ; 87612099Sjoerg 87712099Sjoergtype_direct_decl: 87812099Sjoerg identifier { 87912099Sjoerg $$ = dname(getsym($1)); 88012099Sjoerg } 88112099Sjoerg | T_LPARN type_decl T_RPARN { 88212099Sjoerg $$ = $2; 88312099Sjoerg } 88412099Sjoerg | type_direct_decl T_LBRACK T_RBRACK { 88512099Sjoerg $$ = addarray($1, 0, 0); 88612099Sjoerg } 88712099Sjoerg | type_direct_decl T_LBRACK constant T_RBRACK { 888281168Spfg $$ = addarray($1, 1, toicon($3, 0)); 88912099Sjoerg } 89012099Sjoerg | type_direct_decl param_list { 89112099Sjoerg $$ = addfunc($1, $2); 89212099Sjoerg popdecl(); 89312099Sjoerg blklev--; 89412099Sjoerg } 89512099Sjoerg ; 89612099Sjoerg 89712099Sjoerg/* 89812099Sjoerg * param_decl and notype_param_decl exist to avoid a conflict in 89912099Sjoerg * argument lists. A typename enclosed in parens should always be 90012099Sjoerg * treated as a typename, not an argument. 90112099Sjoerg * "typedef int a; f(int (a));" is "typedef int a; f(int foo(a));" 90212099Sjoerg * not "typedef int a; f(int a);" 90312099Sjoerg */ 90412099Sjoergparam_decl: 90512099Sjoerg direct_param_decl { 90612099Sjoerg $$ = $1; 90712099Sjoerg } 90812099Sjoerg | pointer direct_param_decl { 90912099Sjoerg $$ = addptr($2, $1); 91012099Sjoerg } 91112099Sjoerg ; 91212099Sjoerg 91312099Sjoergdirect_param_decl: 91412099Sjoerg identifier { 91512099Sjoerg $$ = dname(getsym($1)); 91612099Sjoerg } 91712099Sjoerg | T_LPARN notype_param_decl T_RPARN { 91812099Sjoerg $$ = $2; 91912099Sjoerg } 92012099Sjoerg | direct_param_decl T_LBRACK T_RBRACK { 92112099Sjoerg $$ = addarray($1, 0, 0); 92212099Sjoerg } 92312099Sjoerg | direct_param_decl T_LBRACK constant T_RBRACK { 924281168Spfg $$ = addarray($1, 1, toicon($3, 0)); 92512099Sjoerg } 92612099Sjoerg | direct_param_decl param_list { 92712099Sjoerg $$ = addfunc($1, $2); 92812099Sjoerg popdecl(); 92912099Sjoerg blklev--; 93012099Sjoerg } 93112099Sjoerg ; 93212099Sjoerg 93312099Sjoergnotype_param_decl: 93412099Sjoerg direct_notype_param_decl { 93512099Sjoerg $$ = $1; 93612099Sjoerg } 93712099Sjoerg | pointer direct_notype_param_decl { 93812099Sjoerg $$ = addptr($2, $1); 93912099Sjoerg } 94012099Sjoerg ; 94112099Sjoerg 94212099Sjoergdirect_notype_param_decl: 94312099Sjoerg T_NAME { 94412099Sjoerg $$ = dname(getsym($1)); 94512099Sjoerg } 94612099Sjoerg | T_LPARN notype_param_decl T_RPARN { 94712099Sjoerg $$ = $2; 94812099Sjoerg } 94912099Sjoerg | direct_notype_param_decl T_LBRACK T_RBRACK { 95012099Sjoerg $$ = addarray($1, 0, 0); 95112099Sjoerg } 95212099Sjoerg | direct_notype_param_decl T_LBRACK constant T_RBRACK { 953281168Spfg $$ = addarray($1, 1, toicon($3, 0)); 95412099Sjoerg } 95512099Sjoerg | direct_notype_param_decl param_list { 95612099Sjoerg $$ = addfunc($1, $2); 95712099Sjoerg popdecl(); 95812099Sjoerg blklev--; 95912099Sjoerg } 96012099Sjoerg ; 96112099Sjoerg 96212099Sjoergpointer: 96312099Sjoerg asterisk { 96412099Sjoerg $$ = $1; 96512099Sjoerg } 96612099Sjoerg | asterisk type_qualifier_list { 96712099Sjoerg $$ = mergepq($1, $2); 96812099Sjoerg } 96912099Sjoerg | asterisk pointer { 97012099Sjoerg $$ = mergepq($1, $2); 97112099Sjoerg } 97212099Sjoerg | asterisk type_qualifier_list pointer { 97312099Sjoerg $$ = mergepq(mergepq($1, $2), $3); 97412099Sjoerg } 97512099Sjoerg ; 97612099Sjoerg 97712099Sjoergasterisk: 97812099Sjoerg T_MULT { 97991592Smarkm $$ = xcalloc(1, sizeof (pqinf_t)); 98012099Sjoerg $$->p_pcnt = 1; 98112099Sjoerg } 98212099Sjoerg ; 98312099Sjoerg 98412099Sjoergtype_qualifier_list: 98512099Sjoerg type_qualifier { 98612099Sjoerg $$ = $1; 98712099Sjoerg } 98812099Sjoerg | type_qualifier_list type_qualifier { 98912099Sjoerg $$ = mergepq($1, $2); 99012099Sjoerg } 99112099Sjoerg ; 99212099Sjoerg 99312099Sjoergtype_qualifier: 99412099Sjoerg T_QUAL { 99591592Smarkm $$ = xcalloc(1, sizeof (pqinf_t)); 99612099Sjoerg if ($1 == CONST) { 99712099Sjoerg $$->p_const = 1; 99812099Sjoerg } else { 99912099Sjoerg $$->p_volatile = 1; 100012099Sjoerg } 100112099Sjoerg } 100212099Sjoerg ; 100312099Sjoerg 100412099Sjoergparam_list: 100512099Sjoerg id_list_lparn identifier_list T_RPARN { 100612099Sjoerg $$ = $2; 100712099Sjoerg } 100812099Sjoerg | abs_decl_param_list { 100912099Sjoerg $$ = $1; 101012099Sjoerg } 101112099Sjoerg ; 101212099Sjoerg 101312099Sjoergid_list_lparn: 101412099Sjoerg T_LPARN { 101512099Sjoerg blklev++; 101612099Sjoerg pushdecl(PARG); 101712099Sjoerg } 101812099Sjoerg ; 101912099Sjoerg 102012099Sjoergidentifier_list: 102112099Sjoerg T_NAME { 102212099Sjoerg $$ = iname(getsym($1)); 102312099Sjoerg } 102412099Sjoerg | identifier_list T_COMMA T_NAME { 102512099Sjoerg $$ = lnklst($1, iname(getsym($3))); 102612099Sjoerg } 102712099Sjoerg | identifier_list error { 102812099Sjoerg $$ = $1; 102912099Sjoerg } 103012099Sjoerg ; 103112099Sjoerg 103212099Sjoergabs_decl_param_list: 103312099Sjoerg abs_decl_lparn T_RPARN { 103412099Sjoerg $$ = NULL; 103512099Sjoerg } 103612099Sjoerg | abs_decl_lparn vararg_parameter_type_list T_RPARN { 103712099Sjoerg dcs->d_proto = 1; 103812099Sjoerg $$ = $2; 103912099Sjoerg } 104012099Sjoerg | abs_decl_lparn error T_RPARN { 104112099Sjoerg $$ = NULL; 104212099Sjoerg } 104312099Sjoerg ; 104412099Sjoerg 104512099Sjoergabs_decl_lparn: 104612099Sjoerg T_LPARN { 104712099Sjoerg blklev++; 104812099Sjoerg pushdecl(PARG); 104912099Sjoerg } 105012099Sjoerg ; 105112099Sjoerg 105212099Sjoergvararg_parameter_type_list: 105312099Sjoerg parameter_type_list { 105412099Sjoerg $$ = $1; 105512099Sjoerg } 105612099Sjoerg | parameter_type_list T_COMMA T_ELLIPSE { 105712099Sjoerg dcs->d_vararg = 1; 105812099Sjoerg $$ = $1; 105912099Sjoerg } 106012099Sjoerg | T_ELLIPSE { 106112099Sjoerg if (sflag) { 106212099Sjoerg /* ANSI C requires formal parameter before "..." */ 106312099Sjoerg error(84); 106412099Sjoerg } else if (!tflag) { 106512099Sjoerg /* ANSI C requires formal parameter before "..." */ 106612099Sjoerg warning(84); 106712099Sjoerg } 106812099Sjoerg dcs->d_vararg = 1; 106912099Sjoerg $$ = NULL; 107012099Sjoerg } 107112099Sjoerg ; 107212099Sjoerg 107312099Sjoergparameter_type_list: 107491592Smarkm parameter_declaration { 107512099Sjoerg $$ = $1; 107612099Sjoerg } 107791592Smarkm | parameter_type_list T_COMMA parameter_declaration { 107812099Sjoerg $$ = lnklst($1, $3); 107912099Sjoerg } 108012099Sjoerg ; 108112099Sjoerg 108212099Sjoergparameter_declaration: 108312099Sjoerg declmods deftyp { 108412099Sjoerg $$ = decl1arg(aname(), 0); 108512099Sjoerg } 108612099Sjoerg | declspecs deftyp { 108712099Sjoerg $$ = decl1arg(aname(), 0); 108812099Sjoerg } 108912099Sjoerg | declmods deftyp notype_param_decl { 109012099Sjoerg $$ = decl1arg($3, 0); 109112099Sjoerg } 109212099Sjoerg /* 109312099Sjoerg * param_decl is needed because of following conflict: 109412099Sjoerg * "typedef int a; f(int (a));" could be parsed as 109512099Sjoerg * "function with argument a of type int", or 109612099Sjoerg * "function with an abstract argument of type function". 109712099Sjoerg * This grammar realizes the second case. 109812099Sjoerg */ 109912099Sjoerg | declspecs deftyp param_decl { 110012099Sjoerg $$ = decl1arg($3, 0); 110112099Sjoerg } 110212099Sjoerg | declmods deftyp abs_decl { 110312099Sjoerg $$ = decl1arg($3, 0); 110412099Sjoerg } 110512099Sjoerg | declspecs deftyp abs_decl { 110612099Sjoerg $$ = decl1arg($3, 0); 110712099Sjoerg } 110812099Sjoerg ; 110912099Sjoerg 111091592Smarkmopt_asm_or_symbolrename: /* expect only one */ 111191592Smarkm /* empty */ { 111291592Smarkm $$ = NULL; 111391592Smarkm } 111412099Sjoerg | T_ASM T_LPARN T_STRING T_RPARN { 111512099Sjoerg freeyyv(&$3, T_STRING); 111691592Smarkm $$ = NULL; 111712099Sjoerg } 111891592Smarkm | T_SYMBOLRENAME T_LPARN T_NAME T_RPARN { 111991592Smarkm $$ = $3; 112091592Smarkm } 112112099Sjoerg ; 112212099Sjoerg 112312099Sjoerginitializer: 112412099Sjoerg init_expr 112512099Sjoerg ; 112612099Sjoerg 112712099Sjoerginit_expr: 112812099Sjoerg expr %prec T_COMMA { 112912099Sjoerg mkinit($1); 113012099Sjoerg } 1131281168Spfg | init_by_name init_expr %prec T_COMMA 113212099Sjoerg | init_lbrace init_expr_list init_rbrace 113312099Sjoerg | init_lbrace init_expr_list T_COMMA init_rbrace 113412099Sjoerg | error 113512099Sjoerg ; 113612099Sjoerg 113712099Sjoerginit_expr_list: 113812099Sjoerg init_expr %prec T_COMMA 113912099Sjoerg | init_expr_list T_COMMA init_expr 114012099Sjoerg ; 114112099Sjoerg 1142281168Spfglorange: 1143281168Spfg constant T_ELLIPSE { 1144281168Spfg $$.lo = toicon($1, 1); 1145281168Spfg } 1146281168Spfg ; 1147281168Spfgrange: 1148281168Spfg constant { 1149281168Spfg $$.lo = toicon($1, 1); 1150281168Spfg $$.hi = $$.lo + 1; 1151281168Spfg } 1152281168Spfg | lorange constant { 1153281168Spfg $$.lo = $1.lo; 1154281168Spfg $$.hi = toicon($2, 1); 1155281168Spfg } 1156281168Spfg ; 1157281168Spfg 1158281168Spfginit_by_name: 1159281168Spfg T_LBRACK range T_RBRACK T_ASSIGN { 1160281168Spfg if (!Sflag) 1161281168Spfg warning(321); 1162281168Spfg } 1163281168Spfg | point identifier T_ASSIGN { 1164281168Spfg if (!Sflag) 1165281168Spfg warning(313); 1166281168Spfg memberpush($2); 1167281168Spfg } 1168281168Spfg | identifier T_COLON { 1169281168Spfg gnuism(315); 1170281168Spfg memberpush($1); 1171281168Spfg } 1172281168Spfg ; 1173281168Spfg 117412099Sjoerginit_lbrace: 117512099Sjoerg T_LBRACE { 117612099Sjoerg initlbr(); 117712099Sjoerg } 117812099Sjoerg ; 117912099Sjoerg 118012099Sjoerginit_rbrace: 118112099Sjoerg T_RBRACE { 118212099Sjoerg initrbr(); 118312099Sjoerg } 118412099Sjoerg ; 118512099Sjoerg 118612099Sjoergtype_name: 118712099Sjoerg { 118812099Sjoerg pushdecl(ABSTRACT); 118912099Sjoerg } abstract_declaration { 119012099Sjoerg popdecl(); 119112099Sjoerg $$ = $2->s_type; 119212099Sjoerg } 119312099Sjoerg ; 119412099Sjoerg 119512099Sjoergabstract_declaration: 119612099Sjoerg noclass_declmods deftyp { 119712099Sjoerg $$ = decl1abs(aname()); 119812099Sjoerg } 119912099Sjoerg | noclass_declspecs deftyp { 120012099Sjoerg $$ = decl1abs(aname()); 120112099Sjoerg } 120212099Sjoerg | noclass_declmods deftyp abs_decl { 120312099Sjoerg $$ = decl1abs($3); 120412099Sjoerg } 120512099Sjoerg | noclass_declspecs deftyp abs_decl { 120612099Sjoerg $$ = decl1abs($3); 120712099Sjoerg } 120812099Sjoerg ; 120912099Sjoerg 121012099Sjoergabs_decl: 121112099Sjoerg pointer { 121212099Sjoerg $$ = addptr(aname(), $1); 121312099Sjoerg } 121412099Sjoerg | direct_abs_decl { 121512099Sjoerg $$ = $1; 121612099Sjoerg } 121712099Sjoerg | pointer direct_abs_decl { 121812099Sjoerg $$ = addptr($2, $1); 121912099Sjoerg } 122012099Sjoerg ; 122112099Sjoerg 122212099Sjoergdirect_abs_decl: 122312099Sjoerg T_LPARN abs_decl T_RPARN { 122412099Sjoerg $$ = $2; 122512099Sjoerg } 122612099Sjoerg | T_LBRACK T_RBRACK { 122712099Sjoerg $$ = addarray(aname(), 0, 0); 122812099Sjoerg } 122912099Sjoerg | T_LBRACK constant T_RBRACK { 1230281168Spfg $$ = addarray(aname(), 1, toicon($2, 0)); 123112099Sjoerg } 123212099Sjoerg | direct_abs_decl T_LBRACK T_RBRACK { 123312099Sjoerg $$ = addarray($1, 0, 0); 123412099Sjoerg } 123512099Sjoerg | direct_abs_decl T_LBRACK constant T_RBRACK { 1236281168Spfg $$ = addarray($1, 1, toicon($3, 0)); 123712099Sjoerg } 123812099Sjoerg | abs_decl_param_list { 123912099Sjoerg $$ = addfunc(aname(), $1); 124012099Sjoerg popdecl(); 124112099Sjoerg blklev--; 124212099Sjoerg } 124312099Sjoerg | direct_abs_decl abs_decl_param_list { 124412099Sjoerg $$ = addfunc($1, $2); 124512099Sjoerg popdecl(); 124612099Sjoerg blklev--; 124712099Sjoerg } 124812099Sjoerg ; 124912099Sjoerg 1250281168Spfgnon_expr_stmnt: 125112099Sjoerg labeled_stmnt 125212099Sjoerg | comp_stmnt 125312099Sjoerg | selection_stmnt 125412099Sjoerg | iteration_stmnt 125512099Sjoerg | jump_stmnt { 125612099Sjoerg ftflg = 0; 125712099Sjoerg } 125812099Sjoerg | asm_stmnt 1259281168Spfg 1260281168Spfgstmnt: 1261281168Spfg expr_stmnt 1262281168Spfg | non_expr_stmnt 126312099Sjoerg ; 126412099Sjoerg 126512099Sjoerglabeled_stmnt: 126612099Sjoerg label stmnt 126712099Sjoerg ; 126812099Sjoerg 126912099Sjoerglabel: 127012099Sjoerg identifier T_COLON { 127112099Sjoerg symtyp = FLAB; 127212099Sjoerg label(T_NAME, getsym($1), NULL); 127312099Sjoerg } 127412099Sjoerg | T_CASE constant T_COLON { 127512099Sjoerg label(T_CASE, NULL, $2); 127612099Sjoerg ftflg = 1; 1277281168Spfg } 1278281168Spfg | T_CASE constant T_ELLIPSE constant T_COLON { 1279281168Spfg /* XXX: We don't fill all cases */ 1280281168Spfg label(T_CASE, NULL, $2); 1281281168Spfg ftflg = 1; 1282281168Spfg } 128312099Sjoerg | T_DEFAULT T_COLON { 128412099Sjoerg label(T_DEFAULT, NULL, NULL); 128512099Sjoerg ftflg = 1; 128612099Sjoerg } 128712099Sjoerg ; 128812099Sjoerg 128912099Sjoergcomp_stmnt: 1290281168Spfg comp_stmnt_lbrace declaration_list opt_stmnt_list comp_stmnt_rbrace 1291281168Spfg | comp_stmnt_lbrace opt_stmnt_list comp_stmnt_rbrace 129212099Sjoerg ; 129312099Sjoerg 1294281168Spfgcomp_stmnt_lbrace: 129512099Sjoerg T_LBRACE { 129612099Sjoerg blklev++; 129712099Sjoerg mblklev++; 129812099Sjoerg pushdecl(AUTO); 129912099Sjoerg } 130012099Sjoerg ; 130112099Sjoerg 1302281168Spfgcomp_stmnt_rbrace: 130312099Sjoerg T_RBRACE { 130412099Sjoerg popdecl(); 130512099Sjoerg freeblk(); 130612099Sjoerg mblklev--; 130712099Sjoerg blklev--; 130812099Sjoerg ftflg = 0; 130912099Sjoerg } 131012099Sjoerg ; 131112099Sjoerg 131212099Sjoergopt_stmnt_list: 131312099Sjoerg /* empty */ 131412099Sjoerg | stmnt_list 131512099Sjoerg ; 131612099Sjoerg 131712099Sjoergstmnt_list: 131891592Smarkm stmnt 131912099Sjoerg | stmnt_list stmnt { 132091592Smarkm RESTORE(); 132112099Sjoerg } 132291592Smarkm | stmnt_list error T_SEMI 132312099Sjoerg ; 132412099Sjoerg 132512099Sjoergexpr_stmnt: 132612099Sjoerg expr T_SEMI { 1327281168Spfg expr($1, 0, 0, 1); 132812099Sjoerg ftflg = 0; 132912099Sjoerg } 133012099Sjoerg | T_SEMI { 133112099Sjoerg ftflg = 0; 133212099Sjoerg } 133312099Sjoerg ; 133412099Sjoerg 1335281168Spfg/* 1336281168Spfg * The following two productions are used to implement 1337281168Spfg * ({ [[decl-list] stmt-list] }). 1338281168Spfg * XXX: This is not well tested. 1339281168Spfg */ 1340281168Spfgexpr_stmnt_val: 1341281168Spfg expr T_SEMI { 1342281168Spfg /* XXX: We should really do that only on the last name */ 1343281168Spfg if ($1->tn_op == NAME) 1344281168Spfg $1->tn_sym->s_used = 1; 1345281168Spfg $$ = $1; 1346281168Spfg expr($1, 0, 0, 0); 1347281168Spfg ftflg = 0; 1348281168Spfg } 1349281168Spfg | non_expr_stmnt { 1350281168Spfg $$ = getnode(); 1351281168Spfg $$->tn_type = gettyp(VOID); 1352281168Spfg } 1353281168Spfg ; 1354281168Spfg 1355281168Spfgexpr_stmnt_list: 1356281168Spfg expr_stmnt_val 1357281168Spfg | expr_stmnt_list expr_stmnt_val { 1358281168Spfg $$ = $2; 1359281168Spfg } 1360281168Spfg | expr_stmnt_list expr_stmnt_val 1361281168Spfg ; 1362281168Spfg 136312099Sjoergselection_stmnt: 136412099Sjoerg if_without_else { 136591592Smarkm SAVE(); 136612099Sjoerg if2(); 136712099Sjoerg if3(0); 136812099Sjoerg } 136912099Sjoerg | if_without_else T_ELSE { 137091592Smarkm SAVE(); 137112099Sjoerg if2(); 137212099Sjoerg } stmnt { 137391592Smarkm CLRWFLGS(); 137412099Sjoerg if3(1); 137512099Sjoerg } 137612099Sjoerg | if_without_else T_ELSE error { 137791592Smarkm CLRWFLGS(); 137812099Sjoerg if3(0); 137912099Sjoerg } 138012099Sjoerg | switch_expr stmnt { 138191592Smarkm CLRWFLGS(); 138212099Sjoerg switch2(); 138312099Sjoerg } 138412099Sjoerg | switch_expr error { 138591592Smarkm CLRWFLGS(); 138612099Sjoerg switch2(); 138712099Sjoerg } 138812099Sjoerg ; 138912099Sjoerg 139012099Sjoergif_without_else: 139112099Sjoerg if_expr stmnt 139212099Sjoerg | if_expr error 139312099Sjoerg ; 139412099Sjoerg 139512099Sjoergif_expr: 139612099Sjoerg T_IF T_LPARN expr T_RPARN { 139712099Sjoerg if1($3); 139891592Smarkm CLRWFLGS(); 139912099Sjoerg } 140012099Sjoerg ; 140112099Sjoerg 140212099Sjoergswitch_expr: 140312099Sjoerg T_SWITCH T_LPARN expr T_RPARN { 140412099Sjoerg switch1($3); 140591592Smarkm CLRWFLGS(); 140612099Sjoerg } 140712099Sjoerg ; 140812099Sjoerg 140991592Smarkmdo_stmnt: 141091592Smarkm do stmnt { 141191592Smarkm CLRWFLGS(); 141291592Smarkm } 141391592Smarkm ; 141491592Smarkm 141512099Sjoergiteration_stmnt: 141612099Sjoerg while_expr stmnt { 141791592Smarkm CLRWFLGS(); 141812099Sjoerg while2(); 141912099Sjoerg } 142012099Sjoerg | while_expr error { 142191592Smarkm CLRWFLGS(); 142212099Sjoerg while2(); 142312099Sjoerg } 142491592Smarkm | do_stmnt do_while_expr { 142591592Smarkm do2($2); 142612099Sjoerg ftflg = 0; 142712099Sjoerg } 142812099Sjoerg | do error { 142991592Smarkm CLRWFLGS(); 143012099Sjoerg do2(NULL); 143112099Sjoerg } 143212099Sjoerg | for_exprs stmnt { 143391592Smarkm CLRWFLGS(); 143412099Sjoerg for2(); 143512099Sjoerg } 143612099Sjoerg | for_exprs error { 143791592Smarkm CLRWFLGS(); 143812099Sjoerg for2(); 143912099Sjoerg } 144012099Sjoerg ; 144112099Sjoerg 144212099Sjoergwhile_expr: 144312099Sjoerg T_WHILE T_LPARN expr T_RPARN { 144412099Sjoerg while1($3); 144591592Smarkm CLRWFLGS(); 144612099Sjoerg } 144712099Sjoerg ; 144812099Sjoerg 144912099Sjoergdo: 145012099Sjoerg T_DO { 145112099Sjoerg do1(); 145212099Sjoerg } 145312099Sjoerg ; 145412099Sjoerg 145512099Sjoergdo_while_expr: 145612099Sjoerg T_WHILE T_LPARN expr T_RPARN T_SEMI { 145712099Sjoerg $$ = $3; 145812099Sjoerg } 145912099Sjoerg ; 146012099Sjoerg 146112099Sjoergfor_exprs: 146212099Sjoerg T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN { 146312099Sjoerg for1($3, $5, $7); 146491592Smarkm CLRWFLGS(); 146512099Sjoerg } 146612099Sjoerg ; 146712099Sjoerg 146812099Sjoergopt_expr: 146912099Sjoerg /* empty */ { 147012099Sjoerg $$ = NULL; 147112099Sjoerg } 147212099Sjoerg | expr { 147312099Sjoerg $$ = $1; 147412099Sjoerg } 147512099Sjoerg ; 147612099Sjoerg 147712099Sjoergjump_stmnt: 147812099Sjoerg goto identifier T_SEMI { 147912099Sjoerg dogoto(getsym($2)); 148012099Sjoerg } 148112099Sjoerg | goto error T_SEMI { 148212099Sjoerg symtyp = FVFT; 148312099Sjoerg } 148412099Sjoerg | T_CONTINUE T_SEMI { 148512099Sjoerg docont(); 148612099Sjoerg } 148712099Sjoerg | T_BREAK T_SEMI { 148812099Sjoerg dobreak(); 148912099Sjoerg } 149012099Sjoerg | T_RETURN T_SEMI { 149112099Sjoerg doreturn(NULL); 149212099Sjoerg } 149312099Sjoerg | T_RETURN expr T_SEMI { 149412099Sjoerg doreturn($2); 149512099Sjoerg } 149612099Sjoerg ; 149712099Sjoerg 149812099Sjoerggoto: 149912099Sjoerg T_GOTO { 150012099Sjoerg symtyp = FLAB; 150112099Sjoerg } 150212099Sjoerg ; 150312099Sjoerg 150412099Sjoergasm_stmnt: 150512099Sjoerg T_ASM T_LPARN read_until_rparn T_SEMI { 150612099Sjoerg setasm(); 150712099Sjoerg } 150812099Sjoerg | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI { 150912099Sjoerg setasm(); 151012099Sjoerg } 151112099Sjoerg | T_ASM error 151212099Sjoerg ; 151312099Sjoerg 151412099Sjoergread_until_rparn: 151512099Sjoerg /* empty */ { 151612099Sjoerg ignuptorp(); 151712099Sjoerg } 151812099Sjoerg ; 151912099Sjoerg 152012099Sjoergdeclaration_list: 152112099Sjoerg declaration { 152291592Smarkm CLRWFLGS(); 152312099Sjoerg } 152412099Sjoerg | declaration_list declaration { 152591592Smarkm CLRWFLGS(); 152612099Sjoerg } 152712099Sjoerg ; 152812099Sjoerg 152912099Sjoergconstant: 153012099Sjoerg expr %prec T_COMMA { 153112099Sjoerg $$ = $1; 153212099Sjoerg } 153312099Sjoerg ; 153412099Sjoerg 153512099Sjoergexpr: 153612099Sjoerg expr T_MULT expr { 153712099Sjoerg $$ = build(MULT, $1, $3); 153812099Sjoerg } 153912099Sjoerg | expr T_DIVOP expr { 154012099Sjoerg $$ = build($2, $1, $3); 154112099Sjoerg } 154212099Sjoerg | expr T_ADDOP expr { 154312099Sjoerg $$ = build($2, $1, $3); 154412099Sjoerg } 154512099Sjoerg | expr T_SHFTOP expr { 154612099Sjoerg $$ = build($2, $1, $3); 154712099Sjoerg } 154812099Sjoerg | expr T_RELOP expr { 154912099Sjoerg $$ = build($2, $1, $3); 155012099Sjoerg } 155112099Sjoerg | expr T_EQOP expr { 155212099Sjoerg $$ = build($2, $1, $3); 155312099Sjoerg } 155412099Sjoerg | expr T_AND expr { 155512099Sjoerg $$ = build(AND, $1, $3); 155612099Sjoerg } 155712099Sjoerg | expr T_XOR expr { 155812099Sjoerg $$ = build(XOR, $1, $3); 155912099Sjoerg } 156012099Sjoerg | expr T_OR expr { 156112099Sjoerg $$ = build(OR, $1, $3); 156212099Sjoerg } 156312099Sjoerg | expr T_LOGAND expr { 156412099Sjoerg $$ = build(LOGAND, $1, $3); 156512099Sjoerg } 156612099Sjoerg | expr T_LOGOR expr { 156712099Sjoerg $$ = build(LOGOR, $1, $3); 156812099Sjoerg } 156912099Sjoerg | expr T_QUEST expr T_COLON expr { 157012099Sjoerg $$ = build(QUEST, $1, build(COLON, $3, $5)); 157112099Sjoerg } 157212099Sjoerg | expr T_ASSIGN expr { 157312099Sjoerg $$ = build(ASSIGN, $1, $3); 157412099Sjoerg } 157512099Sjoerg | expr T_OPASS expr { 157612099Sjoerg $$ = build($2, $1, $3); 157712099Sjoerg } 157812099Sjoerg | expr T_COMMA expr { 157912099Sjoerg $$ = build(COMMA, $1, $3); 158012099Sjoerg } 158112099Sjoerg | term { 158212099Sjoerg $$ = $1; 158312099Sjoerg } 158412099Sjoerg ; 158512099Sjoerg 158612099Sjoergterm: 158712099Sjoerg T_NAME { 158891592Smarkm /* XXX really necessary? */ 158912099Sjoerg if (yychar < 0) 159012099Sjoerg yychar = yylex(); 159112099Sjoerg $$ = getnnode(getsym($1), yychar); 159212099Sjoerg } 159312099Sjoerg | string { 159412099Sjoerg $$ = getsnode($1); 159512099Sjoerg } 159612099Sjoerg | T_CON { 159712099Sjoerg $$ = getcnode(gettyp($1->v_tspec), $1); 159812099Sjoerg } 159912099Sjoerg | T_LPARN expr T_RPARN { 160012099Sjoerg if ($2 != NULL) 160112099Sjoerg $2->tn_parn = 1; 160212099Sjoerg $$ = $2; 160312099Sjoerg } 1604281168Spfg | T_LPARN comp_stmnt_lbrace declaration_list expr_stmnt_list { 1605281168Spfg blklev--; 1606281168Spfg mblklev--; 1607281168Spfg initsym = mktempsym(duptyp($4->tn_type)); 1608281168Spfg mblklev++; 1609281168Spfg blklev++; 1610281168Spfg gnuism(320); 1611281168Spfg } comp_stmnt_rbrace T_RPARN { 1612281168Spfg $$ = getnnode(initsym, 0); 1613281168Spfg } 1614281168Spfg | T_LPARN comp_stmnt_lbrace expr_stmnt_list { 1615281168Spfg blklev--; 1616281168Spfg mblklev--; 1617281168Spfg initsym = mktempsym($3->tn_type); 1618281168Spfg mblklev++; 1619281168Spfg blklev++; 1620281168Spfg gnuism(320); 1621281168Spfg } comp_stmnt_rbrace T_RPARN { 1622281168Spfg $$ = getnnode(initsym, 0); 1623281168Spfg } 162412099Sjoerg | term T_INCDEC { 162512099Sjoerg $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL); 162612099Sjoerg } 162712099Sjoerg | T_INCDEC term { 162812099Sjoerg $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL); 162912099Sjoerg } 163012099Sjoerg | T_MULT term { 163112099Sjoerg $$ = build(STAR, $2, NULL); 163212099Sjoerg } 163312099Sjoerg | T_AND term { 163412099Sjoerg $$ = build(AMPER, $2, NULL); 163512099Sjoerg } 163612099Sjoerg | T_UNOP term { 163712099Sjoerg $$ = build($1, $2, NULL); 163812099Sjoerg } 163912099Sjoerg | T_ADDOP term { 164012099Sjoerg if (tflag && $1 == PLUS) { 164112099Sjoerg /* unary + is illegal in traditional C */ 164212099Sjoerg warning(100); 164312099Sjoerg } 164412099Sjoerg $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL); 164512099Sjoerg } 164612099Sjoerg | term T_LBRACK expr T_RBRACK { 164712099Sjoerg $$ = build(STAR, build(PLUS, $1, $3), NULL); 164812099Sjoerg } 164912099Sjoerg | term T_LPARN T_RPARN { 165012099Sjoerg $$ = funccall($1, NULL); 165112099Sjoerg } 165212099Sjoerg | term T_LPARN func_arg_list T_RPARN { 165312099Sjoerg $$ = funccall($1, $3); 165412099Sjoerg } 165512099Sjoerg | term point_or_arrow T_NAME { 165612099Sjoerg if ($1 != NULL) { 165712099Sjoerg sym_t *msym; 165812099Sjoerg /* XXX strmemb should be integrated in build() */ 165912099Sjoerg if ($2 == ARROW) { 166012099Sjoerg /* must to this before strmemb is called */ 166112099Sjoerg $1 = cconv($1); 166212099Sjoerg } 166312099Sjoerg msym = strmemb($1, $2, getsym($3)); 166412099Sjoerg $$ = build($2, $1, getnnode(msym, 0)); 166512099Sjoerg } else { 166612099Sjoerg $$ = NULL; 166712099Sjoerg } 166812099Sjoerg } 166912099Sjoerg | T_SIZEOF term %prec T_SIZEOF { 167012099Sjoerg if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL) 167112099Sjoerg chkmisc($2, 0, 0, 0, 0, 0, 1); 167212099Sjoerg } 167312099Sjoerg | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF { 167412099Sjoerg $$ = bldszof($3); 167512099Sjoerg } 167612099Sjoerg | T_LPARN type_name T_RPARN term %prec T_UNOP { 167712099Sjoerg $$ = cast($4, $2); 167812099Sjoerg } 1679281168Spfg | T_LPARN type_name T_RPARN %prec T_UNOP { 1680281168Spfg sym_t *tmp = mktempsym($2); 1681281168Spfg idecl(tmp, 1, NULL); 1682281168Spfg } init_lbrace init_expr_list init_rbrace { 1683281168Spfg if (!Sflag) 1684281168Spfg gnuism(319); 1685281168Spfg $$ = getnnode(initsym, 0); 1686281168Spfg } 168712099Sjoerg ; 168812099Sjoerg 168912099Sjoergstring: 169012099Sjoerg T_STRING { 169112099Sjoerg $$ = $1; 169212099Sjoerg } 169312099Sjoerg | T_STRING string2 { 169412099Sjoerg $$ = catstrg($1, $2); 169512099Sjoerg } 169612099Sjoerg ; 169712099Sjoerg 169812099Sjoergstring2: 169912099Sjoerg T_STRING { 170012099Sjoerg if (tflag) { 170112099Sjoerg /* concatenated strings are illegal in traditional C */ 170212099Sjoerg warning(219); 170312099Sjoerg } 170412099Sjoerg $$ = $1; 170512099Sjoerg } 170612099Sjoerg | string2 T_STRING { 170712099Sjoerg $$ = catstrg($1, $2); 170812099Sjoerg } 170912099Sjoerg ; 171012099Sjoerg 171112099Sjoergfunc_arg_list: 171212099Sjoerg expr %prec T_COMMA { 171312099Sjoerg $$ = funcarg(NULL, $1); 171412099Sjoerg } 171512099Sjoerg | func_arg_list T_COMMA expr { 171612099Sjoerg $$ = funcarg($1, $3); 171712099Sjoerg } 171812099Sjoerg ; 171912099Sjoerg 172012099Sjoergpoint_or_arrow: 172112099Sjoerg T_STROP { 172212099Sjoerg symtyp = FMOS; 172312099Sjoerg $$ = $1; 172412099Sjoerg } 172512099Sjoerg ; 172612099Sjoerg 1727281168Spfgpoint: 1728281168Spfg T_STROP { 1729281168Spfg if ($1 != POINT) 1730281168Spfg error(249); 1731281168Spfg } 1732281168Spfg ; 1733281168Spfg 173412099Sjoergidentifier: 173512099Sjoerg T_NAME { 173612099Sjoerg $$ = $1; 173712099Sjoerg } 173812099Sjoerg | T_TYPENAME { 173912099Sjoerg $$ = $1; 174012099Sjoerg } 174112099Sjoerg ; 174212099Sjoerg 174312099Sjoerg%% 174412099Sjoerg 174512099Sjoerg/* ARGSUSED */ 174612099Sjoergint 174791592Smarkmyyerror(char *msg) 174812099Sjoerg{ 174912099Sjoerg error(249); 175012099Sjoerg if (++sytxerr >= 5) 175112099Sjoerg norecover(); 175212099Sjoerg return (0); 175312099Sjoerg} 175412099Sjoerg 1755115967Sobrienstatic __inline int uq_gt(uint64_t, uint64_t); 1756115967Sobrienstatic __inline int 175791592Smarkmuq_gt(uint64_t a, uint64_t b) 175891592Smarkm{ 175991592Smarkm 176091592Smarkm return (a > b); 176191592Smarkm} 176291592Smarkm 1763115967Sobrienstatic __inline int q_gt(int64_t, int64_t); 1764115967Sobrienstatic __inline int 176591592Smarkmq_gt(int64_t a, int64_t b) 176691592Smarkm{ 176791592Smarkm 176891592Smarkm return (a > b); 176991592Smarkm} 177091592Smarkm 177191592Smarkm#define q_lt(a, b) q_gt(b, a) 177291592Smarkm 177312099Sjoerg/* 177412099Sjoerg * Gets a node for a constant and returns the value of this constant 177512099Sjoerg * as integer. 177612099Sjoerg * Is the node not constant or too large for int or of type float, 177712099Sjoerg * a warning will be printed. 177812099Sjoerg * 177912099Sjoerg * toicon() should be used only inside declarations. If it is used in 178012099Sjoerg * expressions, it frees the memory used for the expression. 178112099Sjoerg */ 178212099Sjoergstatic int 1783281168Spfgtoicon(tnode_t *tn, int required) 178412099Sjoerg{ 178512099Sjoerg int i; 178612099Sjoerg tspec_t t; 178712099Sjoerg val_t *v; 178812099Sjoerg 1789281168Spfg v = constant(tn, required); 179012099Sjoerg 179112099Sjoerg /* 179212099Sjoerg * Abstract declarations are used inside expression. To free 179312099Sjoerg * the memory would be a fatal error. 179412099Sjoerg */ 179512099Sjoerg if (dcs->d_ctx != ABSTRACT) 179612099Sjoerg tfreeblk(); 179712099Sjoerg 179812099Sjoerg if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) { 179912099Sjoerg i = (int)v->v_ldbl; 180012099Sjoerg /* integral constant expression expected */ 180112099Sjoerg error(55); 180212099Sjoerg } else { 180312099Sjoerg i = (int)v->v_quad; 180412099Sjoerg if (isutyp(t)) { 180591592Smarkm if (uq_gt((uint64_t)v->v_quad, 180691592Smarkm (uint64_t)INT_MAX)) { 180712099Sjoerg /* integral constant too large */ 180812099Sjoerg warning(56); 180912099Sjoerg } 181012099Sjoerg } else { 181191592Smarkm if (q_gt(v->v_quad, (int64_t)INT_MAX) || 181291592Smarkm q_lt(v->v_quad, (int64_t)INT_MIN)) { 181326582Stegge /* integral constant too large */ 181426582Stegge warning(56); 181526582Stegge } 181612099Sjoerg } 181712099Sjoerg } 181812099Sjoerg free(v); 181912099Sjoerg return (i); 182012099Sjoerg} 182112099Sjoerg 182212099Sjoergstatic void 182391592Smarkmidecl(sym_t *decl, int initflg, sbuf_t *rename) 182412099Sjoerg{ 182591592Smarkm char *s; 182691592Smarkm 182712099Sjoerg initerr = 0; 182812099Sjoerg initsym = decl; 182912099Sjoerg 183012099Sjoerg switch (dcs->d_ctx) { 183112099Sjoerg case EXTERN: 183291592Smarkm if (rename != NULL) { 183391592Smarkm if (decl->s_rename != NULL) 1834281168Spfg LERROR("idecl()"); 183591592Smarkm 183691592Smarkm s = getlblk(1, rename->sb_len + 1); 183791592Smarkm (void)memcpy(s, rename->sb_name, rename->sb_len + 1); 183891592Smarkm decl->s_rename = s; 183991592Smarkm freeyyv(&rename, T_NAME); 184091592Smarkm } 184112099Sjoerg decl1ext(decl, initflg); 184212099Sjoerg break; 184312099Sjoerg case ARG: 184491592Smarkm if (rename != NULL) { 184591592Smarkm /* symbol renaming can't be used on function arguments */ 184691592Smarkm error(310); 184791592Smarkm freeyyv(&rename, T_NAME); 184891592Smarkm break; 184991592Smarkm } 185012099Sjoerg (void)decl1arg(decl, initflg); 185112099Sjoerg break; 185212099Sjoerg case AUTO: 185391592Smarkm if (rename != NULL) { 185491592Smarkm /* symbol renaming can't be used on automatic variables */ 185591592Smarkm error(311); 185691592Smarkm freeyyv(&rename, T_NAME); 185791592Smarkm break; 185891592Smarkm } 185912099Sjoerg decl1loc(decl, initflg); 186012099Sjoerg break; 186112099Sjoerg default: 1862281168Spfg LERROR("idecl()"); 186312099Sjoerg } 186412099Sjoerg 186512099Sjoerg if (initflg && !initerr) 186612099Sjoerg prepinit(); 186712099Sjoerg} 186812099Sjoerg 186912099Sjoerg/* 187012099Sjoerg * Discard all input tokens up to and including the next 187112099Sjoerg * unmatched right paren 187212099Sjoerg */ 187391592Smarkmstatic void 187491592Smarkmignuptorp(void) 187512099Sjoerg{ 187612099Sjoerg int level; 187712099Sjoerg 187812099Sjoerg if (yychar < 0) 187912099Sjoerg yychar = yylex(); 188012099Sjoerg freeyyv(&yylval, yychar); 188112099Sjoerg 188212099Sjoerg level = 1; 188312099Sjoerg while (yychar != T_RPARN || --level > 0) { 188412099Sjoerg if (yychar == T_LPARN) { 188512099Sjoerg level++; 188612099Sjoerg } else if (yychar <= 0) { 188712099Sjoerg break; 188812099Sjoerg } 188912099Sjoerg freeyyv(&yylval, yychar = yylex()); 189012099Sjoerg } 189112099Sjoerg 189212099Sjoerg yyclearin; 189312099Sjoerg} 1894