PageRenderTime 25ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/src/netbsd/src/usr.bin/xlint/lint1/cgram.y

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