1 /*
2 **      cdecl -- C gibberish translator
3 **      src/parser.y
4 **
5 **      Copyright (C) 2017-2021  Paul J. Lucas, et al.
6 **
7 **      This program is free software: you can redistribute it and/or modify
8 **      it under the terms of the GNU General Public License as published by
9 **      the Free Software Foundation, either version 3 of the License, or
10 **      (at your option) any later version.
11 **
12 **      This program is distributed in the hope that it will be useful,
13 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
14 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 **      GNU General Public License for more details.
16 **
17 **      You should have received a copy of the GNU General Public License
18 **      along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 /**
22  * @file
23  * Defines helper macros, data structures, variables, functions, and the
24  * grammar for C/C++ declarations.
25  */
26 
27 /** @cond DOXYGEN_IGNORE */
28 
29 %expect 17
30 
31 %{
32 /** @endcond */
33 
34 // local
35 #include "pjl_config.h"                 /* must go first */
36 #include "c_ast.h"
37 #include "c_ast_util.h"
38 #include "c_keyword.h"
39 #include "c_lang.h"
40 #include "c_operator.h"
41 #include "c_sglob.h"
42 #include "c_sname.h"
43 #include "c_type.h"
44 #include "c_typedef.h"
45 #include "cdecl.h"
46 #include "cdecl_keyword.h"
47 #include "check.h"
48 #include "color.h"
49 #ifdef ENABLE_CDECL_DEBUG
50 #include "dump.h"
51 #endif /* ENABLE_CDECL_DEBUG */
52 #include "did_you_mean.h"
53 #include "english.h"
54 #include "gibberish.h"
55 #include "help.h"
56 #include "lexer.h"
57 #include "literals.h"
58 #include "options.h"
59 #include "print.h"
60 #include "set_options.h"
61 #include "slist.h"
62 #include "types.h"
63 #include "util.h"
64 
65 /// @cond DOXYGEN_IGNORE
66 
67 // standard
68 #include <assert.h>
69 #include <stdarg.h>
70 #include <stdbool.h>
71 #include <stdio.h>
72 #include <stdlib.h>
73 
74 #ifdef __GNUC__
75 // Silence these warnings for Bison-generated code.
76 #pragma GCC diagnostic ignored "-Wconversion"
77 #pragma GCC diagnostic ignored "-Wunreachable-code"
78 #endif /* __GNUC__ */
79 
80 // Developer aid for tracing when Bison %destructors are called.
81 #if 0
82 #define DTRACE                    EPRINTF( "%d: destructor\n", __LINE__ )
83 #else
84 #define DTRACE                    NO_OP
85 #endif
86 
87 #ifdef ENABLE_CDECL_DEBUG
88 #define IF_DEBUG(...) \
89   BLOCK( if ( opt_cdecl_debug ) { __VA_ARGS__ } )
90 #else
91 #define IF_DEBUG(...)             /* nothing */
92 #endif /* ENABLE_CDECL_DEBUG */
93 
94 /// @endcond
95 
96 ///////////////////////////////////////////////////////////////////////////////
97 
98 /**
99  * @defgroup parser-group Parser
100  * Helper macros, data structures, variables, functions, and the grammar for
101  * C/C++ declarations.
102  * @{
103  */
104 
105 /**
106  * Calls c_ast_check(): if the check fails, calls #PARSE_ABORT().
107  *
108  * @param AST The AST to check.
109  */
110 #define C_AST_CHECK(AST) \
111   BLOCK( if ( !c_ast_check( AST ) ) PARSE_ABORT(); )
112 
113 /**
114  * Calls c_type_add(): if adding the type fails, calls #PARSE_ABORT().
115  *
116  * @param DST_TYPE The \ref c_type to add to.
117  * @param NEW_TYPE The \ref c_type to add.
118  * @param NEW_LOC The source location of \a NEW_TYPE.
119  *
120  * @sa #C_TID_ADD()
121  * @sa #C_TYPE_ADD_TID()
122  */
123 #define C_TYPE_ADD(DST_TYPE,NEW_TYPE,NEW_LOC) BLOCK( \
124   if ( !c_type_add( (DST_TYPE), (NEW_TYPE), &(NEW_LOC) ) ) PARSE_ABORT(); )
125 
126 /**
127  * Calls c_type_add_tid(): if adding the type fails, calls #PARSE_ABORT().
128  *
129  * @param DST_TYPE The \ref c_type to add to.
130  * @param NEW_TID The \ref c_tid_t to add.
131  * @param NEW_LOC The source location of \a NEW_TID.
132  *
133  * @sa #C_TID_ADD()
134  * @sa #C_TYPE_ADD()
135  */
136 #define C_TYPE_ADD_TID(DST_TYPE,NEW_TID,NEW_LOC) BLOCK( \
137   if ( !c_type_add_tid( (DST_TYPE), (NEW_TID), &(NEW_LOC) ) ) PARSE_ABORT(); )
138 
139 /**
140  * Calls c_tid_add(): if adding the type fails, calls #PARSE_ABORT().
141  *
142  * @param DST_TID The \ref c_tid_t to add to.
143  * @param NEW_TID The \ref c_tid_t to add.
144  * @param NEW_LOC The source location of \a NEW_TID.
145  *
146  * @sa #C_TYPE_ADD()
147  * @sa #C_TYPE_ADD_TID()
148  */
149 #define C_TID_ADD(DST_TID,NEW_TID,NEW_LOC) BLOCK( \
150   if ( !c_tid_add( (DST_TID), (NEW_TID), &(NEW_LOC) ) ) PARSE_ABORT(); )
151 
152 /**
153  * Calls fl_is_nested_type_ok(): if it returns `false`, calls #PARSE_ABORT().
154  *
155  * @param TYPE_LOC The location of the type declaration.
156  */
157 #define CHECK_NESTED_TYPE_OK(TYPE_LOC) BLOCK( \
158   if ( !fl_is_nested_type_ok( __FILE__, __LINE__, TYPE_LOC ) ) PARSE_ABORT(); )
159 
160 /**
161  * Calls #elaborate_error_dym() with a \ref dym_kind_t of #DYM_NONE.
162  *
163  * @param ... Arguments passed to fl_elaborate_error().
164  *
165  * @note This must be used _only_ after an `error` token, e.g.:
166  * @code
167  *  | Y_DEFINE error
168  *    {
169  *      elaborate_error( "name expected" );
170  *    }
171  * @endcode
172  *
173  * @sa elaborate_error_dym()
174  * @sa keyword_expected()
175  * @sa punct_expected()
176  */
177 #define elaborate_error(...) \
178   elaborate_error_dym( DYM_NONE, __VA_ARGS__ )
179 
180 /**
181  * Calls fl_elaborate_error() followed by #PARSE_ABORT().
182  *
183  * @param DYM_KINDS The bitwise-or of the kind(s) of things possibly meant.
184  * @param ... Arguments passed to fl_elaborate_error().
185  *
186  * @note
187  * This must be used _only_ after an `error` token, e.g.:
188  * @code
189  *  | error
190  *    {
191  *      elaborate_error_dym( DYM_COMMANDS, "unexpected token" );
192  *    }
193  * @endcode
194  *
195  * @sa elaborate_error()
196  * @sa keyword_expected()
197  * @sa punct_expected()
198  */
199 #define elaborate_error_dym(DYM_KINDS,...) BLOCK( \
200   fl_elaborate_error( __FILE__, __LINE__, (DYM_KINDS), __VA_ARGS__ ); PARSE_ABORT(); )
201 
202 /**
203  * Calls fl_keyword_expected() followed by #PARSE_ABORT().
204  *
205  * @param KEYWORD A keyword literal.
206  *
207  * @note
208  * This must be used _only_ after an `error` token, e.g.:
209  * @code
210  *  : Y_VIRTUAL
211  *  | error
212  *    {
213  *      keyword_expected( L_VIRTUAL );
214  *    }
215  * @endcode
216  *
217  * @sa elaborate_error()
218  * @sa elaborate_error_dym()
219  * @sa punct_expected()
220  */
221 #define keyword_expected(KEYWORD) BLOCK ( \
222   fl_keyword_expected( __FILE__, __LINE__, (KEYWORD) ); PARSE_ABORT(); )
223 
224 /**
225  * Aborts the current parse (presumably after an error message has been
226  * printed).
227  */
228 #define PARSE_ABORT()             BLOCK( parse_cleanup( true ); YYABORT; )
229 
230 /**
231  * Calls fl_punct_expected() followed by #PARSE_ABORT().
232  *
233  * @param PUNCT The punctuation character that was expected.
234  *
235  * @note
236  * This must be used _only_ after an `error` token, e.g.:
237  * @code
238  *  : ','
239  *  | error
240  *    {
241  *      punct_expected( ',' );
242  *    }
243  * @endcode
244  *
245  * @sa elaborate_error()
246  * @sa elaborate_error_dym()
247  * @sa keyword_expected()
248  */
249 #define punct_expected(PUNCT) BLOCK( \
250   fl_punct_expected( __FILE__, __LINE__, (PUNCT) ); PARSE_ABORT(); )
251 
252 /**
253  * Show all (as opposed to only those that are supported in the current
254  * language) predefined, user, or both types.
255  */
256 #define SHOW_ALL_TYPES            0x10u
257 
258 /**
259 * Show only predefined types that are valid in the current language.
260 */
261 #define SHOW_PREDEFINED_TYPES     (1u << 0)
262 
263 /**
264  * Show only user-defined types that were defined in the current language or
265  * earlier.
266  */
267 #define SHOW_USER_TYPES           (1u << 1)
268 
269 /** @} */
270 
271 ///////////////////////////////////////////////////////////////////////////////
272 
273 /**
274  * @defgroup parser-dump-group Debugging Macros
275  * Macros that are used to dump a trace during parsing when \ref
276  * opt_cdecl_debug is `true`.
277  * @ingroup parser-group
278  * @{
279  */
280 
281 /**
282  * Dumps a comma followed by a newline the _second_ and subsequent times it's
283  * called.  It's used to separate items being dumped.
284  */
285 #define DUMP_COMMA \
286   BLOCK( if ( true_or_set( &dump_comma ) ) PUTS( ",\n" ); )
287 
288 /**
289  * Dumps an AST.
290  *
291  * @param KEY The key name to print.
292  * @param AST The AST to dump.
293  *
294  * @sa #DUMP_AST_LIST()
295  */
296 #define DUMP_AST(KEY,AST) IF_DEBUG( \
297   if ( (AST) != NULL ) { DUMP_COMMA; c_ast_dump( (AST), 1, (KEY), stdout ); } )
298 
299 /**
300  * Dumps an s_list of AST.
301  *
302  * @param KEY The key name to print.
303  * @param AST_LIST The \ref slist of AST to dump.
304  *
305  * @sa #DUMP_AST()
306  */
307 #define DUMP_AST_LIST(KEY,AST_LIST) IF_DEBUG( \
308   DUMP_COMMA; PUTS( "  " KEY " = " );         \
309   c_ast_list_dump( &(AST_LIST), 1, stdout ); )
310 
311 /**
312  * Dumps a `bool`.
313  *
314  * @param KEY The key name to print.
315  * @param BOOL The `bool` to dump.
316  */
317 #define DUMP_BOOL(KEY,BOOL)  IF_DEBUG(  \
318   DUMP_COMMA; PUTS( "  " KEY " = " );   \
319   bool_dump( BOOL, stdout ); )
320 
321 /**
322  * Ends a dump block.
323  *
324  * @sa #DUMP_START()
325  */
326 #define DUMP_END()                IF_DEBUG( PUTS( "\n}\n" ); )
327 
328 /**
329  * Dumps an integer.
330  *
331  * @param KEY The key name to print.
332  * @param NUM The integer to dump.
333  *
334  * @sa #DUMP_STR()
335  */
336 #define DUMP_INT(KEY,NUM) \
337   IF_DEBUG( DUMP_COMMA; FPRINTF( stdout, "  " KEY " = %d", (int)(NUM) ); )
338 
339 /**
340  * Dumps a scoped name.
341  *
342  * @param KEY The key name to print.
343  * @param SNAME The scoped name to dump.
344  *
345  * @sa #DUMP_SNAME_LIST()
346  * @sa #DUMP_STR()
347  */
348 #define DUMP_SNAME(KEY,SNAME) IF_DEBUG( \
349   DUMP_COMMA; PUTS( "  " KEY " = " );   \
350   c_sname_dump( &(SNAME), stdout ); )
351 
352 /**
353  * Dumps a list of scoped names.
354  *
355  * @param KEY The key name to print.
356  * @param LIST The list of scoped names to dump.
357  *
358  * @sa #DUMP_SNAME()
359  */
360 #define DUMP_SNAME_LIST(KEY,LIST) IF_DEBUG( \
361   DUMP_COMMA; PUTS( "  " KEY " = " );       \
362   c_sname_list_dump( &(LIST), stdout ); )
363 
364 #ifdef ENABLE_CDECL_DEBUG
365 /**
366  * @def DUMP_START
367  *
368  * Starts a dump block.  The dump block _must_ end with #DUMP_END().  If a rule
369  * has a result, it should be dumped as the final thing before the #DUMP_END()
370  * repeating the name of the rule, e.g.:
371  * @code
372  *  DUMP_START( "rule",                 // <-- This rule name ...
373  *              "subrule_1 name subrule_2" );
374  *  DUMP_AST( "subrule_1", $1 );
375  *  DUMP_STR( "name", $2 );
376  *  DUMP_AST( "subrule_2", $3 );
377  *  // ...
378  *  DUMP_AST( "rule", $$ );             // <-- ... is repeated here.
379  *  DUMP_END();
380  * @endcode
381  *
382  * Whenever possible, an entire dump block should be completed before any
383  * actions are taken as a result of a failed semantic check or other error
384  * (typically, calling print_error() and #PARSE_ABORT()) so that the entire
385  * block is dumped for debugging purposes first. If necessary, set a flag
386  * within the dump block, then check it after, e.g.:
387  * @code
388  *  DUMP_START( "rule", "subrule_1 name subrule_2" );
389  *  DUMP_AST( "subrule_1", $1 );
390  *  DUMP_STR( "name", $2 );
391  *  DUMP_AST( "subrule_2", $3 );
392  *
393  *  bool ok = true;
394  *  if ( semantic_check_failed ) {
395  *    // ...
396  *    ok = false;
397  *  }
398  *
399  *  DUMP_AST( "rule", $$ );
400  *  DUMP_END();
401  *
402  *  if ( !ok ) {
403  *    print_error( &@1, "...\n" );
404  *    PARSE_ABORT();
405  *  }
406  * @endcode
407  *
408  * @param NAME The grammar production name.
409  * @param PROD The grammar production rule.
410  *
411  * @sa #DUMP_AST
412  * @sa #DUMP_AST_LIST
413  * @sa #DUMP_BOOL
414  * @sa #DUMP_END
415  * @sa #DUMP_INT
416  * @sa #DUMP_SNAME
417  * @sa #DUMP_STR
418  * @sa #DUMP_TID
419  * @sa #DUMP_TYPE
420  */
421 #define DUMP_START(NAME,PROD)                           \
422   bool dump_comma = false;                              \
423   IF_DEBUG( PUTS( "\n" NAME " ::= " PROD " = {\n" ); )
424 #else
425 #define DUMP_START(NAME,PROD)     /* nothing */
426 #endif
427 
428 /**
429  * Dumps a C string.
430  *
431  * @param KEY The key name to print.
432  * @param STR The C string to dump.
433  *
434  * @sa #DUMP_INT()
435  * @sa #DUMP_SNAME()
436  */
437 #define DUMP_STR(KEY,STR) IF_DEBUG( \
438   DUMP_COMMA; PUTS( "  " KEY " = " ); str_dump( (STR), stdout ); )
439 
440 /**
441  * Dumps a \ref c_tid_t.
442  *
443  * @param KEY The key name to print.
444  * @param TID The \ref c_tid_t to dump.
445  *
446  * @sa #DUMP_TYPE()
447  */
448 #define DUMP_TID(KEY,TID) IF_DEBUG( \
449   DUMP_COMMA; PUTS( "  " KEY " = " ); c_tid_dump( (TID), stdout ); )
450 
451 /**
452  * Dumps a \ref c_type.
453  *
454  * @param KEY The key name to print.
455  * @param TYPE The \ref c_type to dump.
456  *
457  * @sa #DUMP_TID()
458  */
459 #define DUMP_TYPE(KEY,TYPE) IF_DEBUG( \
460   DUMP_COMMA; PUTS( "  " KEY " = " ); c_type_dump( &(TYPE), stdout ); )
461 
462 /** @} */
463 
464 ///////////////////////////////////////////////////////////////////////////////
465 
466 /**
467  * @addtogroup parser-group
468  * @{
469  */
470 
471 /**
472  * Inherited attributes.
473  */
474 struct in_attr {
475   c_alignas_t   align;            ///< Alignment, if any.
476   c_sname_t     current_scope;    ///< C++ only: current scope, if any.
477   c_ast_list_t  type_ast_stack;   ///< Type AST stack.
478   c_ast_list_t  typedef_ast_list; ///< AST nodes of `typedef` being declared.
479   c_ast_t      *typedef_type_ast; ///< AST of `typedef` being declared.
480   bool          typename;         ///< C++ only: `typename` specified?
481 };
482 typedef struct in_attr in_attr_t;
483 
484 /**
485  * Qualifier and its source location.
486  */
487 struct c_qualifier {
488   c_tid_t qual_stid;                    ///< E.g., #TS_CONST or #TS_VOLATILE.
489   c_loc_t loc;                          ///< Qualifier source location.
490 };
491 typedef struct c_qualifier c_qualifier_t;
492 
493 /**
494  * Information for show_type_visitor().
495  */
496 struct show_type_info {
497   unsigned      show_which;             ///< Predefined, user, or both?
498   c_gib_flags_t gib_flags;              ///< Gibberish flags.
499   c_sglob_t     sglob;                  ///< Scoped glob to match, if any.
500 };
501 typedef struct show_type_info show_type_info_t;
502 
503 // local functions
504 PJL_WARN_UNUSED_RESULT
505 static bool slist_node_is_ast_placeholder( void* );
506 
507 // local variables
508 static c_ast_depth_t  ast_depth;        ///< Parentheses nesting depth.
509 static slist_t        decl_ast_list;    ///< List of ASTs being declared.
510 static c_ast_list_t   gc_ast_list;      ///< c_ast nodes freed after parse.
511 static in_attr_t      in_attr;          ///< Inherited attributes.
512 static c_ast_list_t   typedef_ast_list; ///< c_ast nodes for `typedef`s.
513 
514 ////////// inline functions ///////////////////////////////////////////////////
515 
516 /**
517  * Garbage-collect the AST nodes on \a ast_list.
518  *
519  * @param ast_list The AST list to free.
520  */
c_ast_list_gc(c_ast_list_t * ast_list)521 static inline void c_ast_list_gc( c_ast_list_t *ast_list ) {
522   slist_cleanup( ast_list, (slist_free_fn_t)&c_ast_free );
523 }
524 
525 /**
526  * Creates a new AST and adds it to \ref gc_ast_list.
527  *
528  * @param kind The kind of AST to create.
529  * @param loc A pointer to the token location data.
530  * @return Returns a pointer to a new AST.
531  *
532  * @sa c_ast_pair_new_gc()
533  */
534 PJL_WARN_UNUSED_RESULT
c_ast_new_gc(c_ast_kind_t kind,c_loc_t const * loc)535 static inline c_ast_t* c_ast_new_gc( c_ast_kind_t kind, c_loc_t const *loc ) {
536   return c_ast_new( kind, ast_depth, loc, &gc_ast_list );
537 }
538 
539 /**
540  * Set our mode to deciphering gibberish into English.
541  */
gibberish_to_english(void)542 static inline void gibberish_to_english( void ) {
543   cdecl_mode = CDECL_GIBBERISH_TO_ENGLISH;
544   lexer_find &= ~LEXER_FIND_CDECL_KEYWORDS;
545 }
546 
547 /**
548  * Peeks at the type AST at the top of the
549  * \ref in_attr.type_ast_stack "type AST inherited attribute stack".
550  *
551  * @return Returns said AST.
552  *
553  * @sa ia_type_ast_pop()
554  * @sa ia_type_ast_push()
555  */
556 PJL_WARN_UNUSED_RESULT
ia_type_ast_peek(void)557 static inline c_ast_t* ia_type_ast_peek( void ) {
558   return slist_peek_head( &in_attr.type_ast_stack );
559 }
560 
561 /**
562  * Pops a type AST from the
563  * \ref in_attr.type_ast_stack "type AST inherited attribute stack".
564  *
565  * @return Returns said AST.
566  *
567  * @sa ia_type_ast_peek()
568  * @sa ia_type_ast_push()
569  */
570 PJL_NOWARN_UNUSED_RESULT
ia_type_ast_pop(void)571 static inline c_ast_t* ia_type_ast_pop( void ) {
572   return slist_pop_head( &in_attr.type_ast_stack );
573 }
574 
575 /**
576  * Pushes a type AST onto the
577  * \ref in_attr.type_ast_stack "type AST inherited attribute  stack".
578  *
579  * @param ast The AST to push.
580  *
581  * @sa ia_type_ast_peek()
582  * @sa ia_type_ast_pop()
583  */
ia_type_ast_push(c_ast_t * ast)584 static inline void ia_type_ast_push( c_ast_t *ast ) {
585   slist_push_head( &in_attr.type_ast_stack, ast );
586 }
587 
588 /**
589  * Gets a printable string of \ref lexer_token.
590  *
591  * @return Returns said string or NULL if \ref lexer_token is the empty string.
592  */
593 PJL_WARN_UNUSED_RESULT
printable_token(void)594 static inline char const* printable_token( void ) {
595   switch ( lexer_token[0] ) {
596     case '\0': return NULL;
597     case '\n': return "\\n";
598     default  : return lexer_token;
599   } // switch
600 }
601 
602 /**
603  * Cleans-up all memory associated with \a sti but _not_ \a sti itself.
604  *
605  * @param sti The \ref show_type_info to free.
606  *
607  * @sa sti_init()
608  */
sti_cleanup(show_type_info_t * sti)609 static inline void sti_cleanup( show_type_info_t *sti ) {
610   c_sglob_cleanup( &sti->sglob );
611   MEM_ZERO( sti );
612 }
613 
614 /**
615  * Checks if the current language is _not_ among \a lang_ids.
616  *
617  * @param lang_ids The bitwise-or of language(s).
618  * @return Returns `true` only if cdecl has been initialized and \ref opt_lang
619  * is _not_ among \a lang_ids.
620  */
621 PJL_WARN_UNUSED_RESULT
unsupported(c_lang_id_t lang_ids)622 static inline bool unsupported( c_lang_id_t lang_ids ) {
623   return cdecl_initialized && !opt_lang_is_any( lang_ids );
624 }
625 
626 ////////// local functions ////////////////////////////////////////////////////
627 
628 /**
629  * Adds a type to the global set.
630  *
631  * @param decl_keyword The keyword used for the declaration.
632  * @param type_ast The AST of the type to add.
633  * @param type_loc The location of the offending type declaration.
634  * @return Returns `true` either if the type was added or it's equivalent to
635  * the existing type; `false` if a different type already exists having the
636  * same name.
637  */
638 PJL_WARN_UNUSED_RESULT
add_type(char const * decl_keyword,c_ast_t const * type_ast,c_loc_t const * type_loc)639 static bool add_type( char const *decl_keyword, c_ast_t const *type_ast,
640                       c_loc_t const *type_loc ) {
641   assert( decl_keyword != NULL );
642   assert( type_ast != NULL );
643   assert( type_loc != NULL );
644 
645   c_typedef_t const *const old_tdef = c_typedef_add( type_ast );
646   if ( old_tdef == NULL ) {             // type was added
647     //
648     // We have to move the AST from the gc_ast_list so it won't be garbage
649     // collected at the end of the parse to a separate typedef_ast_list that's
650     // freed only at program termination.
651     //
652     // But first, free all orphaned placeholder AST nodes.  (For a normal, non-
653     // type-defining parse, this step isn't necessary since all nodes are freed
654     // at the end of the parse anyway.)
655     //
656     slist_free_if( &gc_ast_list, &slist_node_is_ast_placeholder );
657     slist_push_list_tail( &typedef_ast_list, &gc_ast_list );
658   }
659   else if ( old_tdef->ast != NULL ) {   // type exists and isn't equivalent
660     print_error( type_loc,
661       "\"%s\": \"%s\" redefinition with different type; original is: ",
662       c_sname_full_name( &type_ast->sname ), decl_keyword
663     );
664 
665     // The == works because this function is called with L_DEFINE.
666     if ( decl_keyword == L_DEFINE ) {
667       c_ast_explain_type( old_tdef->ast, stderr );
668     } else {
669       //
670       // When printing the existing type in C/C++ as part of an error message,
671       // we always want to omit the trailing semicolon.
672       //
673       bool const orig_semicolon = opt_semicolon;
674       opt_semicolon = false;
675 
676       c_typedef_gibberish(
677         // The == works because this function is called with L_USING.
678         old_tdef, decl_keyword == L_USING ? C_GIB_USING : C_GIB_TYPEDEF, stderr
679       );
680 
681       opt_semicolon = orig_semicolon;
682     }
683 
684     return false;
685   }
686 
687   return true;
688 }
689 
690 /**
691  * Prints a warning that the attribute \a keyword syntax is not supported (and
692  * ignored).
693  *
694  * @param loc The source location of \a keyword.
695  * @param keyword The attribute syntax keyword, e.g., `__attribute__` or
696  * `__declspec`.
697  */
attr_syntax_not_supported(c_loc_t const * loc,char const * keyword)698 static void attr_syntax_not_supported( c_loc_t const *loc,
699                                        char const *keyword ) {
700   assert( loc != NULL );
701   assert( keyword != NULL );
702 
703   print_warning( loc,
704     "\"%s\" not supported by %s (ignoring)", keyword, CDECL
705   );
706   if ( OPT_LANG_IS(C_CPP_MIN(2X,11)) )
707     print_hint( "[[...]]" );
708   else
709     EPUTC( '\n' );
710 }
711 
712 /**
713  * Prints an additional parsing error message including a newline to standard
714  * error that continues from where yyerror() left off.  Additionally:
715  *
716  * + If the printable_token() isn't NULL:
717  *     + Checks to see if it's a keyword: if it is, mentions that it's a
718  *       keyword in the error message.
719  *     + May print "did you mean ...?" \a dym_kinds suggestions.
720  *
721  * + In debug mode, also prints the file & line where the function was called
722  *   from.
723  *
724  * @note This function isn't normally called directly; use the
725  * #elaborate_error() macro instead.
726  *
727  * @param file The name of the file where this function was called from.
728  * @param line The line number within \a file where this function was called
729  * from.
730  * @param dym_kinds The bitwise-or of the kind(s) of things possibly meant.
731  * @param format A `printf()` style format string.
732  * @param ... Arguments to print.
733  *
734  * @sa fl_keyword_expected()
735  * @sa fl_punct_expected()
736  * @sa yyerror()
737  */
738 PJL_PRINTF_LIKE_FUNC(4)
fl_elaborate_error(char const * file,int line,dym_kind_t dym_kinds,char const * format,...)739 static void fl_elaborate_error( char const *file, int line,
740                                 dym_kind_t dym_kinds, char const *format,
741                                 ... ) {
742   assert( format != NULL );
743 
744   EPUTS( ": " );
745   print_debug_file_line( file, line );
746 
747   char const *const error_token = printable_token();
748   if ( error_token != NULL )
749     EPRINTF( "\"%s\": ", error_token );
750 
751   va_list args;
752   va_start( args, format );
753   vfprintf( stderr, format, args );
754   va_end( args );
755 
756   if ( error_token != NULL ) {
757     c_keyword_t const *const k =
758       c_keyword_find( error_token, LANG_ANY, C_KW_CTX_DEFAULT );
759     if ( k != NULL ) {
760       c_lang_id_t const oldest_lang = c_lang_oldest( k->lang_ids );
761       if ( oldest_lang > opt_lang )
762         EPRINTF( "; not a keyword until %s", c_lang_name( oldest_lang ) );
763       else
764         EPRINTF( " (\"%s\" is a keyword)", error_token );
765     }
766     else if ( cdecl_mode == CDECL_ENGLISH_TO_GIBBERISH ) {
767       cdecl_keyword_t const *const ck = cdecl_keyword_find( error_token );
768       if ( ck != NULL )
769         EPRINTF( " (\"%s\" is a cdecl keyword)", error_token );
770     }
771 
772     print_suggestions( dym_kinds, error_token );
773   }
774 
775   EPUTC( '\n' );
776 }
777 
778 /**
779  * Checks whether the type currently being declared (`enum`, `struct`,
780  * `typedef`, or `union`) is nested within some other type (`struct` or
781  * `union`) and whether the current language is C.
782  *
783  * @note It is unnecessary to check either when a `class` is being declared or
784  * when a type is being declared within a `namespace` since those are not legal
785  * in C anyway.
786  *
787  * @note This function isn't normally called directly; use the
788  * #CHECK_NESTED_TYPE_OK() macro instead.
789  *
790  * @param file The name of the file where this function was called from.
791  * @param line The line number within \a file where this function was called
792  * from.
793  * @param type_loc The location of the type declaration.
794  * @return Returns `true` only if the type currently being declared is either
795  * not nested or the current language is C++.
796  */
797 PJL_WARN_UNUSED_RESULT
fl_is_nested_type_ok(char const * file,int line,c_loc_t const * type_loc)798 static bool fl_is_nested_type_ok( char const *file, int line,
799                                   c_loc_t const *type_loc ) {
800   assert( type_loc != NULL );
801   if ( !c_sname_empty( &in_attr.current_scope ) && OPT_LANG_IS(C_ANY) ) {
802     fl_print_error( file, line, type_loc, "nested types not supported in C\n" );
803     return false;
804   }
805   return true;
806 }
807 
808 /**
809  * A special case of fl_elaborate_error() that prevents oddly worded error
810  * messages where a C/C++ keyword is expected, but that keyword isn't a keyword
811  * either until a later version of the language or in a different language;
812  * hence, the lexer will return the keyword as the Y_NAME token instead of the
813  * keyword token.
814  *
815  * For example, if fl_elaborate_error() were used for the following \b cdecl
816  * command when the current language is C, you'd get the following:
817  * @code
818  * declare f as virtual function returning void
819  *              ^
820  * 14: syntax error: "virtual": "virtual" expected; not a keyword until C++98
821  * @endcode
822  * because it's really this:
823  * @code
824  * ... "virtual" [the name]": "virtual" [the token] expected ...
825  * @endcode
826  * and that looks odd.
827  *
828  * @note This function isn't normally called directly; use the
829  * #keyword_expected() macro instead.
830  *
831  * @param file The name of the file where this function was called from.
832  * @param line The line number within \a file where this function was called
833  * from.
834  * @param keyword A keyword literal.
835  *
836  * @sa fl_elaborate_error()
837  * @sa fl_punct_expected()
838  * @sa yyerror()
839  */
fl_keyword_expected(char const * file,int line,char const * keyword)840 static void fl_keyword_expected( char const *file, int line,
841                                  char const *keyword ) {
842   assert( keyword != NULL );
843 
844   char const *const error_token = printable_token();
845   if ( error_token != NULL && strcmp( error_token, keyword ) == 0 ) {
846     c_keyword_t const *const k =
847       c_keyword_find( keyword, LANG_ANY, C_KW_CTX_DEFAULT );
848     if ( k != NULL ) {
849       char const *const which_lang = c_lang_which( k->lang_ids );
850       if ( which_lang[0] != '\0' ) {
851         EPRINTF( ": \"%s\" not supported%s\n", keyword, which_lang );
852         return;
853       }
854     }
855   }
856 
857   fl_elaborate_error( file, line, DYM_NONE, "\"%s\" expected", keyword );
858 }
859 
860 /**
861  * A special case of fl_elaborate_error() that prevents oddly worded error
862  * messages when a punctuation character is expected by not doing keyword look-
863  * ups of the error token.
864 
865  * For example, if fl_elaborate_error() were used for the following \b cdecl
866  * command, you'd get the following:
867  * @code
868  * explain void f(int g const)
869  *                      ^
870  * 29: syntax error: "const": ',' expected ("const" is a keyword)
871  * @endcode
872  * and that looks odd since, if a punctuation character was expected, it seems
873  * silly to point out that the encountered token is a keyword.
874  *
875  * @note This function isn't normally called directly; use the
876  * #punct_expected() macro instead.
877  *
878  * @param file The name of the file where this function was called from.
879  * @param line The line number within \a file where this function was called
880  * from.
881  * @param punct The punctuation character that was expected.
882  *
883  * @sa fl_elaborate_error()
884  * @sa fl_keyword_expected()
885  * @sa yyerror()
886  */
fl_punct_expected(char const * file,int line,char punct)887 static void fl_punct_expected( char const *file, int line, char punct ) {
888   EPUTS( ": " );
889   print_debug_file_line( file, line );
890 
891   char const *const error_token = printable_token();
892   if ( error_token != NULL )
893     EPRINTF( "\"%s\": ", error_token );
894 
895   EPRINTF( "'%c' expected\n", punct );
896 }
897 
898 /**
899  * Frees all resources used by \ref in_attr "inherited attributes".
900  */
ia_free(void)901 static void ia_free( void ) {
902   c_sname_cleanup( &in_attr.current_scope );
903   // Do _not_ pass &c_ast_free for the 3rd argument! All AST nodes were already
904   // free'd from the gc_ast_list in parse_cleanup(). Just free the slist nodes.
905   slist_cleanup( &in_attr.type_ast_stack, /*free_fn=*/NULL );
906   c_ast_list_gc( &in_attr.typedef_ast_list );
907   MEM_ZERO( &in_attr );
908 }
909 
910 /**
911  * Cleans up individial parse data after each parse.
912  *
913  * @param hard_reset If `true`, does a "hard" reset that currently resets the
914  * EOF flag of the lexer.  This should be `true` if an error occurs and
915  * `YYABORT` is called.
916  *
917  * @sa parse_init()
918  */
parse_cleanup(bool hard_reset)919 static void parse_cleanup( bool hard_reset ) {
920   lexer_reset( hard_reset );
921   slist_cleanup( &decl_ast_list, /*free_fn=*/NULL );
922   c_ast_list_gc( &gc_ast_list );
923   ia_free();
924 }
925 
926 /**
927  * Gets ready to parse a command.
928  *
929  * @sa parse_cleanup()
930  */
parse_init(void)931 static void parse_init( void ) {
932   ast_depth = 0;
933   cdecl_mode = CDECL_ENGLISH_TO_GIBBERISH;
934 }
935 
936 /**
937  * Implements the cdecl `quit` command.
938  *
939  * @note
940  * This should be marked `noreturn` but isn't since that would generate a
941  * warning that a `break` in the Bison-generated code won't be executed.
942  */
quit(void)943 static void quit( void ) {
944   exit( EX_OK );
945 }
946 
947 /**
948  * Prints the definition of a `typedef`.
949  *
950  * @param tdef The \ref c_typedef to print.
951  * @param data Optional data passed to the visitor: in this case, the bitmask
952  * of which `typedef`s to print.
953  * @return Always returns `false`.
954  */
955 PJL_WARN_UNUSED_RESULT
show_type_visitor(c_typedef_t const * tdef,void * data)956 static bool show_type_visitor( c_typedef_t const *tdef, void *data ) {
957   assert( tdef != NULL );
958   assert( data != NULL );
959 
960   show_type_info_t const *const sti = data;
961 
962   bool const show_in_lang =
963     (sti->show_which & SHOW_ALL_TYPES) != 0 ||
964     opt_lang_is_any( tdef->lang_ids );
965 
966   if ( show_in_lang ) {
967     bool const show_type =
968       ((tdef->user_defined ?
969         (sti->show_which & SHOW_USER_TYPES) != 0 :
970         (sti->show_which & SHOW_PREDEFINED_TYPES) != 0)) &&
971       (sti->sglob.count == 0 ||
972        c_sname_match( &tdef->ast->sname, &sti->sglob ));
973 
974     if ( show_type ) {
975       if ( sti->gib_flags == C_GIB_NONE )
976         c_ast_explain_type( tdef->ast, cdecl_fout );
977       else
978         c_typedef_gibberish( tdef, sti->gib_flags, cdecl_fout );
979     }
980   }
981 
982   return false;
983 }
984 
985 /**
986  * A predicate function for slist_free_if() that checks whether \a data (cast
987  * to an AST) is a #K_PLACEHOLDER: if so, c_ast_free()s it.
988  *
989  * @param data The AST to check.
990  * @return Returns `true` only if \a data (cast to an AST) is a #K_PLACEHOLDER.
991  */
slist_node_is_ast_placeholder(void * data)992 static bool slist_node_is_ast_placeholder( void *data ) {
993   c_ast_t *const ast = data;
994   if ( ast->kind == K_PLACEHOLDER ) {
995     assert( c_ast_is_orphan( ast ) );
996     c_ast_free( ast );
997     return true;
998   }
999   return false;
1000 }
1001 
1002 /**
1003  * Initializes a show_type_info_t.
1004  *
1005  * @param sti The \ref show_type_info to initialize.
1006  * @param show_which Which types to show: predefined, user, or both?
1007  * @param glob The glob string.  May be NULL.
1008  * @param gib_flags The \ref c_gib_flags_t to use.
1009  *
1010  * @sa sti_cleanup()
1011  */
sti_init(show_type_info_t * sti,unsigned show_which,char const * glob,c_gib_flags_t gib_flags)1012 static void sti_init( show_type_info_t *sti, unsigned show_which,
1013                       char const *glob, c_gib_flags_t gib_flags ) {
1014   assert( sti != NULL );
1015   sti->show_which = show_which;
1016   sti->gib_flags = gib_flags;
1017   c_sglob_init( &sti->sglob );
1018   c_sglob_parse( glob, &sti->sglob );
1019 }
1020 
1021 /**
1022  * Prints a parsing error message to standard error.  This function is called
1023  * directly by Bison to print just `syntax error` (usually).
1024  *
1025  * @note A newline is _not_ printed since the error message will be appended to
1026  * by fl_elaborate_error().  For example, the parts of an error message are
1027  * printed by the functions shown:
1028  *
1029  *      42: syntax error: "int": "into" expected
1030  *      |--||----------||----------------------|
1031  *      |   |           |
1032  *      |   yyerror()   fl_elaborate_error()
1033  *      |
1034  *      print_loc()
1035  *
1036  * @param msg The error message to print.
1037  *
1038  * @sa fl_elaborate_error()
1039  * @sa fl_keyword_expected()
1040  * @sa fl_punct_expected()
1041  * @sa print_loc()
1042  */
yyerror(char const * msg)1043 static void yyerror( char const *msg ) {
1044   assert( msg != NULL );
1045 
1046   c_loc_t const loc = lexer_loc();
1047   print_loc( &loc );
1048 
1049   SGR_START_COLOR( stderr, error );
1050   EPUTS( msg );                         // no newline
1051   SGR_END_COLOR( stderr );
1052 
1053   parse_cleanup( false );
1054 }
1055 
1056 /** @} */
1057 
1058 ///////////////////////////////////////////////////////////////////////////////
1059 
1060 /// @cond DOXYGEN_IGNORE
1061 
1062 %}
1063 
1064 //
1065 // The difference between "literal" and either "name" or "str_val" is that
1066 // "literal" points to a statically allocated `L_` string literal constant that
1067 // MUST NOT be free'd whereas both "name" and "str_val" point to a malloc'd
1068 // string that MUST be free'd.
1069 //
1070 %union {
1071   c_alignas_t         align;
1072   c_ast_t            *ast;        // for the AST being built
1073   c_ast_list_t        ast_list;   // for declarations and function parameters
1074   c_ast_pair_t        ast_pair;   // for the AST being built
1075   unsigned            bitmask;    // multipurpose bitmask (used by show)
1076   c_cast_kind_t       cast_kind;  // C/C++ cast kind
1077   bool                flag;       // simple flag
1078   c_gib_flags_t       gib_flags;  // gibberish flags
1079   cdecl_help_t        help;       // type of help to print
1080   int                 int_val;    // integer value
1081   slist_t             list;       // multipurpose list
1082   char const         *literal;    // token L_* literal (for new-style casts)
1083   char               *name;       // identifier name, cf. sname
1084   c_oper_id_t         oper_id;    // overloaded operator ID
1085   c_sname_t           sname;      // scoped identifier name, cf. name
1086   char               *str_val;    // quoted string value
1087   c_typedef_t const  *tdef;       // typedef
1088   c_tid_t             tid;        // built-ins, storage classes, & qualifiers
1089   c_type_t            type;       // complete type
1090 }
1091 
1092                     // cdecl commands
1093 %token              Y_CAST
1094 //                  Y_CLASS             // covered in C++
1095 //                  Y_CONST             // covered in C89
1096 %token              Y_DECLARE
1097 %token              Y_DEFINE
1098 %token              Y_DYNAMIC
1099 //                  Y_EXIT              // mapped to Y_QUIT by lexer
1100 %token              Y_EXPLAIN
1101 %token              Y_HELP
1102 //                  Y_INLINE            // covered in C99
1103 //                  Y_NAMESPACE         // covered in C++
1104 %token              Y_NO
1105 %token              Y_QUIT
1106 %token              Y_REINTERPRET
1107 %token              Y_SET
1108 %token              Y_SHOW
1109 //                  Y_STATIC            // covered in K&R C
1110 //                  Y_STRUCT            // covered in K&R C
1111 //                  Y_TYPEDEF           // covered in K&R C
1112 //                  Y_UNION             // covered in K&R C
1113 //                  Y_USING             // covered in C++
1114 
1115                     // Pseudo-English
1116 %token              Y_ALIGNED
1117 %token              Y_ALL
1118 %token              Y_ARRAY
1119 %token              Y_AS
1120 %token              Y_BITS
1121 %token              Y_BYTES
1122 %token              Y_COMMANDS
1123 %token              Y_CONSTRUCTOR
1124 %token              Y_CONVERSION
1125 %token              Y_DESTRUCTOR
1126 %token              Y_ENGLISH
1127 %token              Y_EVALUATION
1128 %token              Y_EXPRESSION
1129 %token              Y_FUNCTION
1130 %token              Y_INITIALIZATION
1131 %token              Y_INTO
1132 %token              Y_LENGTH
1133 %token              Y_LINKAGE
1134 %token              Y_LITERAL
1135 %token              Y_MEMBER
1136 %token              Y_NON_MEMBER
1137 %token              Y_OF
1138 %token              Y_OPTIONS
1139 %token              Y_POINTER
1140 %token              Y_PREDEFINED
1141 %token              Y_PURE
1142 %token              Y_REFERENCE
1143 %token              Y_RETURNING
1144 %token              Y_RVALUE
1145 %token              Y_SCOPE
1146 %token              Y_TO
1147 %token              Y_USER
1148 %token              Y_USER_DEFINED
1149 %token              Y_VARIABLE
1150 %token              Y_WIDTH
1151 
1152                     // Precedence
1153 %nonassoc           Y_PREC_LESS_THAN_upc_layout_qualifier
1154 
1155                     //
1156                     // C and C++ operators that are single-character and have
1157                     // no alternative token are represented by themselves
1158                     // directly.  All multi-character operators or those that
1159                     // have an alternative token are given Y_ names.
1160                     //
1161 
1162                     // C/C++ operators: precedence 17
1163 %left               Y_COLON2            "::"
1164 %left               Y_COLON2_STAR       "::*"
1165                     // C/C++ operators: precedence 16
1166 %token              Y_PLUS2             "++"
1167 %token              Y_MINUS2            "--"
1168 %left                                   '(' ')'
1169                                         '[' ']'
1170                                         '.'
1171                     Y_ARROW             "->"
1172                     // C/C++ operators: precedence 15
1173 %right              Y_AMPER          // '&' -- also has alt. token "bitand"
1174                                         '*'
1175                     Y_EXCLAM         // '!' -- also has alt. token "not"
1176                  // Y_UMINUS         // '-' -- covered by '-' below
1177                  // Y_UPLUS          // '+' -- covered by '+' below
1178                     Y_SIZEOF
1179                     Y_TILDE          // '~' -- also has alt.token "compl"
1180                     // C/C++ operators: precedence 14
1181 %left               Y_DOT_STAR          ".*"
1182                     Y_ARROW_STAR        "->*"
1183                     // C/C++ operators: precedence 13
1184 %left                                // '*' -- covered by '*' above
1185                                         '/'
1186                                         '%'
1187                     // C/C++ operators: precedence 12
1188 %left                                   '-'
1189                                         '+'
1190                     // C/C++ operators: precedence 11
1191 %left               Y_LESS2             "<<"
1192                     Y_GREATER2          ">>"
1193                     // C/C++ operators: precedence 10
1194 %left               Y_LESS_EQ_GREATER   "<=>"
1195                     // C/C++ operators: precedence 9
1196 %left                                   '<'
1197                                         '>'
1198                     Y_LESS_EQ           "<="
1199                     Y_GREATER_EQ        ">="
1200                     // C/C++ operators: precedence 8
1201 %left               Y_EQ2               "=="
1202                     Y_EXCLAM_EQ      // "!=" -- also has alt. token "not_eq"
1203                     // C/C++ operators: precedence 7 (covered above)
1204 %left               Y_BIT_AND        // '&' -- covered by Y_AMPER
1205                     // C/C++ operators: precedence 6
1206 %left               Y_CIRC           // '^' -- also has alt. token "xor"
1207                     // C/C++ operators: precedence 5
1208 %left               Y_PIPE           // '|' -- also has alt. token "bitor"
1209                     // C/C++ operators: precedence 4
1210 %left               Y_AMPER2         // "&&" -- also has alt. token "and"
1211                     // C/C++ operators: precedence 3
1212 %left               Y_PIPE2          // "||" -- also has alt. token "or"
1213                     // C/C++ operators: precedence 2
1214 %right              Y_QMARK_COLON       "?:"
1215                                         '='
1216                     Y_PERCENT_EQ        "%="
1217                     Y_AMPER_EQ       // "&=" -- also has alt. token "and_eq"
1218                     Y_STAR_EQ           "*="
1219                     Y_PLUS_EQ           "+="
1220                     Y_MINUS_EQ          "-="
1221                     Y_SLASH_EQ          "/="
1222                     Y_LESS2_EQ          "<<="
1223                     Y_GREATER2_EQ       ">>="
1224                     Y_CIRC_EQ        // "^=" -- also has alt. token "xor_eq"
1225                     Y_PIPE_EQ        // "|=" -- also has alt. token "or_eq"
1226                     // C/C++ operators: precedence 1
1227 %left                                   ','
1228 
1229                     // K&R C
1230 %token  <tid>       Y_AUTO_STORAGE      // C version of "auto"
1231 %token              Y_BREAK
1232 %token              Y_CASE
1233 %token  <tid>       Y_CHAR
1234 %token              Y_CONTINUE
1235 %token  <tid>       Y_DEFAULT
1236 %token              Y_DO
1237 %token  <tid>       Y_DOUBLE
1238 %token              Y_ELSE
1239 %token  <tid>       Y_EXTERN
1240 %token  <tid>       Y_FLOAT
1241 %token              Y_FOR
1242 %token              Y_GOTO
1243 %token              Y_IF
1244 %token  <tid>       Y_INT
1245 %token  <tid>       Y_LONG
1246 %token  <tid>       Y_REGISTER
1247 %token              Y_RETURN
1248 %token  <tid>       Y_SHORT
1249 %token  <tid>       Y_STATIC
1250 %token  <tid>       Y_STRUCT
1251 %token              Y_SWITCH
1252 %token  <tid>       Y_TYPEDEF
1253 %token  <tid>       Y_UNION
1254 %token  <tid>       Y_UNSIGNED
1255 %token              Y_WHILE
1256 
1257                     // C89
1258 %token              Y_ASM
1259 %token  <tid>       Y_CONST
1260 %token              Y_ELLIPSIS    "..." // for varargs
1261 %token  <tid>       Y_ENUM
1262 %token  <tid>       Y_SIGNED
1263 %token  <tid>       Y_VOID
1264 %token  <tid>       Y_VOLATILE
1265 
1266                     // C95
1267 %token  <tid>       Y_WCHAR_T
1268 
1269                     // C99
1270 %token  <tid>       Y__BOOL
1271 %token  <tid>       Y__COMPLEX
1272 %token  <tid>       Y__IMAGINARY
1273 %token  <tid>       Y_INLINE
1274 %token  <tid>       Y_RESTRICT
1275 
1276                     // C11
1277 %token              Y__ALIGNAS
1278 %token              Y__ALIGNOF
1279 %token  <tid>       Y__ATOMIC_QUAL      // qualifier: _Atomic type
1280 %token  <tid>       Y__ATOMIC_SPEC      // specifier: _Atomic (type)
1281 %token              Y__GENERIC
1282 %token  <tid>       Y__NORETURN
1283 %token              Y__STATIC_ASSERT
1284 %token  <tid>       Y__THREAD_LOCAL
1285 %token              Y_THREAD Y_LOCAL
1286 
1287                     // C++
1288 %token  <tid>       Y_BOOL
1289 %token              Y_CATCH
1290 %token  <tid>       Y_CLASS
1291 %token  <literal>   Y_CONST_CAST
1292 %token  <sname>     Y_CONSTRUCTOR_SNAME // e.g., S::T::T
1293 %token  <tid>       Y_DELETE
1294 %token  <sname>     Y_DESTRUCTOR_SNAME  // e.g., S::T::~T
1295 %token  <literal>   Y_DYNAMIC_CAST
1296 %token  <tid>       Y_EXPLICIT
1297 %token  <tid>       Y_FALSE             // for noexcept(false)
1298 %token  <tid>       Y_FRIEND
1299 %token  <tid>       Y_MUTABLE
1300 %token  <tid>       Y_NAMESPACE
1301 %token              Y_NEW
1302 %token              Y_OPERATOR
1303 %token              Y_PRIVATE
1304 %token              Y_PROTECTED
1305 %token              Y_PUBLIC
1306 %token  <literal>   Y_REINTERPRET_CAST
1307 %token  <literal>   Y_STATIC_CAST
1308 %token              Y_TEMPLATE
1309 %token              Y_THIS
1310 %token  <tid>       Y_THROW
1311 %token  <tid>       Y_TRUE              // for noexcept(true)
1312 %token              Y_TRY
1313 %token              Y_TYPEID
1314 %token  <flag>      Y_TYPENAME
1315 %token  <tid>       Y_USING
1316 %token  <tid>       Y_VIRTUAL
1317 
1318                     // C11 & C++11
1319 %token  <tid>       Y_CHAR16_T
1320 %token  <tid>       Y_CHAR32_T
1321 
1322                     // C2X & C++11
1323 %token              Y_ATTR_BEGIN        // First '[' of "[[" for an attribute.
1324 
1325                     // C++11
1326 %token              Y_ALIGNAS
1327 %token              Y_ALIGNOF
1328 %token  <tid>       Y_AUTO_TYPE         // C++11 version of "auto"
1329 %token              Y_CARRIES Y_DEPENDENCY
1330 %token  <tid>       Y_CARRIES_DEPENDENCY
1331 %token  <tid>       Y_CONSTEXPR
1332 %token              Y_DECLTYPE
1333 %token              Y_EXCEPT
1334 %token  <tid>       Y_FINAL
1335 %token  <tid>       Y_NOEXCEPT
1336 %token              Y_NULLPTR
1337 %token  <tid>       Y_OVERRIDE
1338 %token              Y_QUOTE2            // for user-defined literals
1339 %token              Y_STATIC_ASSERT
1340 %token  <tid>       Y_THREAD_LOCAL
1341 
1342                     // C2X & C++14
1343 %token  <tid>       Y_DEPRECATED
1344 
1345                     // C2X & C++17
1346 %token              Y_DISCARD
1347 %token  <tid>       Y_MAYBE_UNUSED
1348 %token              Y_MAYBE Y_UNUSED
1349 %token  <tid>       Y_NODISCARD
1350 
1351                     // C++17
1352 %token  <tid>       Y_NORETURN
1353 
1354                     // C2X & C++20
1355 %token  <tid>       Y_CHAR8_T
1356 
1357                     // C++20
1358 %token              Y_ADDRESS
1359 %token              Y_CONCEPT
1360 %token  <tid>       Y_CONSTEVAL
1361 %token  <tid>       Y_CONSTINIT
1362 %token              Y_CO_AWAIT
1363 %token              Y_CO_RETURN
1364 %token              Y_CO_YIELD
1365 %token  <tid>       Y_EXPORT
1366 %token  <tid>       Y_NO_UNIQUE_ADDRESS
1367 %token              Y_REQUIRES
1368 %token              Y_UNIQUE
1369 
1370                     // Embedded C extensions
1371 %token  <tid>       Y_EMC__ACCUM
1372 %token  <tid>       Y_EMC__FRACT
1373 %token  <tid>       Y_EMC__SAT
1374 
1375                     // Unified Parallel C extensions
1376 %token  <tid>       Y_UPC_RELAXED
1377 %token  <tid>       Y_UPC_SHARED
1378 %token  <tid>       Y_UPC_STRICT
1379 
1380                     // GNU extensions
1381 %token              Y_GNU___ATTRIBUTE__
1382 %token  <tid>       Y_GNU___RESTRICT
1383 
1384                     // Apple extensions
1385 %token  <tid>       Y_APPLE___BLOCK     // __block storage class
1386 %token              Y_APPLE_BLOCK       // English for '^'
1387 
1388                     // Microsoft extensions
1389 %token  <tid>       Y_MSC___CDECL
1390 %token  <tid>       Y_MSC___CLRCALL
1391 %token              Y_MSC___DECLSPEC
1392 %token  <tid>       Y_MSC___FASTCALL
1393 %token  <tid>       Y_MSC___STDCALL
1394 %token  <tid>       Y_MSC___THISCALL
1395 %token  <tid>       Y_MSC___VECTORCALL
1396 
1397                     // Miscellaneous
1398 %token              ':'
1399 %token              ';'
1400 %token              '{' '}'
1401 %token  <str_val>   Y_CHAR_LIT
1402 %token              Y_END
1403 %token              Y_ERROR
1404 %token  <name>      Y_GLOB
1405 %token  <int_val>   Y_INT_LIT
1406 %token  <name>      Y_NAME
1407 %token  <name>      Y_SET_OPTION
1408 %token  <str_val>   Y_STR_LIT
1409 %token  <tdef>      Y_TYPEDEF_NAME      // e.g., size_t
1410 %token  <tdef>      Y_TYPEDEF_SNAME     // e.g., std::string
1411 
1412                     //
1413                     // When the lexer returns Y_LEXER_ERROR, it means that
1414                     // there was a lexical error and that it's already printed
1415                     // an error message so the parser should NOT print an error
1416                     // message and just call PARSE_ABORT().
1417                     ///
1418 %token              Y_LEXER_ERROR
1419 
1420 //
1421 // Grammar rules are named according to the following conventions.  In order,
1422 // if a rule:
1423 //
1424 //  1. Is a list, "_list" is appended.
1425 //  2. Is specific to C/C++, "_c" is appended; is specific to pseudo-English,
1426 //     "_english" is appended.
1427 //  3. Is of type:
1428 //      + <ast>: "_ast" is appended.
1429 //      + <ast_list>: (See #1.)
1430 //      + <ast_pair>: "_astp" is appended.
1431 //      + <bitmask>: "_mask" is appended.
1432 //      + <flag>: "_flag" is appended.
1433 //      + <name>: "_name" is appended.
1434 //      + <int_val>: "_int" is appended.
1435 //      + <literal>: "_literal" is appended.
1436 //      + <sname>: "_sname" is appended.
1437 //      + <tid>: "_[bsa]tid" is appended.
1438 //      + <type>: "_type" is appended.
1439 //  4. Is expected, "_exp" is appended; is optional, "_opt" is appended.
1440 //
1441 // Sort using: sort -bdk3
1442 
1443                     // Pseudo-English
1444 %type   <ast>       alignas_or_width_decl_english_ast
1445 %type   <align>     alignas_specifier_english
1446 %type   <ast>       array_decl_english_ast
1447 %type   <tid>       array_qualifier_list_english_stid
1448 %type   <tid>       array_qualifier_list_english_stid_opt
1449 %type   <int_val>   array_size_int_opt
1450 %type   <tid>       attribute_english_atid
1451 %type   <ast>       block_decl_english_ast
1452 %type   <ast>       constructor_decl_english_ast
1453 %type   <ast>       decl_english_ast
1454 %type   <ast_list>  decl_list_english decl_list_english_opt
1455 %type   <ast>       destructor_decl_english_ast
1456 %type   <ast>       enum_class_struct_union_english_ast
1457 %type   <ast>       enum_fixed_type_english_ast
1458 %type   <tid>       enum_fixed_type_modifier_list_english_btid
1459 %type   <tid>       enum_fixed_type_modifier_list_english_btid_opt
1460 %type   <ast>       enum_unmodified_fixed_type_english_ast
1461 %type   <ast>       func_decl_english_ast
1462 %type   <type>      func_qualifier_english_type_opt
1463 %type   <bitmask>   member_or_non_member_mask_opt
1464 %type   <cast_kind> new_style_cast_english
1465 %type   <sname>     of_scope_english
1466 %type   <sname>     of_scope_list_english of_scope_list_english_opt
1467 %type   <ast>       of_type_enum_fixed_type_english_ast_opt
1468 %type   <ast>       oper_decl_english_ast
1469 %type   <ast_list>  paren_decl_list_english paren_decl_list_english_opt
1470 %type   <ast>       pointer_decl_english_ast
1471 %type   <ast>       qualifiable_decl_english_ast
1472 %type   <ast>       qualified_decl_english_ast
1473 %type   <ast>       reference_decl_english_ast
1474 %type   <ast>       reference_english_ast
1475 %type   <tid>       ref_qualifier_english_stid_opt
1476 %type   <ast>       returning_english_ast returning_english_ast_opt
1477 %type   <type>      scope_english_type scope_english_type_exp
1478 %type   <sname>     sname_english sname_english_exp
1479 %type   <ast>       sname_english_ast
1480 %type   <list>      sname_list_english
1481 %type   <tid>       storage_class_english_stid
1482 %type   <tid>       storage_class_list_english_stid_opt
1483 %type   <ast>       type_english_ast
1484 %type   <type>      type_modifier_english_type
1485 %type   <type>      type_modifier_list_english_type
1486 %type   <type>      type_modifier_list_english_type_opt
1487 %type   <tid>       type_qualifier_english_stid
1488 %type   <type>      type_qualifier_english_type
1489 %type   <type>      type_qualifier_list_english_type
1490 %type   <type>      type_qualifier_list_english_type_opt
1491 %type   <tid>       udc_storage_class_english_stid
1492 %type   <type>      udc_storage_class_english_type
1493 %type   <type>      udc_storage_class_list_english_type_opt
1494 %type   <ast>       unmodified_type_english_ast
1495 %type   <ast>       user_defined_literal_decl_english_ast
1496 %type   <ast>       var_decl_english_ast
1497 %type   <int_val>   width_specifier_english
1498 
1499                     // C/C++ casts
1500 %type   <ast_pair>  array_cast_c_astp
1501 %type   <ast_pair>  block_cast_c_astp
1502 %type   <ast_pair>  cast_c_astp cast_c_astp_opt cast2_c_astp
1503 %type   <ast_pair>  func_cast_c_astp
1504 %type   <ast_pair>  nested_cast_c_astp
1505 %type   <cast_kind> new_style_cast_c
1506 %type   <ast_pair>  pointer_cast_c_astp
1507 %type   <ast_pair>  pointer_to_member_cast_c_astp
1508 %type   <ast_pair>  reference_cast_c_astp
1509 
1510                     // C/C++ declarations
1511 %type   <align>     alignas_specifier_c
1512 %type   <sname>     any_sname_c any_sname_c_exp any_sname_c_opt
1513 %type   <ast_pair>  array_decl_c_astp
1514 %type   <ast>       array_size_c_ast
1515 %type   <int_val>   array_size_c_int
1516 %type   <ast>       atomic_builtin_typedef_type_c_ast
1517 %type   <ast>       atomic_specifier_type_c_ast
1518 %type   <tid>       attribute_c_atid
1519 %type   <tid>       attribute_list_c_atid attribute_list_c_atid_opt
1520 %type   <tid>       attribute_specifier_list_c_atid
1521 %type   <tid>       attribute_specifier_list_c_atid_opt
1522 %type   <int_val>   bit_field_c_int_opt
1523 %type   <ast_pair>  block_decl_c_astp
1524 %type   <ast_pair>  decl_c_astp decl2_c_astp
1525 %type   <ast>       east_modified_type_c_ast
1526 %type   <ast>       enum_class_struct_union_c_ast
1527 %type   <ast>       enum_fixed_type_c_ast enum_fixed_type_c_ast_opt
1528 %type   <tid>       enum_fixed_type_modifier_list_btid
1529 %type   <tid>       enum_fixed_type_modifier_list_btid_opt
1530 %type   <tid>       enum_fixed_type_modifier_btid
1531 %type   <ast>       enum_unmodified_fixed_type_c_ast
1532 %type   <tid>       extern_linkage_c_stid extern_linkage_c_stid_opt
1533 %type   <ast_pair>  func_decl_c_astp
1534 %type   <tid>       func_equals_c_stid_opt
1535 %type   <tid>       func_qualifier_c_stid
1536 %type   <tid>       func_qualifier_list_c_stid_opt
1537 %type   <tid>       func_ref_qualifier_c_stid_opt
1538 %type   <tid>       linkage_stid
1539 %type   <ast_pair>  nested_decl_c_astp
1540 %type   <tid>       noexcept_c_stid_opt
1541 %type   <ast>       oper_c_ast
1542 %type   <ast_pair>  oper_decl_c_astp
1543 %type   <ast>       param_c_ast
1544 %type   <ast_list>  param_list_c_ast param_list_c_ast_exp param_list_c_ast_opt
1545 %type   <ast_pair>  pointer_decl_c_astp
1546 %type   <ast_pair>  pointer_to_member_decl_c_astp
1547 %type   <ast>       pointer_to_member_type_c_ast
1548 %type   <ast>       pointer_type_c_ast
1549 %type   <ast_pair>  reference_decl_c_astp
1550 %type   <ast>       reference_type_c_ast
1551 %type   <tid>       restrict_qualifier_c_stid
1552 %type   <tid>       rparen_func_qualifier_list_c_stid_opt
1553 %type   <sname>     scope_sname_c_opt sub_scope_sname_c_opt
1554 %type   <sname>     sname_c sname_c_exp sname_c_opt
1555 %type   <ast>       sname_c_ast
1556 %type   <type>      storage_class_c_type
1557 %type   <ast>       trailing_return_type_c_ast_opt
1558 %type   <ast>       type_c_ast
1559 %type   <sname>     typedef_sname_c
1560 %type   <ast>       typedef_type_c_ast
1561 %type   <ast>       typedef_type_decl_c_ast
1562 %type   <type>      type_modifier_c_type
1563 %type   <type>      type_modifier_list_c_type type_modifier_list_c_type_opt
1564 %type   <tid>       type_qualifier_c_stid
1565 %type   <tid>       type_qualifier_list_c_stid type_qualifier_list_c_stid_opt
1566 %type   <ast_pair>  user_defined_conversion_decl_c_astp
1567 %type   <ast>       user_defined_literal_c_ast
1568 %type   <ast_pair>  user_defined_literal_decl_c_astp
1569 %type   <ast>       using_decl_c_ast
1570 
1571                     // C++ user-defined conversions
1572 %type   <ast>       pointer_to_member_udc_decl_c_ast
1573 %type   <ast>       pointer_udc_decl_c_ast
1574 %type   <ast>       reference_udc_decl_c_ast
1575 %type   <ast>       udc_decl_c_ast udc_decl_c_ast_opt
1576 
1577                     // Microsoft extensions
1578 %type   <tid>       msc_calling_convention_atid
1579 %type   <ast_pair>  msc_calling_convention_c_astp
1580 
1581                     // Miscellaneous
1582 %type   <name>      any_name any_name_exp
1583 %type   <tdef>      any_typedef
1584 %type   <tid>       builtin_btid
1585 %type   <ast>       builtin_type_ast
1586 %type   <tid>       class_struct_btid class_struct_btid_opt
1587 %type   <tid>       class_struct_union_btid class_struct_union_btid_exp
1588 %type   <oper_id>   c_operator
1589 %type   <tid>       cv_qualifier_stid cv_qualifier_list_stid_opt
1590 %type   <tid>       enum_btid enum_class_struct_union_c_btid
1591 %type   <name>      glob glob_opt
1592 %type   <help>      help_what_opt
1593 %type   <tid>       inline_stid_opt
1594 %type   <int_val>   int_exp
1595 %type   <ast>       name_ast
1596 %type   <name>      name_exp
1597 %type   <tid>       namespace_btid_exp
1598 %type   <sname>     namespace_sname_c namespace_sname_c_exp
1599 %type   <type>      namespace_type
1600 %type   <sname>     namespace_typedef_sname_c
1601 %type   <tid>       no_except_bool_stid_exp
1602 %type   <bitmask>   predefined_or_user_mask_opt
1603 %type   <name>      set_option_value_opt
1604 %type   <gib_flags> show_format show_format_exp show_format_opt
1605 %type   <bitmask>   show_which_types_mask_opt
1606 %type   <tid>       static_stid_opt
1607 %type   <str_val>   str_lit str_lit_exp
1608 %type   <type>      type_modifier_base_type
1609 %type   <flag>      typename_flag_opt
1610 %type   <tid>       virtual_stid_exp virtual_stid_opt
1611 
1612 //
1613 // Bison %destructors.  We don't use the <identifier> syntax because older
1614 // versions of Bison don't support it.
1615 //
1616 // Clean-up of AST nodes is done via garbage collection using gc_ast_list.
1617 //
1618 
1619 // c_ast_list_t
1620 %destructor { DTRACE; c_ast_list_cleanup( &$$ ); } decl_list_english
1621 %destructor { DTRACE; c_ast_list_cleanup( &$$ ); } decl_list_english_opt
1622 %destructor { DTRACE; c_ast_list_cleanup( &$$ ); } param_list_c_ast
1623 %destructor { DTRACE; c_ast_list_cleanup( &$$ ); } param_list_c_ast_exp
1624 %destructor { DTRACE; c_ast_list_cleanup( &$$ ); } param_list_c_ast_opt
1625 %destructor { DTRACE; c_ast_list_cleanup( &$$ ); } paren_decl_list_english
1626 %destructor { DTRACE; c_ast_list_cleanup( &$$ ); } paren_decl_list_english_opt
1627 
1628 // name
1629 %destructor { DTRACE; FREE( $$ ); } any_name
1630 %destructor { DTRACE; FREE( $$ ); } any_name_exp
1631 %destructor { DTRACE; FREE( $$ ); } glob_opt
1632 %destructor { DTRACE; FREE( $$ ); } name_exp
1633 %destructor { DTRACE; FREE( $$ ); } set_option_value_opt
1634 %destructor { DTRACE; FREE( $$ ); } str_lit
1635 %destructor { DTRACE; FREE( $$ ); } str_lit_exp
1636 %destructor { DTRACE; FREE( $$ ); } Y_CHAR_LIT
1637 %destructor { DTRACE; FREE( $$ ); } Y_GLOB
1638 %destructor { DTRACE; FREE( $$ ); } Y_NAME
1639 %destructor { DTRACE; FREE( $$ ); } Y_SET_OPTION
1640 %destructor { DTRACE; FREE( $$ ); } Y_STR_LIT
1641 
1642 // sname
1643 %destructor { DTRACE; c_sname_cleanup( &$$ ); } any_sname_c
1644 %destructor { DTRACE; c_sname_cleanup( &$$ ); } any_sname_c_exp
1645 %destructor { DTRACE; c_sname_cleanup( &$$ ); } any_sname_c_opt
1646 %destructor { DTRACE; c_sname_cleanup( &$$ ); } of_scope_english
1647 %destructor { DTRACE; c_sname_cleanup( &$$ ); } of_scope_list_english
1648 %destructor { DTRACE; c_sname_cleanup( &$$ ); } of_scope_list_english_opt
1649 %destructor { DTRACE; c_sname_cleanup( &$$ ); } scope_sname_c_opt
1650 %destructor { DTRACE; c_sname_cleanup( &$$ ); } sname_c
1651 %destructor { DTRACE; c_sname_cleanup( &$$ ); } sname_c_exp
1652 %destructor { DTRACE; c_sname_cleanup( &$$ ); } sname_c_opt
1653 %destructor { DTRACE; c_sname_cleanup( &$$ ); } sname_english
1654 %destructor { DTRACE; c_sname_cleanup( &$$ ); } sname_english_exp
1655 %destructor { DTRACE; c_sname_cleanup( &$$ ); } sub_scope_sname_c_opt
1656 %destructor { DTRACE; c_sname_cleanup( &$$ ); } typedef_sname_c
1657 %destructor { DTRACE; c_sname_cleanup( &$$ ); } Y_CONSTRUCTOR_SNAME
1658 %destructor { DTRACE; c_sname_cleanup( &$$ ); } Y_DESTRUCTOR_SNAME
1659 
1660 // sname_list
1661 %destructor { DTRACE; c_sname_list_cleanup( &$$ ); } sname_list_english
1662 
1663 ///////////////////////////////////////////////////////////////////////////////
1664 %%
1665 
1666 command_list
1667   : /* empty */
1668   | command_list { parse_init(); } command
1669     { //
1670       // We get here only after a successful parse, so a hard reset is not
1671       // needed.
1672       //
1673       parse_cleanup( false );
1674     }
1675   ;
1676 
1677 command
1678   : cast_command semi_or_end
1679   | declare_command semi_or_end
1680   | define_command semi_or_end
1681   | explain_command semi_or_end
1682   | help_command semi_or_end
1683   | quit_command semi_or_end
1684   | scoped_command
1685   | set_command semi_or_end
1686   | show_command semi_or_end
1687   | template_command semi_or_end
1688   | typedef_command semi_or_end
1689   | using_command semi_or_end
1690   | semi_or_end                         // allows for blank lines
1691   | error
1692     {
1693       if ( printable_token() != NULL )
1694         elaborate_error_dym( DYM_COMMANDS, "unexpected token" );
1695       else
1696         elaborate_error( "unexpected end of command" );
1697     }
1698   ;
1699 
1700 ///////////////////////////////////////////////////////////////////////////////
1701 //  COMMANDS                                                                 //
1702 ///////////////////////////////////////////////////////////////////////////////
1703 
1704 /// cast command //////////////////////////////////////////////////////////////
1705 
1706 cast_command
1707     /*
1708      * C-style cast.
1709      */
1710   : Y_CAST sname_english_exp as_into_to_exp decl_english_ast
1711     {
1712       DUMP_START( "cast_command",
1713                   "CAST sname_english_exp as_into_to_exp decl_english_ast" );
1714       DUMP_SNAME( "sname_english_exp", $2 );
1715       DUMP_AST( "decl_english_ast", $4 );
1716       DUMP_END();
1717 
1718       $4->cast_kind = C_CAST_C;
1719       bool const ok = c_ast_check( $4 );
1720       if ( ok ) {
1721         FPUTC( '(', cdecl_fout );
1722         c_ast_gibberish( $4, C_GIB_CAST, cdecl_fout );
1723         FPRINTF( cdecl_fout, ")%s\n", c_sname_full_name( &$2 ) );
1724       }
1725 
1726       c_sname_cleanup( &$2 );
1727       if ( !ok )
1728         PARSE_ABORT();
1729     }
1730 
1731     /*
1732      * New C++-style cast.
1733      */
1734   | new_style_cast_english cast_exp sname_english_exp as_into_to_exp
1735     decl_english_ast
1736     {
1737       char const *const cast_literal = c_cast_gibberish( $1 );
1738 
1739       DUMP_START( "cast_command",
1740                   "new_style_cast_english CAST sname_english_exp "
1741                   "as_into_to_exp decl_english_ast" );
1742       DUMP_STR( "new_style_cast_english", cast_literal );
1743       DUMP_SNAME( "sname_english_exp", $3 );
1744       DUMP_AST( "decl_english_ast", $5 );
1745       DUMP_END();
1746 
1747       bool ok = false;
1748 
1749       if ( unsupported( LANG_CPP_ANY ) ) {
1750         print_error( &@1,
1751           "%s not supported%s\n",
1752           cast_literal, c_lang_which( LANG_CPP_ANY )
1753         );
1754       }
1755       else {
1756         $5->cast_kind = $1;
1757         if ( (ok = c_ast_check( $5 )) ) {
1758           FPRINTF( cdecl_fout, "%s<", cast_literal );
1759           c_ast_gibberish( $5, C_GIB_CAST, cdecl_fout );
1760           FPRINTF( cdecl_fout, ">(%s)\n", c_sname_full_name( &$3 ) );
1761         }
1762       }
1763 
1764       c_sname_cleanup( &$3 );
1765       if ( !ok )
1766         PARSE_ABORT();
1767     }
1768   ;
1769 
1770 new_style_cast_english
1771   : Y_CONST                       { $$ = C_CAST_CONST;        }
1772   | Y_DYNAMIC                     { $$ = C_CAST_DYNAMIC;      }
1773   | Y_REINTERPRET                 { $$ = C_CAST_REINTERPRET;  }
1774   | Y_STATIC                      { $$ = C_CAST_STATIC;       }
1775   ;
1776 
1777 /// declare command ///////////////////////////////////////////////////////////
1778 
1779 declare_command
1780     /*
1781      * Common declaration, e.g.: declare x as int.
1782      */
1783   : Y_DECLARE sname_list_english as_exp storage_class_list_english_stid_opt
1784     alignas_or_width_decl_english_ast
1785     {
1786       if ( $5->kind == K_NAME ) {
1787         //
1788         // This checks for a case like:
1789         //
1790         //      declare x as y
1791         //
1792         // i.e., declaring a variable name as another name (unknown type).
1793         // This can get this far due to the nature of the C/C++ grammar.
1794         //
1795         // This check has to be done now in the parser rather than later in the
1796         // AST because the name of the AST node needs to be set to the variable
1797         // name, but the AST node is itself a name and overwriting it would
1798         // lose information.
1799         //
1800         assert( !c_sname_empty( &$5->sname ) );
1801         print_error_unknown_name( &@5, &$5->sname );
1802         c_sname_list_cleanup( &$2 );
1803         PARSE_ABORT();
1804       }
1805 
1806       DUMP_START( "declare_command",
1807                   "DECLARE sname_list_english AS "
1808                   "storage_class_list_english_stid_opt "
1809                   "alignas_or_width_decl_english_ast" );
1810       DUMP_SNAME_LIST( "sname_list_english", $2 );
1811       DUMP_TID( "storage_class_list_english_stid_opt", $4 );
1812       DUMP_AST( "alignas_or_width_decl_english_ast", $5 );
1813 
1814       $5->loc = @2;
1815 
1816       bool ok = c_type_add_tid( &$5->type, $4, &@4 );
1817 
1818       DUMP_AST( "decl_english", $5 );
1819       DUMP_END();
1820 
1821       if ( ok ) {
1822         c_gib_flags_t gib_flags = C_GIB_DECL;
1823         if ( slist_len( &$2 ) > 1 )
1824           gib_flags |= C_GIB_MULTI_DECL;
1825         FOREACH_SLIST_NODE( sname_node, &$2 ) {
1826           c_sname_set( &$5->sname, sname_node->data );
1827           if ( !(ok = c_ast_check( $5 )) )
1828             break;
1829           c_ast_gibberish( $5, gib_flags, cdecl_fout );
1830           if ( sname_node->next != NULL ) {
1831             gib_flags |= C_GIB_OMIT_TYPE;
1832             FPUTS( ", ", cdecl_fout );
1833           }
1834         } // for
1835       }
1836 
1837       c_sname_list_cleanup( &$2 );
1838       if ( !ok )
1839         PARSE_ABORT();
1840       if ( opt_semicolon )
1841         FPUTC( ';', cdecl_fout );
1842       FPUTC( '\n', cdecl_fout );
1843     }
1844 
1845     /*
1846      * C++ overloaded operator declaration.
1847      */
1848   | Y_DECLARE c_operator
1849     { //
1850       // This check is done now in the parser rather than later in the AST
1851       // since it yields a better error message since otherwise it would warn
1852       // that "operator" is a keyword in C++98 which skims right past the
1853       // bigger error that operator overloading isn't supported in C.
1854       //
1855       if ( unsupported( LANG_CPP_ANY ) ) {
1856         print_error( &@2, "operator overloading not supported in C\n" );
1857         PARSE_ABORT();
1858       }
1859     }
1860     of_scope_list_english_opt as_exp storage_class_list_english_stid_opt
1861     oper_decl_english_ast
1862     {
1863       DUMP_START( "declare_command",
1864                   "DECLARE c_operator of_scope_list_english_opt AS "
1865                   "storage_class_list_english_stid_opt "
1866                   "oper_decl_english_ast" );
1867       DUMP_STR( "c_operator", c_oper_get( $2 )->name );
1868       DUMP_SNAME( "of_scope_list_english_opt", $4 );
1869       DUMP_TID( "storage_class_list_english_stid_opt", $6 );
1870       DUMP_AST( "oper_decl_english_ast", $7 );
1871 
1872       c_sname_set( &$7->sname, &$4 );
1873       $7->loc = @2;
1874       $7->as.oper.oper_id = $2;
1875       C_TYPE_ADD_TID( &$7->type, $6, @6 );
1876 
1877       DUMP_AST( "declare_command", $7 );
1878       DUMP_END();
1879 
1880       C_AST_CHECK( $7 );
1881       c_ast_gibberish( $7, C_GIB_DECL, cdecl_fout );
1882       if ( opt_semicolon )
1883         FPUTC( ';', cdecl_fout );
1884       FPUTC( '\n', cdecl_fout );
1885     }
1886 
1887     /*
1888      * C++ user-defined conversion operator declaration.
1889      */
1890   | Y_DECLARE udc_storage_class_list_english_type_opt cv_qualifier_list_stid_opt
1891     Y_USER_DEFINED conversion_exp operator_opt of_scope_list_english_opt
1892     returning_exp decl_english_ast
1893     {
1894       DUMP_START( "declare_command",
1895                   "DECLARE udc_storage_class_list_english_type_opt "
1896                   "cv_qualifier_list_stid_opt "
1897                   "USER-DEFINED CONVERSION OPERATOR "
1898                   "of_scope_list_english_opt "
1899                   "RETURNING decl_english_ast" );
1900       DUMP_TYPE( "udc_storage_class_list_english_type_opt", $2 );
1901       DUMP_TID( "cv_qualifier_list_stid_opt", $3 );
1902       DUMP_SNAME( "of_scope_list_english_opt", $7 );
1903       DUMP_AST( "decl_english_ast", $9 );
1904 
1905       c_ast_t *const conv_ast = c_ast_new_gc( K_USER_DEF_CONVERSION, &@$ );
1906       c_sname_set( &conv_ast->sname, &$7 );
1907       conv_ast->type = c_type_or( &$2, &C_TYPE_LIT_S( $3 ) );
1908       c_ast_set_parent( $9, conv_ast );
1909 
1910       DUMP_AST( "declare_command", conv_ast );
1911       DUMP_END();
1912 
1913       C_AST_CHECK( conv_ast );
1914       c_ast_gibberish( conv_ast, C_GIB_DECL, cdecl_fout );
1915       if ( opt_semicolon )
1916         FPUTC( ';', cdecl_fout );
1917       FPUTC( '\n', cdecl_fout );
1918     }
1919 
1920   | Y_DECLARE error
1921     {
1922       if ( OPT_LANG_IS(CPP_ANY) )
1923         elaborate_error( "name or %s expected", L_OPERATOR );
1924       else
1925         elaborate_error( "name expected" );
1926     }
1927   ;
1928 
1929 storage_class_list_english_stid_opt
1930   : /* empty */                   { $$ = TS_NONE; }
1931   | storage_class_list_english_stid_opt storage_class_english_stid
1932     {
1933       DUMP_START( "storage_class_list_english_stid_opt",
1934                   "storage_class_list_english_stid_opt "
1935                   "storage_class_english_stid" );
1936       DUMP_TID( "storage_class_list_english_stid_opt", $1 );
1937       DUMP_TID( "storage_class_english_stid", $2 );
1938 
1939       $$ = $1;
1940       C_TID_ADD( &$$, $2, @2 );
1941 
1942       DUMP_TID( "storage_class_list_english_stid_opt", $$ );
1943       DUMP_END();
1944     }
1945   ;
1946 
1947 storage_class_english_stid
1948   : Y_AUTO_STORAGE
1949   | Y_APPLE___BLOCK
1950   | Y_CONST Y_EVALUATION          { $$ = TS_CONSTEVAL; }
1951   | Y_CONST Y_EXPRESSION          { $$ = TS_CONSTEXPR; }
1952   | Y_CONST Y_INITIALIZATION      { $$ = TS_CONSTINIT; }
1953   | Y_CONSTEVAL
1954   | Y_CONSTEXPR
1955   | Y_CONSTINIT
1956   | Y_DEFAULT
1957   | Y_DELETE
1958   | Y_EXPLICIT
1959   | Y_EXPORT
1960   | Y_EXTERN
1961   | Y_EXTERN linkage_stid linkage_opt
1962     {
1963       $$ = $2;
1964     }
1965   | Y_FINAL
1966   | Y_FRIEND
1967   | Y_INLINE
1968   | Y_MUTABLE
1969   | Y_NO Y_EXCEPT                 { $$ = TS_NOEXCEPT; }
1970   | Y_NOEXCEPT
1971   | Y_OVERRIDE
1972 //| Y_REGISTER                          // in type_modifier_list_english_type
1973   | Y_STATIC
1974   | Y_THREAD local_exp            { $$ = TS_THREAD_LOCAL; }
1975   | Y__THREAD_LOCAL
1976   | Y_THREAD_LOCAL
1977   | Y_THROW
1978   | Y_TYPEDEF
1979   | Y_VIRTUAL
1980   | Y_PURE virtual_stid_exp       { $$ = TS_PURE_VIRTUAL | $2; }
1981   ;
1982 
1983 attribute_english_atid
1984   : Y_CARRIES dependency_exp      { $$ = TA_CARRIES_DEPENDENCY; }
1985   | Y_CARRIES_DEPENDENCY
1986   | Y_DEPRECATED
1987   | Y_MAYBE unused_exp            { $$ = TA_MAYBE_UNUSED; }
1988   | Y_MAYBE_UNUSED
1989   | Y_NO Y_DISCARD                { $$ = TA_NODISCARD; }
1990   | Y_NODISCARD
1991   | Y_NO Y_RETURN                 { $$ = TA_NORETURN; }
1992   | Y__NORETURN
1993   | Y_NORETURN
1994   | Y_NO Y_UNIQUE address_exp     { $$ = TA_NO_UNIQUE_ADDRESS; }
1995   | Y_NO_UNIQUE_ADDRESS
1996   ;
1997 
1998 linkage_stid
1999   : str_lit
2000     {
2001       bool ok = true;
2002 
2003       if ( strcmp( $1, "C" ) == 0 )
2004         $$ = TS_EXTERN_C;
2005       else if ( strcmp( $1, "C++" ) == 0 )
2006         $$ = TS_NONE;
2007       else {
2008         print_error( &@1, "\"%s\": unknown linkage language", $1 );
2009         print_hint( "\"C\" or \"C++\"" );
2010         ok = false;
2011       }
2012 
2013       free( $1 );
2014       if ( !ok )
2015         PARSE_ABORT();
2016     }
2017   ;
2018 
2019 linkage_opt
2020   : /* empty */
2021   | Y_LINKAGE
2022   ;
2023 
2024 udc_storage_class_list_english_type_opt
2025   : /* empty */                   { $$ = T_NONE; }
2026   | udc_storage_class_list_english_type_opt udc_storage_class_english_type
2027     {
2028       DUMP_START( "udc_storage_class_list_english_type_opt",
2029                   "udc_storage_class_list_english_type_opt "
2030                   "udc_storage_class_english_type" );
2031       DUMP_TYPE( "udc_storage_class_list_english_type_opt", $1 );
2032       DUMP_TYPE( "udc_storage_class_english_type", $2 );
2033 
2034       $$ = $1;
2035       C_TYPE_ADD( &$$, &$2, @2 );
2036 
2037       DUMP_TYPE( "udc_storage_class_list_english_type_opt", $$ );
2038       DUMP_END();
2039     }
2040   ;
2041 
2042 udc_storage_class_english_type
2043   : attribute_english_atid        { $$ = C_TYPE_LIT_A( $1 ); }
2044   | udc_storage_class_english_stid
2045     {
2046       $$ = C_TYPE_LIT_S( $1 );
2047     }
2048   ;
2049 
2050   /*
2051    * We need a seperate storage class set for user-defined conversion operators
2052    * without "delete" to eliminiate a shift/reduce conflict; shift:
2053    *
2054    *      declare delete as ...
2055    *
2056    * where "delete" is the operator; and reduce:
2057    *
2058    *      declare delete[d] user-defined conversion operator ...
2059    *
2060    * where "delete" is storage-class-like.  The "delete" can safely be removed
2061    * since only special members can be deleted anyway.
2062    */
2063 udc_storage_class_english_stid
2064   : Y_CONSTEVAL
2065   | Y_CONSTEXPR
2066   | Y_CONSTINIT
2067   | Y_EXPLICIT
2068   | Y_EXPORT
2069   | Y_FINAL
2070   | Y_FRIEND
2071   | Y_INLINE
2072   | Y_NOEXCEPT
2073   | Y_OVERRIDE
2074   | Y_THROW
2075   | Y_VIRTUAL
2076   | Y_PURE virtual_stid_exp       { $$ = TS_PURE_VIRTUAL | $2; }
2077   ;
2078 
2079 alignas_or_width_decl_english_ast
2080   : decl_english_ast              { $$ = $1; }
2081 
2082   | decl_english_ast alignas_specifier_english
2083     {
2084       $$ = $1;
2085       $$->align = $2;
2086       $$->loc = @$;
2087     }
2088 
2089   | decl_english_ast width_specifier_english
2090     { //
2091       // This check has to be done now in the parser rather than later in the
2092       // AST since we need to use the builtin union member now.
2093       //
2094       if ( !c_ast_is_builtin_any( $1, TB_ANY_INTEGRAL ) ) {
2095         print_error( &@2, "bit-field type must be integral\n" );
2096         PARSE_ABORT();
2097       }
2098 
2099       $$ = $1;
2100       $$->loc = @$;
2101       $$->as.builtin.bit_width = (c_bit_width_t)$2;
2102     }
2103   ;
2104 
2105 alignas_specifier_english
2106   : Y_ALIGNED as_or_to_opt Y_INT_LIT bytes_opt
2107     {
2108       $$.kind = C_ALIGNAS_EXPR;
2109       $$.loc = @1;
2110       $$.as.expr = (unsigned)$3;
2111     }
2112   | Y_ALIGNED as_or_to_opt decl_english_ast
2113     {
2114       $$.kind = C_ALIGNAS_TYPE;
2115       $$.loc = @1;
2116       $$.as.type_ast = $3;
2117     }
2118   | Y_ALIGNED as_or_to_opt error
2119     {
2120       MEM_ZERO( &$$ );
2121       $$.loc = @1;
2122       elaborate_error( "integer or type expected" );
2123     }
2124   ;
2125 
2126 as_or_to_opt
2127   : /* empty */
2128   | Y_AS
2129   | Y_TO
2130   ;
2131 
2132 bytes_opt
2133   : /* empty */
2134   | Y_BYTES
2135   ;
2136 
2137 width_specifier_english
2138   : Y_WIDTH int_exp bits_opt
2139     { //
2140       // This check has to be done now in the parser rather than later in the
2141       // AST since we use 0 to mean "no bit-field."
2142       //
2143       if ( $2 == 0 ) {
2144         print_error( &@2, "bit-field width must be > 0\n" );
2145         PARSE_ABORT();
2146       }
2147       $$ = $2;
2148     }
2149   ;
2150 
2151 bits_opt
2152   : /* empty */
2153   | Y_BITS
2154   ;
2155 
2156 /// define command ////////////////////////////////////////////////////////////
2157 
2158 define_command
2159   : Y_DEFINE sname_english_exp as_exp storage_class_list_english_stid_opt
2160     decl_english_ast
2161     {
2162       DUMP_START( "define_command",
2163                   "DEFINE sname_english AS "
2164                   "storage_class_list_english_stid_opt decl_english_ast" );
2165       DUMP_SNAME( "sname", $2 );
2166       DUMP_TID( "storage_class_list_english_stid_opt", $4 );
2167       DUMP_AST( "decl_english_ast", $5 );
2168 
2169       c_sname_set( &$5->sname, &$2 );
2170 
2171       if ( $5->kind == K_NAME ) {       // see the comment in "declare_command"
2172         assert( !c_sname_empty( &$5->sname ) );
2173         print_error_unknown_name( &@5, &$5->sname );
2174         PARSE_ABORT();
2175       }
2176 
2177       //
2178       // Explicitly add TS_TYPEDEF to prohibit cases like:
2179       //
2180       //      define eint as extern int
2181       //      define rint as register int
2182       //      define sint as static int
2183       //      ...
2184       //
2185       //  i.e., a defined type with a storage class.  Once the semantic checks
2186       // pass, remove the TS_TYPEDEF.
2187       //
2188       if ( !c_type_add( &$5->type, &T_TS_TYPEDEF, &@4 ) ||
2189            !c_type_add_tid( &$5->type, $4, &@4 ) ||
2190            !c_ast_check( $5 ) ) {
2191         PARSE_ABORT();
2192       }
2193       PJL_IGNORE_RV( c_ast_take_type_any( $5, &T_TS_TYPEDEF ) );
2194 
2195       if ( c_type_is_tid_any( &$5->type, TB_ANY_SCOPE ) )
2196         c_sname_set_local_type( &$5->sname, &$5->type );
2197       c_sname_fill_in_namespaces( &$5->sname );
2198 
2199       DUMP_AST( "defined.ast", $5 );
2200 
2201       if ( !c_sname_check( &$5->sname, &@2 ) )
2202         PARSE_ABORT();
2203       if ( !add_type( L_DEFINE, $5, &@5 ) )
2204         PARSE_ABORT();
2205 
2206       DUMP_END();
2207     }
2208   ;
2209 
2210 /// explain command ///////////////////////////////////////////////////////////
2211 
2212 explain_command
2213     /*
2214      * C-style cast.
2215      */
2216   : explain c_style_cast_c
2217 
2218     /*
2219      * New C++-style cast.
2220      */
2221   | explain new_style_cast_c
2222 
2223     /*
2224      * Common typed declaration, e.g.: T x.
2225      */
2226   | explain typed_declaration_c
2227 
2228     /*
2229      * Common declaration with alignas, e.g.: alignas(8) T x.
2230      */
2231   | explain aligned_declaration_c
2232 
2233     /*
2234      * asm declaration -- not supported.
2235      */
2236   | explain asm_declaration_c
2237 
2238     /*
2239      * C++ file-scope constructor definition, e.g.: S::S([params]).
2240      */
2241   | explain file_scope_constructor_decl_c
2242 
2243     /*
2244      * C++ in-class destructor declaration, e.g.: ~S().
2245      */
2246   | explain destructor_decl_c
2247 
2248     /*
2249      * C++ file scope destructor definition, e.g.: S::~S().
2250      */
2251   | explain file_scope_destructor_decl_c
2252 
2253     /*
2254      * K&R C implicit int function and C++ in-class constructor declaration.
2255      */
2256   | explain knr_func_or_constructor_decl_c
2257 
2258     /*
2259      * Template declaration -- not supported.
2260      */
2261   | explain template_declaration_c
2262 
2263     /*
2264      * Common C++ declaration with typename (without alignas), e.g.:
2265      *
2266      *      explain typename T::U x
2267      *
2268      * (We can't use typename_flag_opt because it would introduce more
2269      * shift/reduce conflicts.)
2270      */
2271   | explain Y_TYPENAME { in_attr.typename = true; } typed_declaration_c
2272 
2273     /*
2274      * User-defined conversion operator declaration without a storage-class-
2275      * like part.  This is for a case like:
2276      *
2277      *      explain operator int()
2278      *
2279      * User-defined conversion operator declarations with a storage-class-like
2280      * part, e.g.:
2281      *
2282      *      explain explicit operator int()
2283      *
2284      * are handled by the common declaration rule.
2285      */
2286   | explain user_defined_conversion_decl_c_astp
2287     {
2288       DUMP_START( "explain_command",
2289                   "EXPLAIN user_defined_conversion_decl_c_astp" );
2290       DUMP_AST( "user_defined_conversion_decl_c_astp", $2.ast );
2291       DUMP_END();
2292 
2293       C_AST_CHECK( $2.ast );
2294       c_ast_explain_declaration( $2.ast, cdecl_fout );
2295     }
2296 
2297     /*
2298      * C++ using declaration.
2299      */
2300   | explain extern_linkage_c_stid_opt using_decl_c_ast
2301     {
2302       DUMP_START( "explain_command",
2303                   "EXPLAIN extern_linkage_c_stid_opt using_decl_c_ast" );
2304       DUMP_TID( "extern_linkage_c_stid_opt", $2 );
2305       DUMP_AST( "using_decl_c_ast", $3 );
2306       DUMP_END();
2307 
2308       C_TYPE_ADD_TID( &$3->type, $2, @2 );
2309 
2310       C_AST_CHECK( $3 );
2311       c_ast_explain_declaration( $3, cdecl_fout );
2312     }
2313 
2314     /*
2315      * If we match an sname, it means it wasn't an sname for a type (otherwise
2316      * we would have matched the "Common declaration" case above).
2317      */
2318   | explain sname_c
2319     {
2320       print_error_unknown_name( &@2, &$2 );
2321       c_sname_cleanup( &$2 );
2322       PARSE_ABORT();
2323     }
2324 
2325   | explain error
2326     {
2327       elaborate_error( "cast or declaration expected" );
2328     }
2329   ;
2330 
2331 explain
2332   : Y_EXPLAIN
2333     { //
2334       // Set our mode to deciphering gibberish into English and specifically
2335       // tell the lexer to return cdecl keywords (e.g., "func") as ordinary
2336       // names, otherwise gibberish like:
2337       //
2338       //      int func(void);
2339       //
2340       // would result in a parser error.
2341       //
2342       gibberish_to_english();
2343     }
2344   ;
2345 
2346 /// help command //////////////////////////////////////////////////////////////
2347 
2348 help_command
2349   : Y_HELP help_what_opt          { print_help( $2 ); }
2350   ;
2351 
2352 help_what_opt
2353   : /* empty */                   { $$ = CDECL_HELP_COMMANDS; }
2354   | Y_COMMANDS                    { $$ = CDECL_HELP_COMMANDS; }
2355   | Y_ENGLISH                     { $$ = CDECL_HELP_ENGLISH;  }
2356   | Y_OPTIONS                     { $$ = CDECL_HELP_OPTIONS;  }
2357   | error
2358     {
2359       elaborate_error(
2360         "\"%s\", \"%s\", or \"%s\" expected",
2361         L_COMMANDS, L_ENGLISH, L_OPTIONS
2362       );
2363     }
2364   ;
2365 
2366 /// quit command //////////////////////////////////////////////////////////////
2367 
2368 quit_command
2369   : Y_QUIT                        { quit(); }
2370   ;
2371 
2372 /// scope (enum, class, struct, union, namespace) command /////////////////////
2373 
2374 scoped_command
2375   : scoped_declaration_c
2376   ;
2377 
2378 /// set command ///////////////////////////////////////////////////////////////
2379 
2380 set_command
2381   : Y_SET
2382     {
2383       if ( !option_set( NULL, NULL, NULL, NULL ) )
2384         PARSE_ABORT();
2385     }
2386   | Y_SET set_option_list
2387   ;
2388 
2389 set_option_list
2390   : set_option_list set_option
2391   | set_option
2392   ;
2393 
2394 set_option
2395   : Y_SET_OPTION set_option_value_opt
2396     {
2397       bool const ok = option_set( $1, &@1, $2, &@2 );
2398       free( $1 );
2399       free( $2 );
2400       if ( !ok )
2401         PARSE_ABORT();
2402     }
2403   ;
2404 
2405 set_option_value_opt
2406   : /* empty */                   { $$ = NULL; }
2407   | '=' Y_SET_OPTION              { $$ = $2; @$ = @2; }
2408   | '=' error
2409     {
2410       $$ = NULL;
2411       elaborate_error( "option value expected" );
2412     }
2413   ;
2414 
2415 /// show command //////////////////////////////////////////////////////////////
2416 
2417 show_command
2418   : Y_SHOW any_typedef show_format_opt
2419     {
2420       DUMP_START( "show_command", "SHOW any_typedef show_format_opt" );
2421       DUMP_AST( "any_typedef.ast", $2->ast );
2422       DUMP_INT( "show_format_opt", $3 );
2423       DUMP_END();
2424 
2425       if ( $3 == C_GIB_NONE )
2426         c_ast_explain_type( $2->ast, cdecl_fout );
2427       else
2428         c_typedef_gibberish( $2, $3, cdecl_fout );
2429     }
2430 
2431   | Y_SHOW any_typedef Y_AS show_format_exp
2432     {
2433       DUMP_START( "show_command", "SHOW any_typedef AS show_format_exp" );
2434       DUMP_AST( "any_typedef.ast", $2->ast );
2435       DUMP_INT( "show_format_exp", $4 );
2436       DUMP_END();
2437 
2438       c_typedef_gibberish( $2, $4, cdecl_fout );
2439     }
2440 
2441   | Y_SHOW show_which_types_mask_opt glob_opt show_format_opt
2442     {
2443       show_type_info_t sti;
2444       sti_init( &sti, $2, $3, $4 );
2445       c_typedef_visit( &show_type_visitor, &sti );
2446       sti_cleanup( &sti );
2447       free( $3 );
2448     }
2449 
2450   | Y_SHOW show_which_types_mask_opt glob_opt Y_AS show_format_exp
2451     {
2452       show_type_info_t sti;
2453       sti_init( &sti, $2, $3, $5 );
2454       c_typedef_visit( &show_type_visitor, &sti );
2455       sti_cleanup( &sti );
2456       free( $3 );
2457     }
2458 
2459   | Y_SHOW Y_NAME
2460     {
2461       static char const *const type_commands_knr[] = {
2462         L_DEFINE, L_STRUCT, L_TYPEDEF, L_UNION, NULL
2463       };
2464       static char const *const type_commands_c[] = {
2465         L_DEFINE, L_ENUM, L_STRUCT, L_TYPEDEF, L_UNION, NULL
2466       };
2467       static char const *const type_commands_cpp_pre11[] = {
2468         L_CLASS, L_DEFINE, L_ENUM, L_STRUCT, L_TYPEDEF, L_UNION, NULL
2469       };
2470       static char const *const type_commands_cpp11[] = {
2471         L_CLASS, L_DEFINE, L_ENUM, L_STRUCT, L_TYPEDEF, L_UNION, L_USING, NULL
2472       };
2473 
2474       char const *const *const type_commands =
2475         OPT_LANG_IS(C_KNR)     ? type_commands_knr :
2476         OPT_LANG_IS(C_ANY)     ? type_commands_c :
2477         opt_lang < LANG_CPP_11 ? type_commands_cpp_pre11 :
2478                                  type_commands_cpp11;
2479 
2480       print_error( &@2, "\"%s\": not defined as type via ", $2 );
2481       fprint_list( stderr, type_commands, /*elt_size=*/0, /*gets=*/NULL );
2482       print_suggestions( DYM_C_TYPES, $2 );
2483       EPUTC( '\n' );
2484       free( $2 );
2485       PARSE_ABORT();
2486     }
2487 
2488   | Y_SHOW error
2489     {
2490       elaborate_error(
2491         "type name or \"%s\", \"%s\", or \"%s\" expected",
2492         L_ALL, L_PREDEFINED, L_USER
2493       );
2494     }
2495   ;
2496 
2497 show_format
2498   : Y_ENGLISH                     { $$ = C_GIB_NONE; }
2499   | Y_TYPEDEF                     { $$ = C_GIB_TYPEDEF; }
2500   | Y_USING
2501     {
2502       if ( opt_lang < LANG_CPP_11 ) {
2503         print_error( &@1,
2504           "\"%s\" not supported%s\n",
2505           L_USING, c_lang_which( LANG_CPP_MIN(11) )
2506         );
2507         PARSE_ABORT();
2508       }
2509       $$ = C_GIB_USING;
2510     }
2511   ;
2512 
2513 show_format_exp
2514   : show_format
2515   | error
2516     {
2517       if ( opt_lang < LANG_CPP_11 )
2518         elaborate_error( "\"%s\" or \"%s\" expected", L_ENGLISH, L_TYPEDEF );
2519       else
2520         elaborate_error(
2521           "\"%s\", \"%s\", or \"%s\" expected", L_ENGLISH, L_TYPEDEF, L_USING
2522         );
2523     }
2524   ;
2525 
2526 show_format_opt
2527   : /* empty */                   { $$ = C_GIB_NONE; }
2528   | show_format
2529   ;
2530 
2531 show_which_types_mask_opt
2532   : /* empty */                   { $$ = SHOW_USER_TYPES; }
2533   | Y_ALL predefined_or_user_mask_opt
2534     {
2535       $$ = SHOW_ALL_TYPES |
2536            ($2 != 0 ? $2 : SHOW_PREDEFINED_TYPES | SHOW_USER_TYPES);
2537     }
2538   | Y_PREDEFINED                  { $$ = SHOW_PREDEFINED_TYPES; }
2539   | Y_USER                        { $$ = SHOW_USER_TYPES; }
2540   ;
2541 
2542 predefined_or_user_mask_opt
2543   : /* empty */                   { $$ = 0; }
2544   | Y_PREDEFINED                  { $$ = SHOW_PREDEFINED_TYPES; }
2545   | Y_USER                        { $$ = SHOW_USER_TYPES; }
2546   ;
2547 
2548 /// template command //////////////////////////////////////////////////////////
2549 
2550 template_command
2551   : template_declaration_c
2552   ;
2553 
2554 /// typedef command ///////////////////////////////////////////////////////////
2555 
2556 typedef_command
2557   : typedef_declaration_c
2558   ;
2559 
2560 /// using command /////////////////////////////////////////////////////////////
2561 
2562 using_command
2563   : using_declaration_c
2564   ;
2565 
2566 ///////////////////////////////////////////////////////////////////////////////
2567 //  C/C++ casts                                                              //
2568 ///////////////////////////////////////////////////////////////////////////////
2569 
2570 /// Gibberish C-style cast ////////////////////////////////////////////////////
2571 
2572 c_style_cast_c
2573   : '(' type_c_ast
2574     {
2575       ia_type_ast_push( $2 );
2576     }
2577     cast_c_astp_opt rparen_exp sname_c_opt
2578     {
2579       ia_type_ast_pop();
2580 
2581       DUMP_START( "explain_command",
2582                   "EXPLAIN '(' type_c_ast cast_c_astp_opt ')' sname_c_opt" );
2583       DUMP_AST( "type_c_ast", $2 );
2584       DUMP_AST( "cast_c_astp_opt", $4.ast );
2585       DUMP_SNAME( "sname_c_opt", $6 );
2586 
2587       c_ast_t *const cast_ast = c_ast_patch_placeholder( $2, $4.ast );
2588       cast_ast->cast_kind = C_CAST_C;
2589 
2590       DUMP_AST( "explain_command", cast_ast );
2591       DUMP_END();
2592 
2593       bool const ok = c_ast_check( cast_ast );
2594       if ( ok ) {
2595         FPUTS( L_CAST, cdecl_fout );
2596         if ( !c_sname_empty( &$6 ) ) {
2597           FPUTC( ' ', cdecl_fout );
2598           c_sname_english( &$6, cdecl_fout );
2599         }
2600         FPRINTF( cdecl_fout, " %s ", L_INTO );
2601         c_ast_english( cast_ast, cdecl_fout );
2602         FPUTC( '\n', cdecl_fout );
2603       }
2604 
2605       c_sname_cleanup( &$6 );
2606       if ( !ok )
2607         PARSE_ABORT();
2608     }
2609   ;
2610 
2611 /// Gibberish C++-style cast //////////////////////////////////////////////////
2612 
2613 new_style_cast_c
2614   : new_style_cast_c lt_exp type_c_ast
2615     {
2616       ia_type_ast_push( $3 );
2617     }
2618     cast_c_astp_opt gt_exp lparen_exp sname_c_exp rparen_exp
2619     {
2620       ia_type_ast_pop();
2621 
2622       char const *const cast_literal = c_cast_english( $1 );
2623 
2624       DUMP_START( "explain_command",
2625                   "EXPLAIN new_style_cast_c"
2626                   "'<' type_c_ast cast_c_astp_opt '>' '(' sname ')'" );
2627       DUMP_STR( "new_style_cast_c", cast_literal );
2628       DUMP_AST( "type_c_ast", $3 );
2629       DUMP_AST( "cast_c_astp_opt", $5.ast );
2630       DUMP_SNAME( "sname", $8 );
2631 
2632       c_ast_t *const cast_ast = c_ast_patch_placeholder( $3, $5.ast );
2633       cast_ast->cast_kind = $1;
2634 
2635       DUMP_AST( "explain_command", cast_ast );
2636       DUMP_END();
2637 
2638       bool ok = false;
2639 
2640       if ( unsupported( LANG_CPP_ANY ) ) {
2641         print_error( &@1, "%s_cast not supported in C\n", cast_literal );
2642       }
2643       else if ( (ok = c_ast_check( cast_ast )) ) {
2644         FPRINTF( cdecl_fout, "%s %s ", cast_literal, L_CAST );
2645         c_sname_english( &$8, cdecl_fout );
2646         FPRINTF( cdecl_fout, " %s ", L_INTO );
2647         c_ast_english( cast_ast, cdecl_fout );
2648         FPUTC( '\n', cdecl_fout );
2649       }
2650 
2651       c_sname_cleanup( &$8 );
2652       if ( !ok )
2653         PARSE_ABORT();
2654     }
2655   ;
2656 
2657 new_style_cast_c
2658   : Y_CONST_CAST                  { $$ = C_CAST_CONST;        }
2659   | Y_DYNAMIC_CAST                { $$ = C_CAST_DYNAMIC;      }
2660   | Y_REINTERPRET_CAST            { $$ = C_CAST_REINTERPRET;  }
2661   | Y_STATIC_CAST                 { $$ = C_CAST_STATIC;       }
2662   ;
2663 
2664 ///////////////////////////////////////////////////////////////////////////////
2665 //  C/C++ DECLARATIONS                                                       //
2666 ///////////////////////////////////////////////////////////////////////////////
2667 
2668 /// Gibberish C/C++ aligned declaration ///////////////////////////////////////
2669 
2670 aligned_declaration_c
2671   : alignas_specifier_c { in_attr.align = $1; }
2672     typename_flag_opt { in_attr.typename = $3; }
2673     typed_declaration_c
2674   ;
2675 
2676 alignas_specifier_c
2677   : alignas lparen_exp Y_INT_LIT rparen_exp
2678     {
2679       DUMP_START( "alignas_specifier_c", "ALIGNAS '(' Y_INT_LIT ')'" );
2680       DUMP_INT( "INT_LIT", $3 );
2681       DUMP_END();
2682 
2683       $$.kind = C_ALIGNAS_EXPR;
2684       $$.loc = @1;
2685       $$.as.expr = (unsigned)$3;
2686     }
2687 
2688   | alignas lparen_exp type_c_ast { ia_type_ast_push( $3 ); }
2689     cast_c_astp_opt rparen_exp
2690     {
2691       ia_type_ast_pop();
2692 
2693       DUMP_START( "alignas_specifier_c",
2694                   "ALIGNAS '(' type_c_ast cast_c_astp_opt ')'" );
2695       DUMP_AST( "type_c_ast", $3 );
2696       DUMP_AST( "cast_c_astp_opt", $5.ast );
2697       DUMP_END();
2698 
2699       c_ast_t *const type_ast = c_ast_patch_placeholder( $3, $5.ast );
2700 
2701       $$.kind = C_ALIGNAS_TYPE;
2702       $$.loc = @1;
2703       $$.as.type_ast = type_ast;
2704     }
2705 
2706   | alignas lparen_exp error ')'
2707     {
2708       elaborate_error( "integer or type expected" );
2709     }
2710   ;
2711 
2712 alignas
2713   : Y__ALIGNAS
2714   | Y_ALIGNAS
2715   ;
2716 
2717 /// Gibberish C/C++ asm declaration ///////////////////////////////////////////
2718 
2719 asm_declaration_c
2720   : Y_ASM lparen_exp str_lit_exp rparen_exp
2721     {
2722       free( $3 );
2723       print_error( &@1, "%s declarations not supported by %s\n", L_ASM, CDECL );
2724       PARSE_ABORT();
2725     }
2726   ;
2727 
2728 /// Gibberish C/C++ scoped declarations ///////////////////////////////////////
2729 
2730 scoped_declaration_c
2731   : class_struct_union_declaration_c
2732   | enum_declaration_c
2733   | namespace_declaration_c
2734   ;
2735 
2736 class_struct_union_declaration_c
2737     /*
2738      * C++ scoped declaration, e.g.: class C { typedef int I; };
2739      */
2740   : class_struct_union_btid
2741     {
2742       CHECK_NESTED_TYPE_OK( &@1 );
2743       gibberish_to_english();           // see the comment in "explain"
2744     }
2745     any_sname_c_exp
2746     {
2747       c_type_t const *const cur_type =
2748         c_sname_local_type( &in_attr.current_scope );
2749       if ( c_type_is_tid_any( cur_type, TB_ANY_CLASS ) ) {
2750         char const *const cur_name =
2751           c_sname_local_name( &in_attr.current_scope );
2752         char const *const mbr_name = c_sname_local_name( &$3 );
2753         if ( strcmp( mbr_name, cur_name ) == 0 ) {
2754           print_error( &@3,
2755             "\"%s\": %s has the same name as its enclosing %s\n",
2756             mbr_name, L_MEMBER, c_type_name_c( cur_type )
2757           );
2758           c_sname_cleanup( &$3 );
2759           PARSE_ABORT();
2760         }
2761       }
2762 
2763       DUMP_START( "class_struct_union_declaration_c",
2764                   "class_struct_union_btid sname '{' "
2765                   "in_scope_declaration_c_opt "
2766                   "'}' ';'" );
2767       DUMP_SNAME( "(current_scope)", in_attr.current_scope );
2768       DUMP_TID( "class_struct_union_btid", $1 );
2769       DUMP_SNAME( "any_sname_c", $3 );
2770 
2771       c_sname_append_sname( &in_attr.current_scope, &$3 );
2772       c_sname_set_local_type( &in_attr.current_scope, &C_TYPE_LIT_B( $1 ) );
2773       if ( !c_sname_check( &in_attr.current_scope, &@3 ) )
2774         PARSE_ABORT();
2775 
2776       c_ast_t *const csu_ast = c_ast_new_gc( K_ENUM_CLASS_STRUCT_UNION, &@3 );
2777       csu_ast->sname = c_sname_dup( &in_attr.current_scope );
2778       c_sname_append_name(
2779         &csu_ast->as.ecsu.ecsu_sname,
2780         check_strdup( c_sname_local_name( &in_attr.current_scope ) )
2781       );
2782       csu_ast->type.btids = c_tid_check( $1, C_TPID_BASE );
2783 
2784       DUMP_AST( "class_struct_union_declaration_c", csu_ast );
2785       DUMP_END();
2786 
2787       if ( !add_type( c_tid_name_c( $1 ), csu_ast, &@1 ) )
2788         PARSE_ABORT();
2789     }
2790     brace_in_scope_declaration_c_opt
2791   ;
2792 
2793 enum_declaration_c
2794     /*
2795      * C/C++ enum declaration, e.g.: enum E;
2796      */
2797   : enum_btid
2798     {
2799       CHECK_NESTED_TYPE_OK( &@1 );
2800       gibberish_to_english();           // see the comment in "explain"
2801     }
2802     any_sname_c_exp enum_fixed_type_c_ast_opt
2803     {
2804       DUMP_START( "enum_declaration_c", "enum_btid sname ;" );
2805       DUMP_TID( "enum_btid", $1 );
2806       DUMP_SNAME( "any_sname_c", $3 );
2807       DUMP_AST( "enum_fixed_type_c_ast_opt", $4 );
2808 
2809       c_sname_t enum_sname = c_sname_dup( &in_attr.current_scope );
2810       c_sname_append_sname( &enum_sname, &$3 );
2811       c_sname_set_local_type( &enum_sname, &C_TYPE_LIT_B( $1 ) );
2812       if ( !c_sname_check( &enum_sname, &@3 ) ) {
2813         c_sname_cleanup( &enum_sname );
2814         PARSE_ABORT();
2815       }
2816 
2817       c_ast_t *const enum_ast = c_ast_new_gc( K_ENUM_CLASS_STRUCT_UNION, &@3 );
2818       enum_ast->sname = enum_sname;
2819       enum_ast->type.btids = c_tid_check( $1, C_TPID_BASE );
2820       enum_ast->as.ecsu.of_ast = $4;
2821       c_sname_append_name(
2822         &enum_ast->as.ecsu.ecsu_sname,
2823         check_strdup( c_sname_local_name( &enum_sname ) )
2824       );
2825 
2826       DUMP_AST( "enum_declaration_c", enum_ast );
2827       DUMP_END();
2828 
2829       if ( !add_type( c_tid_name_c( $1 ), enum_ast, &@1 ) )
2830         PARSE_ABORT();
2831     }
2832   ;
2833 
2834 namespace_declaration_c
2835     /*
2836      * C++ namespace declaration, e.g.: namespace NS { typedef int I; }
2837      */
2838   : namespace_type
2839     {
2840       gibberish_to_english();           // see the comment in "explain"
2841     }
2842     namespace_sname_c_exp
2843     {
2844       DUMP_START( "namespace_declaration_c",
2845                   "namespace_type sname '{' "
2846                   "in_scope_declaration_c_opt "
2847                   "'}' [';']" );
2848       DUMP_SNAME( "(current_scope)", in_attr.current_scope );
2849       DUMP_TYPE( "namespace_type", $1 );
2850       DUMP_SNAME( "any_sname_c", $3 );
2851       DUMP_END();
2852 
2853       //
2854       // Nested namespace declarations are supported only in C++17 and later.
2855       // (However, we always allow them in configuration files.)
2856       //
2857       // This check has to be done now in the parser rather than later in the
2858       // AST because the AST has no "memory" of how a namespace was
2859       // constructed.
2860       //
2861       if ( c_sname_count( &$3 ) > 1 && unsupported( LANG_CPP_MIN(17) ) ) {
2862         print_error( &@3,
2863           "nested %s declarations not supported%s\n",
2864           L_NAMESPACE, c_lang_which( LANG_CPP_MIN(17) )
2865         );
2866         c_sname_cleanup( &$3 );
2867         PARSE_ABORT();
2868       }
2869 
2870       //
2871       // The namespace type (plain namespace or inline namespace) has to be
2872       // split across the namespace sname: only the storage classes (for
2873       // TS_INLINE) has to be or'd with the first scope-type of the sname ...
2874       //
2875       c_type_t const *const sname_first_type = c_sname_first_type( &$3 );
2876       c_sname_set_first_type(
2877         &$3,
2878         &C_TYPE_LIT(
2879           sname_first_type->btids,
2880           sname_first_type->stids | $1.stids,
2881           sname_first_type->atids
2882         )
2883       );
2884       //
2885       // ... and only the base types (for TB_NAMESPACE) has to be or'd with the
2886       // local scope type of the sname.
2887       //
2888       c_type_t const *const sname_local_type = c_sname_local_type( &$3 );
2889       c_sname_set_local_type(
2890         &$3,
2891         &C_TYPE_LIT(
2892           sname_local_type->btids | $1.btids,
2893           sname_local_type->stids,
2894           sname_local_type->atids
2895         )
2896       );
2897 
2898       c_sname_append_sname( &in_attr.current_scope, &$3 );
2899       if ( !c_sname_check( &in_attr.current_scope, &@3 ) )
2900         PARSE_ABORT();
2901     }
2902     brace_in_scope_declaration_c_exp
2903   ;
2904 
2905 namespace_sname_c_exp
2906   : namespace_sname_c
2907   | namespace_typedef_sname_c
2908   | error
2909     {
2910       c_sname_init( &$$ );
2911       elaborate_error( "name expected" );
2912     }
2913   ;
2914 
2915   /*
2916    * A version of sname_c for namespace declarations that has an extra
2917    * production for C++20 nested inline namespaces.  See sname_c for detailed
2918    * comments.
2919    */
2920 namespace_sname_c
2921   : namespace_sname_c Y_COLON2 Y_NAME
2922     {
2923       DUMP_START( "namespace_sname_c", "sname_c '::' NAME" );
2924       DUMP_SNAME( "namespace_sname_c", $1 );
2925       DUMP_STR( "name", $3 );
2926 
2927       $$ = $1;
2928       c_sname_append_name( &$$, $3 );
2929       c_sname_set_local_type( &$$, &C_TYPE_LIT_B( TB_NAMESPACE ) );
2930 
2931       DUMP_SNAME( "namespace_sname_c", $$ );
2932       DUMP_END();
2933     }
2934 
2935   | namespace_sname_c Y_COLON2 any_typedef
2936     {
2937       DUMP_START( "namespace_sname_c", "namespace_sname_c '::' any_typedef" );
2938       DUMP_SNAME( "namespace_sname_c", $1 );
2939       DUMP_AST( "any_typedef.ast", $3->ast );
2940 
2941       $$ = $1;
2942       c_sname_set_local_type( &$$, &C_TYPE_LIT_B( TB_NAMESPACE ) );
2943       c_sname_t temp_sname = c_sname_dup( &$3->ast->sname );
2944       c_sname_append_sname( &$$, &temp_sname );
2945 
2946       DUMP_SNAME( "namespace_sname_c", $$ );
2947       DUMP_END();
2948     }
2949 
2950   | namespace_sname_c Y_COLON2 Y_INLINE name_exp
2951     {
2952       DUMP_START( "namespace_sname_c", "sname_c '::' NAME INLINE NAME" );
2953       DUMP_SNAME( "namespace_sname_c", $1 );
2954       DUMP_STR( "name", $4 );
2955 
2956       $$ = $1;
2957       c_sname_append_name( &$$, $4 );
2958       c_sname_set_local_type( &$$, &C_TYPE_LIT( TB_NAMESPACE, $3, TA_NONE ) );
2959 
2960       DUMP_SNAME( "namespace_sname_c", $$ );
2961       DUMP_END();
2962     }
2963 
2964   | Y_NAME
2965     {
2966       DUMP_START( "namespace_sname_c", "NAME" );
2967       DUMP_STR( "NAME", $1 );
2968 
2969       c_sname_init_name( &$$, $1 );
2970       c_sname_set_local_type( &$$, &C_TYPE_LIT_B( TB_NAMESPACE ) );
2971 
2972       DUMP_SNAME( "sname_c", $$ );
2973       DUMP_END();
2974     }
2975   ;
2976 
2977   /*
2978    * A version of typedef_sname_c for namespace declarations that has an extra
2979    * production for C++20 nested inline namespaces.  See typedef_sname_c for
2980    * detailed comments.
2981    */
2982 namespace_typedef_sname_c
2983   : namespace_typedef_sname_c Y_COLON2 sname_c
2984     {
2985       DUMP_START( "namespace_typedef_sname_c",
2986                   "namespace_typedef_sname_c '::' sname_c" );
2987       DUMP_SNAME( "namespace_typedef_sname_c", $1 );
2988       DUMP_SNAME( "sname_c", $3 );
2989 
2990       $$ = $1;
2991       c_sname_append_sname( &$$, &$3 );
2992 
2993       DUMP_SNAME( "typedef_sname_c", $$ );
2994       DUMP_END();
2995     }
2996 
2997   | namespace_typedef_sname_c Y_COLON2 any_typedef
2998     {
2999       DUMP_START( "namespace_typedef_sname_c",
3000                   "namespace_typedef_sname_c '::' any_typedef" );
3001       DUMP_SNAME( "namespace_typedef_sname_c", $1 );
3002       DUMP_AST( "any_typedef", $3->ast );
3003 
3004       $$ = $1;
3005       c_sname_set_local_type( &$$, c_sname_local_type( &$3->ast->sname ) );
3006       c_sname_t temp_sname = c_sname_dup( &$3->ast->sname );
3007       c_sname_append_sname( &$$, &temp_sname );
3008 
3009       DUMP_SNAME( "typedef_sname_c", $$ );
3010       DUMP_END();
3011     }
3012 
3013   | namespace_typedef_sname_c Y_COLON2 Y_INLINE name_exp
3014     {
3015       DUMP_START( "namespace_typedef_sname_c",
3016                   "namespace_typedef_sname_c '::' INLINE NAME" );
3017       DUMP_SNAME( "namespace_typedef_sname_c", $1 );
3018       DUMP_STR( "name", $4 );
3019 
3020       $$ = $1;
3021       c_sname_append_name( &$$, $4 );
3022       c_sname_set_local_type( &$$, &C_TYPE_LIT( TB_NAMESPACE, $3, TA_NONE ) );
3023 
3024       DUMP_SNAME( "namespace_typedef_sname_c", $$ );
3025       DUMP_END();
3026     }
3027 
3028   | any_typedef                   { $$ = c_sname_dup( &$1->ast->sname ); }
3029   ;
3030 
3031 brace_in_scope_declaration_c_exp
3032   : brace_in_scope_declaration_c
3033   | error
3034     {
3035       punct_expected( '{' );
3036     }
3037   ;
3038 
3039 brace_in_scope_declaration_c_opt
3040   : /* empty */
3041   | brace_in_scope_declaration_c
3042   ;
3043 
3044 brace_in_scope_declaration_c
3045   : '{' '}'
3046   | '{' in_scope_declaration_c_exp semi_opt rbrace_exp
3047   ;
3048 
3049 in_scope_declaration_c_exp
3050   : scoped_declaration_c
3051   | typedef_declaration_c semi_exp
3052   | using_declaration_c semi_exp
3053   | error
3054     {
3055       elaborate_error( "declaration expected" );
3056     }
3057   ;
3058 
3059 /// Gibberish C++ template declaration ////////////////////////////////////////
3060 
3061 template_declaration_c
3062   : Y_TEMPLATE
3063     {
3064       print_error( &@1,
3065         "%s declarations not supported by %s\n", L_TEMPLATE, CDECL
3066       );
3067       PARSE_ABORT();
3068     }
3069   ;
3070 
3071 /// Gibberish C/C++ typed declaration /////////////////////////////////////////
3072 
3073 typed_declaration_c
3074   : type_c_ast { ia_type_ast_push( $1 ); } decl_list_c_opt
3075     {
3076       ia_type_ast_pop();
3077     }
3078   ;
3079 
3080 /// Gibberish C/C++ typedef declaration ///////////////////////////////////////
3081 
3082 typedef_declaration_c
3083   : Y_TYPEDEF typename_flag_opt
3084     {
3085       CHECK_NESTED_TYPE_OK( &@1 );
3086       in_attr.typename = $2;
3087       gibberish_to_english();           // see the comment in "explain"
3088     }
3089     type_c_ast
3090     {
3091       if ( $2 && !c_ast_is_typename_ok( $4 ) )
3092         PARSE_ABORT();
3093 
3094       // see the comment in "define_command" about TS_TYPEDEF
3095       C_TYPE_ADD_TID( &$4->type, TS_TYPEDEF, @4 );
3096 
3097       //
3098       // We have to keep a pristine copy of the AST for the base type of the
3099       // typedef being declared in case multiple types are defined in the same
3100       // typedef.  For example, given:
3101       //
3102       //      typedef int I, *PI;
3103       //              ^
3104       // the "int" is the base type that needs to get patched twice to form two
3105       // types: I and PI.  Hence, we keep a pristine copy and then duplicate it
3106       // so every type gets a pristine copy.
3107       //
3108       assert( slist_empty( &in_attr.typedef_ast_list ) );
3109       slist_push_list_tail( &in_attr.typedef_ast_list, &gc_ast_list );
3110       in_attr.typedef_type_ast = $4;
3111       ia_type_ast_push( c_ast_dup( in_attr.typedef_type_ast, &gc_ast_list ) );
3112     }
3113     typedef_decl_list_c
3114     {
3115       ia_type_ast_pop();
3116     }
3117   ;
3118 
3119 typedef_decl_list_c
3120   : typedef_decl_list_c ','
3121     { //
3122       // We're defining another type in the same typedef so we need to replace
3123       // the current type AST inherited attribute with a new duplicate of the
3124       // pristine one we kept earlier.
3125       //
3126       ia_type_ast_pop();
3127       ia_type_ast_push( c_ast_dup( in_attr.typedef_type_ast, &gc_ast_list ) );
3128     }
3129     typedef_decl_c
3130 
3131   | typedef_decl_c
3132   ;
3133 
3134 typedef_decl_c
3135   : // in_attr: type_c_ast
3136     decl_c_astp
3137     {
3138       c_ast_t *const type_ast = ia_type_ast_peek();
3139 
3140       DUMP_START( "typedef_decl_c", "decl_c_astp" );
3141       DUMP_SNAME( "(current_scope)", in_attr.current_scope );
3142       DUMP_AST( "(type_c_ast)", type_ast );
3143       DUMP_AST( "decl_c_astp", $1.ast );
3144 
3145       c_ast_t *typedef_ast;
3146       c_sname_t temp_sname;
3147 
3148       if ( $1.ast->kind == K_TYPEDEF ) {
3149         //
3150         // This is for either of the following cases:
3151         //
3152         //      typedef int int32_t;
3153         //      typedef int32_t int_least32_t;
3154         //
3155         // that is: any type name followed by an existing typedef name.
3156         //
3157         typedef_ast = type_ast;
3158         if ( c_sname_empty( &typedef_ast->sname ) )
3159           typedef_ast->sname = c_sname_dup( &$1.ast->as.tdef.for_ast->sname );
3160       }
3161       else {
3162         //
3163         // This is for either of the following cases:
3164         //
3165         //      typedef int foo;
3166         //      typedef int32_t foo;
3167         //
3168         // that is: any type name followed by a new name.
3169         //
3170         typedef_ast = c_ast_patch_placeholder( type_ast, $1.ast );
3171         temp_sname = c_ast_take_name( $1.ast );
3172         c_sname_set( &typedef_ast->sname, &temp_sname );
3173       }
3174 
3175       C_AST_CHECK( typedef_ast );
3176       // see the comment in "define_command" about TS_TYPEDEF
3177       PJL_IGNORE_RV( c_ast_take_type_any( typedef_ast, &T_TS_TYPEDEF ) );
3178 
3179       if ( c_sname_count( &typedef_ast->sname ) > 1 ) {
3180         print_error( &@1,
3181           "%s names can not be scoped; use: %s %s { %s ... }\n",
3182           L_TYPEDEF, L_NAMESPACE, c_sname_scope_name( &typedef_ast->sname ),
3183           L_TYPEDEF
3184         );
3185         PARSE_ABORT();
3186       }
3187 
3188       temp_sname = c_sname_dup( &in_attr.current_scope );
3189       c_sname_prepend_sname( &typedef_ast->sname, &temp_sname );
3190 
3191       DUMP_AST( "typedef_decl_c", typedef_ast );
3192       DUMP_END();
3193 
3194       if ( !add_type( L_TYPEDEF, typedef_ast, &@1 ) )
3195         PARSE_ABORT();
3196     }
3197   ;
3198 
3199 /// Gibberish C++ using declaration ///////////////////////////////////////////
3200 
3201 using_declaration_c
3202   : using_decl_c_ast
3203     {
3204       // see the comment in "define_command" about TS_TYPEDEF
3205       PJL_IGNORE_RV( c_ast_take_type_any( $1, &T_TS_TYPEDEF ) );
3206 
3207       if ( !add_type( L_USING, $1, &@1 ) )
3208         PARSE_ABORT();
3209     }
3210   ;
3211 
3212 using_decl_c_ast
3213   : Y_USING
3214     {
3215       gibberish_to_english();           // see the comment in "explain"
3216     }
3217     any_name_exp equals_exp type_c_ast
3218     {
3219       // see the comment in "define_command" about TS_TYPEDEF
3220       if ( !c_type_add_tid( &$5->type, TS_TYPEDEF, &@5 ) ) {
3221         free( $3 );
3222         PARSE_ABORT();
3223       }
3224       ia_type_ast_push( $5 );
3225     }
3226     cast_c_astp_opt
3227     {
3228       ia_type_ast_pop();
3229 
3230       DUMP_START( "using_decl_c_ast",
3231                   "USING any_name_exp '=' type_c_ast cast_c_astp_opt" );
3232       DUMP_SNAME( "(current_scope)", in_attr.current_scope );
3233       DUMP_STR( "any_name_exp", $3 );
3234       DUMP_AST( "type_c_ast", $5 );
3235       DUMP_AST( "cast_c_astp_opt", $7.ast );
3236 
3237       //
3238       // Ensure the type on the right-hand side doesn't have a name, e.g.:
3239       //
3240       //      using U = void (*F)();    // error
3241       //
3242       // This check has to be done now in the parser rather than later in the
3243       // AST because the patched AST loses the name.
3244       //
3245       c_sname_t const *const sname = c_ast_find_name( $7.ast, C_VISIT_DOWN );
3246       if ( sname != NULL ) {
3247         print_error( &$7.ast->loc,
3248           "\"%s\" type can not have a name\n", L_USING
3249         );
3250         free( $3 );
3251         PARSE_ABORT();
3252       }
3253 
3254       c_sname_t temp_sname = c_sname_dup( &in_attr.current_scope );
3255       c_sname_append_name( &temp_sname, $3 );
3256 
3257       $$ = c_ast_patch_placeholder( $5, $7.ast );
3258       c_sname_set( &$$->sname, &temp_sname );
3259 
3260       DUMP_AST( "using_decl_c_ast", $$ );
3261       DUMP_END();
3262 
3263       //
3264       // Using declarations are supported only in C++11 and later.  (However,
3265       // we always allow them in configuration files.)
3266       //
3267       // This check has to be done now in the parser rather than later in the
3268       // AST because using declarations are treated like typedef declarations
3269       // and the AST has no "memory" that such a declaration was a using
3270       // declaration.
3271       //
3272       if ( unsupported( LANG_CPP_MIN(11) ) ) {
3273         print_error( &@1,
3274           "\"%s\" not supported%s\n",
3275           L_USING, c_lang_which( LANG_CPP_MIN(11) )
3276         );
3277         PARSE_ABORT();
3278       }
3279 
3280       C_AST_CHECK( $$ );
3281     }
3282   ;
3283 
3284 /// Gibberish C/C++ declarations //////////////////////////////////////////////
3285 
3286 decl_list_c_opt
3287     /*
3288      * An enum, class, struct, or union (ECSU) declaration by itself, e.g.:
3289      *
3290      *      explain struct S
3291      *
3292      * without any object of that type.
3293      */
3294   : // in_attr: type_c_ast
3295     /* empty */
3296     {
3297       c_ast_t *const type_ast = ia_type_ast_peek();
3298 
3299       DUMP_START( "decl_list_c_opt", "<empty>" );
3300       DUMP_AST( "(type_c_ast)", type_ast );
3301       DUMP_AST( "decl_list_c_opt", type_ast );
3302 
3303       if ( type_ast->kind != K_ENUM_CLASS_STRUCT_UNION ) {
3304         //
3305         // The declaration is a non-ECSU type, e.g.:
3306         //
3307         //      int
3308         //
3309         c_loc_t const loc = lexer_loc();
3310         print_error( &loc, "declaration expected\n" );
3311         PARSE_ABORT();
3312       }
3313 
3314       c_sname_t const *const ecsu_sname = &type_ast->as.ecsu.ecsu_sname;
3315       assert( !c_sname_empty( ecsu_sname ) );
3316 
3317       if ( c_sname_count( ecsu_sname ) > 1 ) {
3318         print_error( &type_ast->loc,
3319           "forward declaration can not have a scoped name\n"
3320         );
3321         PARSE_ABORT();
3322       }
3323 
3324       c_sname_t temp_sname = c_sname_dup( ecsu_sname );
3325       c_sname_set( &type_ast->sname, &temp_sname );
3326 
3327       DUMP_AST( "decl_list_c_opt", type_ast );
3328       DUMP_END();
3329 
3330       C_AST_CHECK( type_ast );
3331       c_ast_explain_type( type_ast, cdecl_fout );
3332     }
3333 
3334   | decl_list_c
3335   ;
3336 
3337 decl_list_c
3338   : decl_list_c ',' decl_c
3339   | decl_c
3340   ;
3341 
3342 decl_c
3343   : // in_attr: alignas_specifier_c typename_flag_opt type_c_ast
3344     decl_c_astp
3345     { //
3346       // The type has to be duplicated to guarantee a fresh type AST in case
3347       // we're doing multiple declarations, e.g.:
3348       //
3349       //    explain int *p, *q
3350       //
3351       c_ast_t *const type_ast = c_ast_dup( ia_type_ast_peek(), &gc_ast_list );
3352 
3353       DUMP_START( "decl_c", "decl_c_astp" );
3354       switch ( in_attr.align.kind ) {
3355         case C_ALIGNAS_NONE:
3356           break;
3357         case C_ALIGNAS_EXPR:
3358           DUMP_INT( "(alignas_specifier_c.as.expr)", in_attr.align.as.expr );
3359           break;
3360         case C_ALIGNAS_TYPE:
3361           DUMP_AST(
3362             "(alignas_specifier_c.as.type_ast)", in_attr.align.as.type_ast
3363           );
3364           break;
3365       } // switch
3366       DUMP_BOOL( "(typename_flag_opt)", in_attr.typename );
3367       DUMP_AST( "(type_c_ast)", type_ast );
3368       DUMP_AST( "decl_c_astp", $1.ast );
3369 
3370       c_ast_t const *const decl_ast = c_ast_join_type_decl(
3371         in_attr.typename, &in_attr.align, type_ast, $1.ast
3372       );
3373 
3374       DUMP_AST( "decl_c", decl_ast );
3375       DUMP_END();
3376 
3377       if ( decl_ast == NULL )
3378         PARSE_ABORT();
3379       C_AST_CHECK( decl_ast );
3380 
3381       if ( !c_sname_empty( &decl_ast->sname ) ) {
3382         //
3383         // For declarations that have a name, ensure that it's not used more
3384         // than once in the same declaration with different types.  (More than
3385         // once with the same type are "tentative definitions" and OK.)
3386         //
3387         //      int i, i;               // ok (same type)
3388         //      int j, *j;              // error (different types)
3389         //
3390         FOREACH_SLIST_NODE( node, &decl_ast_list ) {
3391           c_ast_t const *const prev_ast = node->data;
3392           if ( c_sname_cmp( &decl_ast->sname, &prev_ast->sname ) == 0 &&
3393               !c_ast_equal( decl_ast, prev_ast ) ) {
3394             print_error( &decl_ast->loc,
3395               "\"%s\": redefinition with different type\n",
3396               c_sname_full_name( &decl_ast->sname )
3397             );
3398             PARSE_ABORT();
3399           }
3400         } // for
3401         slist_push_tail( &decl_ast_list, CONST_CAST( void*, decl_ast ) );
3402       }
3403 
3404       c_ast_explain_declaration( decl_ast, cdecl_fout );
3405 
3406       //
3407       // The type's AST takes on the name of the thing being declared, e.g.:
3408       //
3409       //      int x
3410       //
3411       // makes the type_ast (kind = "built-in type", type = "int") take on the
3412       // name of "x" so it'll be explained as:
3413       //
3414       //      declare x as int
3415       //
3416       // Once explained, the name must be cleared for the subsequent
3417       // declaration (if any) in the same declaration statement, e.g.:
3418       //
3419       //      int x, y
3420       //
3421       c_sname_cleanup( &type_ast->sname );
3422     }
3423   ;
3424 
3425 decl_c_astp
3426   : decl2_c_astp
3427   | pointer_decl_c_astp
3428   | pointer_to_member_decl_c_astp
3429   | reference_decl_c_astp
3430   | msc_calling_convention_atid msc_calling_convention_c_astp
3431     {
3432       $$ = $2;
3433       $$.ast->loc = @$;
3434       $$.ast->type.atids |= $1;
3435     }
3436   ;
3437 
3438 msc_calling_convention_c_astp
3439   : func_decl_c_astp
3440   | pointer_decl_c_astp
3441   ;
3442 
3443 decl2_c_astp
3444   : array_decl_c_astp
3445   | block_decl_c_astp
3446   | func_decl_c_astp
3447   | nested_decl_c_astp
3448   | oper_decl_c_astp
3449   | sname_c_ast gnu_attribute_specifier_list_c_opt
3450     {
3451       $$ = (c_ast_pair_t){ $1, NULL };
3452     }
3453   | typedef_type_decl_c_ast       { $$ = (c_ast_pair_t){ $1, NULL }; }
3454   | user_defined_conversion_decl_c_astp
3455   | user_defined_literal_decl_c_astp
3456   ;
3457 
3458 /// Gibberish C/C++ array declaration /////////////////////////////////////////
3459 
3460 array_decl_c_astp
3461   : // in_attr: type_c_ast
3462     decl2_c_astp array_size_c_int gnu_attribute_specifier_list_c_opt
3463     {
3464       c_ast_t *const type_ast = ia_type_ast_peek();
3465 
3466       DUMP_START( "array_decl_c_astp", "decl2_c_astp array_size_c_int" );
3467       DUMP_AST( "(type_c_ast)", type_ast );
3468       DUMP_AST( "decl2_c_astp", $1.ast );
3469       DUMP_AST( "target_ast", $1.target_ast );
3470       DUMP_INT( "array_size_c_int", $2 );
3471 
3472       c_ast_t *const array_ast = c_ast_new_gc( K_ARRAY, &@$ );
3473       array_ast->as.array.size = $2;
3474       c_ast_set_parent( c_ast_new_gc( K_PLACEHOLDER, &@1 ), array_ast );
3475 
3476       if ( $1.target_ast != NULL ) {    // array-of or function-like-ret type
3477         $$.ast = $1.ast;
3478         $$.target_ast = c_ast_add_array( $1.target_ast, array_ast, type_ast );
3479       } else {
3480         $$.ast = c_ast_add_array( $1.ast, array_ast, type_ast );
3481         $$.target_ast = NULL;
3482       }
3483 
3484       DUMP_AST( "array_decl_c_astp", $$.ast );
3485       DUMP_END();
3486     }
3487   ;
3488 
3489 array_size_c_int
3490   : '[' rbracket_exp              { $$ = C_ARRAY_SIZE_NONE; }
3491   | '[' Y_INT_LIT rbracket_exp    { $$ = $2; }
3492   | '[' error ']'
3493     {
3494       elaborate_error( "integer expected for array size" );
3495     }
3496   ;
3497 
3498 /// Gibberish C/C++ block declaration (Apple extension) ///////////////////////
3499 
3500 block_decl_c_astp                       // Apple extension
3501   : // in_attr: type_c_ast
3502     '(' Y_CIRC
3503     { //
3504       // A block AST has to be the type inherited attribute for decl_c_astp so
3505       // we have to create it here.
3506       //
3507       ia_type_ast_push( c_ast_new_gc( K_APPLE_BLOCK, &@$ ) );
3508     }
3509     type_qualifier_list_c_stid_opt decl_c_astp rparen_exp
3510     lparen_exp param_list_c_ast_opt ')' gnu_attribute_specifier_list_c_opt
3511     {
3512       c_ast_t *const block_ast = ia_type_ast_pop();
3513       c_ast_t *const type_ast = ia_type_ast_peek();
3514 
3515       DUMP_START( "block_decl_c_astp",
3516                   "'(' '^' type_qualifier_list_c_stid_opt decl_c_astp ')' "
3517                   "'(' param_list_c_ast_opt ')'" );
3518       DUMP_AST( "(type_c_ast)", type_ast );
3519       DUMP_TID( "type_qualifier_list_c_stid_opt", $4 );
3520       DUMP_AST( "decl_c_astp", $5.ast );
3521       DUMP_AST_LIST( "param_list_c_ast_opt", $8 );
3522 
3523       C_TYPE_ADD_TID( &block_ast->type, $4, @4 );
3524       block_ast->as.block.param_ast_list = $8;
3525       $$.ast = c_ast_add_func( $5.ast, block_ast, type_ast );
3526       $$.target_ast = block_ast->as.block.ret_ast;
3527 
3528       DUMP_AST( "block_decl_c_astp", $$.ast );
3529       DUMP_END();
3530     }
3531   ;
3532 
3533 /// Gibberish in-class destructor declaration /////////////////////////////////
3534 
3535 destructor_decl_c
3536     /*
3537      * C++ in-class destructor declaration, e.g.: ~S().
3538      */
3539   : virtual_stid_opt Y_TILDE any_name_exp
3540     lparen_exp rparen_func_qualifier_list_c_stid_opt noexcept_c_stid_opt
3541     gnu_attribute_specifier_list_c_opt func_equals_c_stid_opt
3542     {
3543       DUMP_START( "destructor_decl_c",
3544                   "virtual_opt '~' NAME '(' ')' func_qualifier_list_c_stid_opt "
3545                   "noexcept_c_stid_opt gnu_attribute_specifier_list_c_opt "
3546                   "func_equals_c_stid_opt" );
3547       DUMP_TID( "virtual_stid_opt", $1 );
3548       DUMP_STR( "any_name_exp", $3 );
3549       DUMP_TID( "func_qualifier_list_c_stid_opt", $5 );
3550       DUMP_TID( "noexcept_c_stid_opt", $6 );
3551       DUMP_TID( "func_equals_c_stid_opt", $8 );
3552 
3553       c_ast_t *const ast = c_ast_new_gc( K_DESTRUCTOR, &@$ );
3554       c_sname_append_name( &ast->sname, $3 );
3555       ast->type.stids = c_tid_check( $1 | $5 | $6 | $8, C_TPID_STORE );
3556 
3557       DUMP_AST( "destructor_decl_c", ast );
3558       DUMP_END();
3559 
3560       C_AST_CHECK( ast );
3561       c_ast_explain_declaration( ast, cdecl_fout );
3562     }
3563   ;
3564 
3565 /// Gibberish file-scope constructor declaration //////////////////////////////
3566 
3567 file_scope_constructor_decl_c
3568   : inline_stid_opt Y_CONSTRUCTOR_SNAME
3569     lparen_exp param_list_c_ast_opt rparen_func_qualifier_list_c_stid_opt
3570     noexcept_c_stid_opt gnu_attribute_specifier_list_c_opt
3571     {
3572       DUMP_START( "file_scope_constructor_decl_c",
3573                   "inline_opt CONSTRUCTOR_SNAME '(' param_list_c_ast_opt ')' "
3574                   "func_qualifier_list_c_stid_opt noexcept_c_stid_opt" );
3575       DUMP_TID( "inline_stid_opt", $1 );
3576       DUMP_SNAME( "CONSTRUCTOR_SNAME", $2 );
3577       DUMP_AST_LIST( "param_list_c_ast_opt", $4 );
3578       DUMP_TID( "func_qualifier_list_c_stid_opt", $5 );
3579       DUMP_TID( "noexcept_c_stid_opt", $6 );
3580 
3581       c_sname_set_scope_type( &$2, &C_TYPE_LIT_B( TB_CLASS ) );
3582 
3583       c_ast_t *const ast = c_ast_new_gc( K_CONSTRUCTOR, &@$ );
3584       ast->sname = $2;
3585       ast->type.stids = c_tid_check( $1 | $5 | $6, C_TPID_STORE );
3586       ast->as.constructor.param_ast_list = $4;
3587 
3588       DUMP_AST( "file_scope_constructor_decl_c", ast );
3589       DUMP_END();
3590 
3591       C_AST_CHECK( ast );
3592       c_ast_explain_declaration( ast, cdecl_fout );
3593     }
3594   ;
3595 
3596 /// Gibberish file-scope destructor declaration ///////////////////////////////
3597 
3598 file_scope_destructor_decl_c
3599   : inline_stid_opt Y_DESTRUCTOR_SNAME
3600     lparen_exp rparen_func_qualifier_list_c_stid_opt noexcept_c_stid_opt
3601     gnu_attribute_specifier_list_c_opt
3602     {
3603       DUMP_START( "file_scope_destructor_decl_c",
3604                   "inline_opt DESTRUCTOR_SNAME '(' ')' "
3605                   "func_qualifier_list_c_stid_opt noexcept_c_stid_opt" );
3606       DUMP_TID( "inline_stid_opt", $1 );
3607       DUMP_SNAME( "DESTRUCTOR_SNAME", $2 );
3608       DUMP_TID( "func_qualifier_list_c_stid_opt", $4 );
3609       DUMP_TID( "noexcept_c_stid_opt", $5 );
3610 
3611       c_sname_set_scope_type( &$2, &C_TYPE_LIT_B( TB_CLASS ) );
3612 
3613       c_ast_t *const ast = c_ast_new_gc( K_DESTRUCTOR, &@$ );
3614       ast->sname = $2;
3615       ast->type.stids = c_tid_check( $1 | $4 | $5, C_TPID_STORE );
3616 
3617       DUMP_AST( "file_scope_destructor_decl_c", ast );
3618       DUMP_END();
3619 
3620       C_AST_CHECK( ast );
3621       c_ast_explain_declaration( ast, cdecl_fout );
3622     }
3623   ;
3624 
3625 /// Gibberish function declaration ////////////////////////////////////////////
3626 
3627 func_decl_c_astp
3628     /*
3629      * Function and C++ constructor declaration.
3630      *
3631      * This grammar rule handles both since they're so similar (and so would
3632      * cause grammar conflicts if they were separate rules in an LALR(1)
3633      * parser).
3634      */
3635   : // in_attr: type_c_ast
3636     decl2_c_astp '(' param_list_c_ast_opt
3637     rparen_func_qualifier_list_c_stid_opt func_ref_qualifier_c_stid_opt
3638     noexcept_c_stid_opt trailing_return_type_c_ast_opt func_equals_c_stid_opt
3639     {
3640       c_ast_t *const decl2_ast = $1.ast;
3641       c_tid_t  const func_qualifier_stid = $4;
3642       c_tid_t  const func_ref_qualifier_stid = $5;
3643       c_tid_t  const noexcept_stid = $6;
3644       c_tid_t  const func_equals_stid = $8;
3645       c_ast_t *const trailing_ret_ast = $7;
3646       c_ast_t *const type_ast = ia_type_ast_peek();
3647 
3648       DUMP_START( "func_decl_c_astp",
3649                   "decl2_c_astp '(' param_list_c_ast_opt ')' "
3650                   "func_qualifier_list_c_stid_opt "
3651                   "func_ref_qualifier_c_stid_opt noexcept_c_stid_opt "
3652                   "trailing_return_type_c_ast_opt "
3653                   "func_equals_c_stid_opt" );
3654       DUMP_AST( "(type_c_ast)", type_ast );
3655       DUMP_AST( "decl2_c_astp", decl2_ast );
3656       DUMP_AST_LIST( "param_list_c_ast_opt", $3 );
3657       DUMP_TID( "func_qualifier_list_c_stid_opt", func_qualifier_stid );
3658       DUMP_TID( "func_ref_qualifier_c_stid_opt", func_ref_qualifier_stid );
3659       DUMP_TID( "noexcept_c_stid_opt", noexcept_stid );
3660       DUMP_AST( "trailing_return_type_c_ast_opt", trailing_ret_ast );
3661       DUMP_TID( "func_equals_c_stid_opt", func_equals_stid );
3662       DUMP_AST( "target_ast", $1.target_ast );
3663 
3664       c_tid_t const func_stid =
3665         func_qualifier_stid | func_ref_qualifier_stid | noexcept_stid |
3666         func_equals_stid;
3667 
3668       //
3669       // Cdecl can't know for certain whether a "function" name is really a
3670       // constructor name because it:
3671       //
3672       //  1. Doesn't have the context of the surrounding class:
3673       //
3674       //          class T {
3675       //          public:
3676       //            T();                // <-- All cdecl usually has is this.
3677       //            // ...
3678       //          };
3679       //
3680       //  2. Can't check to see if the name is a typedef for a class, struct,
3681       //     or union (even though that would greatly help) since:
3682       //
3683       //          T(U);
3684       //
3685       //     could be either:
3686       //
3687       //      + A constructor of type T with a parameter of type U; or:
3688       //      + A variable named U of type T (with unnecessary parentheses).
3689       //
3690       // Hence, we have to infer which of a function or a constructor was
3691       // likely the one meant.  Assume the declaration is for a constructor
3692       // only if:
3693       //
3694       bool const assume_constructor =
3695 
3696         // + The current language is C++.
3697         OPT_LANG_IS(CPP_ANY) &&
3698 
3699         // + The existing base type is none (because constructors don't have
3700         //   return types).
3701         type_ast->type.btids == TB_NONE &&
3702 
3703         // + The existing type does _not_ have any non-constructor storage
3704         //   classes.
3705         !c_type_is_tid_any( &type_ast->type, TS_NOT_CONSTRUCTOR ) &&
3706 
3707         ( // + The existing type has any constructor-only storage-class-like
3708           //   types (e.g., explicit).
3709           c_type_is_tid_any( &type_ast->type, TS_CONSTRUCTOR_ONLY ) ||
3710 
3711           // + Or the existing type only has storage-class-like types that may
3712           //   be applied to constructors.
3713           only_bits_set(
3714             c_tid_no_tpid( type_ast->type.stids ),
3715             c_tid_no_tpid( TS_CONSTRUCTOR_DECL )
3716           )
3717         ) &&
3718 
3719         // + The new type does _not_ have any non-constructor storage classes.
3720         !c_tid_is_any( func_stid, TS_NOT_CONSTRUCTOR );
3721 
3722       c_ast_t *const func_ast =
3723         c_ast_new_gc( assume_constructor ? K_CONSTRUCTOR : K_FUNCTION, &@$ );
3724       func_ast->type.stids = c_tid_check( func_stid, C_TPID_STORE );
3725       func_ast->as.func.param_ast_list = $3;
3726 
3727       if ( assume_constructor ) {
3728         assert( trailing_ret_ast == NULL );
3729         c_type_or_eq( &func_ast->type, &type_ast->type );
3730         $$.ast = func_ast;
3731       }
3732       else if ( $1.target_ast != NULL ) {
3733         $$.ast = decl2_ast;
3734         PJL_IGNORE_RV( c_ast_add_func( $1.target_ast, func_ast, type_ast ) );
3735       }
3736       else {
3737         $$.ast = c_ast_add_func(
3738           decl2_ast,
3739           func_ast,
3740           trailing_ret_ast != NULL ? trailing_ret_ast : type_ast
3741         );
3742       }
3743 
3744       $$.target_ast = func_ast->as.func.ret_ast;
3745 
3746       c_tid_t const msc_call_atids = $$.ast->type.atids & TA_ANY_MSC_CALL;
3747       if ( msc_call_atids != TA_NONE ) {
3748         //
3749         // Microsoft calling conventions need to be moved from the pointer to
3750         // the function, e.g., change:
3751         //
3752         //      declare f as cdecl pointer to function returning void
3753         //
3754         // to:
3755         //
3756         //      declare f as pointer to cdecl function returning void
3757         //
3758         for ( c_ast_t const *ast = $$.ast;
3759               (ast = c_ast_unpointer( ast )) != NULL; ) {
3760           if ( ast->kind == K_FUNCTION ) {
3761             $$.ast->type.atids &= c_tid_compl( TA_ANY_MSC_CALL );
3762             CONST_CAST( c_ast_t*, ast )->type.atids |= msc_call_atids;
3763           }
3764         } // for
3765       }
3766 
3767       DUMP_AST( "func_decl_c_astp", $$.ast );
3768       DUMP_END();
3769     }
3770   ;
3771 
3772 knr_func_or_constructor_decl_c
3773     /*
3774      * K&R C implicit int function and C++ in-class constructor declaration.
3775      *
3776      * This grammar rule handles both since they're so similar (and so would
3777      * cause grammar conflicts if they were separate rules in an LALR(1)
3778      * parser).
3779      */
3780   : Y_NAME '(' param_list_c_ast_opt ')' noexcept_c_stid_opt
3781     func_equals_c_stid_opt
3782     {
3783       if ( OPT_LANG_IS(C_MIN(99)) ) {
3784         //
3785         // In C99 and later, an implicit int function is an error.  This check
3786         // has to be done now in the parser rather than later in the AST since
3787         // the AST would have no "memory" that the return type was implicitly
3788         // int.
3789         //
3790         print_error( &@1,
3791           "implicit \"%s\" functions are illegal in %s and later\n",
3792           L_INT, c_lang_name( LANG_C_99 )
3793         );
3794         PARSE_ABORT();
3795       }
3796 
3797       DUMP_START( "knr_func_or_constructor_decl_c",
3798                   "NAME '(' param_list_c_ast_opt ')' noexcept_c_stid_opt "
3799                   "func_equals_c_stid_opt" );
3800       DUMP_STR( "NAME", $1 );
3801       DUMP_AST_LIST( "param_list_c_ast_opt", $3 );
3802       DUMP_TID( "noexcept_c_stid_opt", $5 );
3803       DUMP_TID( "func_equals_c_stid_opt", $6 );
3804 
3805       c_ast_t *ast;
3806       c_sname_t sname;
3807       c_sname_init_name( &sname, $1 );
3808 
3809       if ( OPT_LANG_IS(C_ANY) ) {
3810         //
3811         // In C prior to C99, encountering a name followed by '(' declares a
3812         // function that implicitly returns int:
3813         //
3814         //      power(x, n)             /* raise x to n-th power; n > 0 */
3815         //
3816         c_ast_t *const ret_ast = c_ast_new_gc( K_BUILTIN, &@1 );
3817         ret_ast->type.btids = TB_INT;
3818 
3819         ast = c_ast_new_gc( K_FUNCTION, &@$ );
3820         ast->as.func.ret_ast = ret_ast;
3821         ast->type.stids = c_tid_check( $5 | $6, C_TPID_STORE );
3822       }
3823       else {
3824         //
3825         // In C++, encountering a name followed by '(' declares an in-class
3826         // constructor.
3827         //
3828         ast = c_ast_new_gc( K_CONSTRUCTOR, &@$ );
3829         ast->type.stids = c_tid_check( $5 | $6, C_TPID_STORE );
3830       }
3831 
3832       c_sname_set( &ast->sname, &sname );
3833       ast->as.func.param_ast_list = $3;
3834 
3835       DUMP_AST( "knr_func_or_constructor_decl_c", ast );
3836       DUMP_END();
3837 
3838       C_AST_CHECK( ast );
3839       c_ast_explain_declaration( ast, cdecl_fout );
3840     }
3841   ;
3842 
3843 rparen_func_qualifier_list_c_stid_opt
3844   : ')'
3845     {
3846       if ( OPT_LANG_IS(CPP_ANY) ) {
3847         //
3848         // Both "final" and "override" are matched only within member function
3849         // declarations.  Now that ')' has been parsed, we're within one, so
3850         // set the keyword context to C_KW_CTX_MBR_FUNC.
3851         //
3852         lexer_keyword_ctx = C_KW_CTX_MBR_FUNC;
3853       }
3854     }
3855     func_qualifier_list_c_stid_opt
3856     {
3857       lexer_keyword_ctx = C_KW_CTX_DEFAULT;
3858       $$ = $3;
3859     }
3860   ;
3861 
3862 func_qualifier_list_c_stid_opt
3863   : /* empty */                   { $$ = TS_NONE; }
3864   | func_qualifier_list_c_stid_opt func_qualifier_c_stid
3865     {
3866       DUMP_START( "func_qualifier_list_c_stid_opt",
3867                   "func_qualifier_list_c_stid_opt func_qualifier_c_stid" );
3868       DUMP_TID( "func_qualifier_list_c_stid_opt", $1 );
3869       DUMP_TID( "func_qualifier_c_stid", $2 );
3870 
3871       $$ = $1;
3872       C_TID_ADD( &$$, $2, @2 );
3873 
3874       DUMP_TID( "func_qualifier_list_c_stid_opt", $$ );
3875       DUMP_END();
3876     }
3877   ;
3878 
3879 func_qualifier_c_stid
3880   : cv_qualifier_stid
3881   | Y_FINAL
3882   | Y_OVERRIDE
3883     /*
3884      * GNU C++ allows restricted-this-pointer member functions:
3885      *
3886      *      void S::f() __restrict;
3887      *
3888      * <https://gcc.gnu.org/onlinedocs/gcc/Restricted-Pointers.html>
3889      */
3890   | Y_GNU___RESTRICT                    // GNU C++ extension
3891   ;
3892 
3893 func_ref_qualifier_c_stid_opt
3894   : /* empty */                   { $$ = TS_NONE; }
3895   | Y_AMPER                       { $$ = TS_REFERENCE; }
3896   | Y_AMPER2                      { $$ = TS_RVALUE_REFERENCE; }
3897   ;
3898 
3899 noexcept_c_stid_opt
3900   : /* empty */                   { $$ = TS_NONE; }
3901   | Y_NOEXCEPT
3902   | Y_NOEXCEPT '(' no_except_bool_stid_exp rparen_exp
3903     {
3904       $$ = $3;
3905     }
3906   | Y_THROW lparen_exp rparen_exp
3907   ;
3908 
3909 no_except_bool_stid_exp
3910   : Y_FALSE
3911   | Y_TRUE
3912   | error
3913     {
3914       elaborate_error( "\"%s\" or \"%s\" expected", L_TRUE, L_FALSE );
3915     }
3916   ;
3917 
3918 trailing_return_type_c_ast_opt
3919   : /* empty */                   { $$ = NULL; }
3920   | // in_attr: type_c_ast
3921     Y_ARROW type_c_ast { ia_type_ast_push( $2 ); } cast_c_astp_opt
3922     {
3923       ia_type_ast_pop();
3924       c_ast_t const *const ret_ast = ia_type_ast_peek();
3925 
3926       DUMP_START( "trailing_return_type_c_ast_opt",
3927                   "type_c_ast cast_c_astp_opt" );
3928       DUMP_AST( "(type_c_ast)", ret_ast );
3929       DUMP_AST( "type_c_ast", $2 );
3930       DUMP_AST( "cast_c_astp_opt", $4.ast );
3931 
3932       $$ = $4.ast != NULL ? $4.ast : $2;
3933 
3934       DUMP_AST( "trailing_return_type_c_ast_opt", $$ );
3935       DUMP_END();
3936 
3937       //
3938       // The function trailing return-type syntax is supported only in C++11
3939       // and later.  This check has to be done now in the parser rather than
3940       // later in the AST because the AST has no "memory" of where the return-
3941       // type came from.
3942       //
3943       if ( unsupported( LANG_CPP_MIN(11) ) ) {
3944         print_error( &@1,
3945           "trailing return type not supported%s\n",
3946           c_lang_which( LANG_CPP_MIN(11) )
3947         );
3948         PARSE_ABORT();
3949       }
3950 
3951       //
3952       // Ensure that a function using the C++11 trailing return type syntax
3953       // starts with "auto":
3954       //
3955       //      void f() -> int
3956       //      ^
3957       //      error: must be "auto"
3958       //
3959       // This check has to be done now in the parser rather than later in the
3960       // AST because the "auto" is just a syntactic return-type placeholder in
3961       // C++11 and the AST node for the placeholder is discarded and never made
3962       // part of the AST.
3963       //
3964       if ( ret_ast->type.btids != TB_AUTO ) {
3965         print_error( &ret_ast->loc,
3966           "function with trailing return type must only specify \"%s\"\n",
3967           L_AUTO
3968         );
3969         PARSE_ABORT();
3970       }
3971     }
3972 
3973   | gnu_attribute_specifier_list_c
3974     {
3975       $$ = NULL;
3976     }
3977   ;
3978 
3979 func_equals_c_stid_opt
3980   : /* empty */                   { $$ = TS_NONE; }
3981   | '=' Y_DEFAULT                 { $$ = $2; }
3982   | '=' Y_DELETE                  { $$ = $2; }
3983   | '=' Y_INT_LIT
3984     {
3985       if ( $2 != 0 ) {
3986         print_error( &@2, "'0' expected\n" );
3987         PARSE_ABORT();
3988       }
3989       $$ = TS_PURE_VIRTUAL;
3990     }
3991   | '=' error
3992     {
3993       if ( opt_lang < LANG_CPP_11 )
3994         elaborate_error( "'0' expected" );
3995       else
3996         elaborate_error(
3997           "'0', \"%s\", or \"%s\" expected", L_DEFAULT, L_DELETE
3998         );
3999     }
4000   ;
4001 
4002 /// Gibberish C/C++ function(like) parameter declaration //////////////////////
4003 
4004 param_list_c_ast_exp
4005   : param_list_c_ast
4006   | error
4007     {
4008       slist_init( &$$ );
4009       elaborate_error( "parameter list expected" );
4010     }
4011   ;
4012 
4013 param_list_c_ast_opt
4014   : /* empty */                   { slist_init( &$$ ); }
4015   | param_list_c_ast
4016   ;
4017 
4018 param_list_c_ast
4019   : param_list_c_ast comma_exp param_c_ast
4020     {
4021       DUMP_START( "param_list_c_ast", "param_list_c_ast ',' param_c_ast" );
4022       DUMP_AST_LIST( "param_list_c_ast", $1 );
4023       DUMP_AST( "param_c_ast", $3 );
4024 
4025       $$ = $1;
4026       slist_push_tail( &$$, $3 );
4027 
4028       DUMP_AST_LIST( "param_list_c_ast", $$ );
4029       DUMP_END();
4030     }
4031 
4032   | param_c_ast
4033     {
4034       DUMP_START( "param_list_c_ast", "param_c_ast" );
4035       DUMP_AST( "param_c_ast", $1 );
4036 
4037       slist_init( &$$ );
4038       slist_push_tail( &$$, $1 );
4039 
4040       DUMP_AST_LIST( "param_list_c_ast", $$ );
4041       DUMP_END();
4042     }
4043   ;
4044 
4045 param_c_ast
4046     /*
4047      * Ordinary function parameter declaration.
4048      */
4049   : type_c_ast { ia_type_ast_push( $1 ); } cast_c_astp_opt
4050     {
4051       ia_type_ast_pop();
4052 
4053       DUMP_START( "param_c_ast", "type_c_ast cast_c_astp_opt" );
4054       DUMP_AST( "type_c_ast", $1 );
4055       DUMP_AST( "cast_c_astp_opt", $3.ast );
4056 
4057       $$ = c_ast_patch_placeholder( $1, $3.ast );
4058 
4059       if ( $$->kind == K_FUNCTION )     // see the comment in decl_english_ast
4060         $$ = c_ast_pointer( $$, &gc_ast_list );
4061 
4062       DUMP_AST( "param_c_ast", $$ );
4063       DUMP_END();
4064     }
4065 
4066     /*
4067      * K&R C type-less function parameter declaration.
4068      */
4069   | name_ast
4070 
4071     /*
4072      * Varargs declaration.
4073      */
4074   | "..."
4075     {
4076       DUMP_START( "param_c_ast", "..." );
4077 
4078       $$ = c_ast_new_gc( K_VARIADIC, &@$ );
4079 
4080       DUMP_AST( "param_c_ast", $$ );
4081       DUMP_END();
4082     }
4083   ;
4084 
4085 
4086 /// Gibberish C/C++ nested declaration ////////////////////////////////////////
4087 
4088 nested_decl_c_astp
4089   : '('
4090     {
4091       ia_type_ast_push( c_ast_new_gc( K_PLACEHOLDER, &@$ ) );
4092       ++ast_depth;
4093     }
4094     decl_c_astp rparen_exp
4095     {
4096       ia_type_ast_pop();
4097       --ast_depth;
4098 
4099       DUMP_START( "nested_decl_c_astp", "'(' decl_c_astp ')'" );
4100       DUMP_AST( "decl_c_astp", $3.ast );
4101 
4102       $$ = $3;
4103       $$.ast->loc = @$;
4104 
4105       DUMP_AST( "nested_decl_c_astp", $$.ast );
4106       DUMP_END();
4107     }
4108   ;
4109 
4110 /// Gibberish C++ operator declaration ////////////////////////////////////////
4111 
4112 oper_decl_c_astp
4113   : // in_attr: type_c_ast
4114     oper_c_ast lparen_exp param_list_c_ast_opt
4115     rparen_func_qualifier_list_c_stid_opt func_ref_qualifier_c_stid_opt
4116     noexcept_c_stid_opt trailing_return_type_c_ast_opt func_equals_c_stid_opt
4117     {
4118       c_ast_t *const oper_c_ast = $1;
4119       c_tid_t  const func_qualifier_stid = $4;
4120       c_tid_t  const func_ref_qualifier_stid = $5;
4121       c_tid_t  const func_equals_stid = $8;
4122       c_tid_t  const noexcept_stid = $6;
4123       c_ast_t *const trailing_ret_ast = $7;
4124       c_ast_t *const type_ast = ia_type_ast_peek();
4125 
4126       DUMP_START( "oper_decl_c_astp",
4127                   "oper_c_ast '(' param_list_c_ast_opt ')' "
4128                   "func_qualifier_list_c_stid_opt "
4129                   "func_ref_qualifier_c_stid_opt noexcept_c_stid_opt "
4130                   "trailing_return_type_c_ast_opt "
4131                   "func_equals_c_stid_opt" );
4132       DUMP_AST( "(type_c_ast)", type_ast );
4133       DUMP_AST( "oper_c_ast", oper_c_ast );
4134       DUMP_AST_LIST( "param_list_c_ast_opt", $3 );
4135       DUMP_TID( "func_qualifier_list_c_stid_opt", func_qualifier_stid );
4136       DUMP_TID( "func_ref_qualifier_c_stid_opt", func_ref_qualifier_stid );
4137       DUMP_TID( "noexcept_c_stid_opt", noexcept_stid );
4138       DUMP_AST( "trailing_return_type_c_ast_opt", trailing_ret_ast );
4139       DUMP_TID( "func_equals_c_stid_opt", func_equals_stid );
4140 
4141       c_tid_t const oper_stid =
4142         func_qualifier_stid | func_ref_qualifier_stid | noexcept_stid |
4143         func_equals_stid;
4144 
4145       c_ast_t *const oper_ast = c_ast_new_gc( K_OPERATOR, &@$ );
4146       oper_ast->type.stids = c_tid_check( oper_stid, C_TPID_STORE );
4147       oper_ast->as.oper.param_ast_list = $3;
4148       oper_ast->as.oper.oper_id = oper_c_ast->as.oper.oper_id;
4149 
4150       $$.ast = c_ast_add_func(
4151         oper_c_ast,
4152         oper_ast,
4153         trailing_ret_ast != NULL ? trailing_ret_ast : type_ast
4154       );
4155 
4156       $$.target_ast = oper_ast->as.oper.ret_ast;
4157 
4158       DUMP_AST( "oper_decl_c_astp", $$.ast );
4159       DUMP_END();
4160     }
4161   ;
4162 
4163 oper_c_ast
4164   : // in_attr: type_c_ast
4165     scope_sname_c_opt Y_OPERATOR c_operator
4166     {
4167       c_ast_t *const type_ast = ia_type_ast_peek();
4168 
4169       DUMP_START( "oper_c_ast", "OPERATOR c_operator" );
4170       DUMP_AST( "(type_c_ast)", type_ast );
4171       DUMP_SNAME( "scope_sname_c_opt", $1 );
4172       DUMP_STR( "c_operator", c_oper_get( $3 )->name );
4173 
4174       $$ = type_ast;
4175       c_sname_set( &$$->sname, &$1 );
4176       $$->as.oper.oper_id = $3;
4177 
4178       DUMP_AST( "oper_c_ast", $$ );
4179       DUMP_END();
4180     }
4181   ;
4182 
4183 /// Gibberish C/C++ pointer declaration ///////////////////////////////////////
4184 
4185 pointer_decl_c_astp
4186   : pointer_type_c_ast { ia_type_ast_push( $1 ); } decl_c_astp
4187     {
4188       ia_type_ast_pop();
4189 
4190       DUMP_START( "pointer_decl_c_astp", "pointer_type_c_ast decl_c_astp" );
4191       DUMP_AST( "pointer_type_c_ast", $1 );
4192       DUMP_AST( "decl_c_astp", $3.ast );
4193 
4194       PJL_IGNORE_RV( c_ast_patch_placeholder( $1, $3.ast ) );
4195       $$ = $3;
4196       $$.ast->loc = @$;
4197 
4198       DUMP_AST( "pointer_decl_c_astp", $$.ast );
4199       DUMP_END();
4200     }
4201   ;
4202 
4203 pointer_type_c_ast
4204   : // in_attr: type_c_ast
4205     '*' type_qualifier_list_c_stid_opt
4206     {
4207       c_ast_t *const type_ast = ia_type_ast_peek();
4208 
4209       DUMP_START( "pointer_type_c_ast", "* type_qualifier_list_c_stid_opt" );
4210       DUMP_AST( "(type_c_ast)", type_ast );
4211       DUMP_TID( "type_qualifier_list_c_stid_opt", $2 );
4212 
4213       $$ = c_ast_new_gc( K_POINTER, &@$ );
4214       $$->type.stids = c_tid_check( $2, C_TPID_STORE );
4215       c_ast_set_parent( type_ast, $$ );
4216 
4217       DUMP_AST( "pointer_type_c_ast", $$ );
4218       DUMP_END();
4219     }
4220   ;
4221 
4222 /// Gibberish C++ pointer-to-member declaration ///////////////////////////////
4223 
4224 pointer_to_member_decl_c_astp
4225   : pointer_to_member_type_c_ast { ia_type_ast_push( $1 ); } decl_c_astp
4226     {
4227       ia_type_ast_pop();
4228 
4229       DUMP_START( "pointer_to_member_decl_c_astp",
4230                   "pointer_to_member_type_c_ast decl_c_astp" );
4231       DUMP_AST( "pointer_to_member_type_c_ast", $1 );
4232       DUMP_AST( "decl_c_astp", $3.ast );
4233 
4234       $$ = $3;
4235       $$.ast->loc = @$;
4236 
4237       DUMP_AST( "pointer_to_member_decl_c_astp", $$.ast );
4238       DUMP_END();
4239     }
4240   ;
4241 
4242 pointer_to_member_type_c_ast
4243   : // in_attr: type_c_ast
4244     any_sname_c Y_COLON2_STAR cv_qualifier_list_stid_opt
4245     {
4246       c_ast_t *const type_ast = ia_type_ast_peek();
4247 
4248       DUMP_START( "pointer_to_member_type_c_ast",
4249                   "sname '::*' cv_qualifier_list_stid_opt" );
4250       DUMP_AST( "(type_c_ast)", type_ast );
4251       DUMP_SNAME( "sname", $1 );
4252       DUMP_TID( "cv_qualifier_list_stid_opt", $3 );
4253 
4254       $$ = c_ast_new_gc( K_POINTER_TO_MEMBER, &@$ );
4255 
4256       c_type_t scope_type = *c_sname_local_type( &$1 );
4257       if ( !c_tid_is_any( scope_type.btids, TB_ANY_SCOPE ) ) {
4258         //
4259         // The sname has no scope-type, but we now know there's a pointer-to-
4260         // member of it, so it must be a class.  (It could alternatively be a
4261         // struct, but we have no context to know, so just pick class because
4262         // it's more C++-like.)
4263         //
4264         scope_type.btids = TB_CLASS;
4265         c_sname_set_local_type( &$1, &scope_type );
4266       }
4267 
4268       // adopt sname's scope-type for the AST
4269       $$->type = c_type_or( &C_TYPE_LIT_S( $3 ), &scope_type );
4270 
4271       $$->as.ptr_mbr.class_sname = $1;
4272       c_ast_set_parent( type_ast, $$ );
4273 
4274       DUMP_AST( "pointer_to_member_type_c_ast", $$ );
4275       DUMP_END();
4276     }
4277   ;
4278 
4279 /// Gibberish C++ reference declaration ///////////////////////////////////////
4280 
4281 reference_decl_c_astp
4282   : reference_type_c_ast { ia_type_ast_push( $1 ); } decl_c_astp
4283     {
4284       ia_type_ast_pop();
4285 
4286       DUMP_START( "reference_decl_c_astp", "reference_type_c_ast decl_c_astp" );
4287       DUMP_AST( "reference_type_c_ast", $1 );
4288       DUMP_AST( "decl_c_astp", $3.ast );
4289 
4290       $$ = $3;
4291       $$.ast->loc = @$;
4292 
4293       DUMP_AST( "reference_decl_c_astp", $$.ast );
4294       DUMP_END();
4295     }
4296   ;
4297 
4298 reference_type_c_ast
4299   : // in_attr: type_c_ast
4300     Y_AMPER type_qualifier_list_c_stid_opt
4301     {
4302       c_ast_t *const type_ast = ia_type_ast_peek();
4303 
4304       DUMP_START( "reference_type_c_ast", "&" );
4305       DUMP_AST( "(type_c_ast)", type_ast );
4306       DUMP_TID( "type_qualifier_list_c_stid_opt", $2 );
4307 
4308       $$ = c_ast_new_gc( K_REFERENCE, &@$ );
4309       $$->type.stids = c_tid_check( $2, C_TPID_STORE );
4310       c_ast_set_parent( type_ast, $$ );
4311 
4312       DUMP_AST( "reference_type_c_ast", $$ );
4313       DUMP_END();
4314     }
4315 
4316   | // in_attr: type_c_ast
4317     Y_AMPER2 type_qualifier_list_c_stid_opt
4318     {
4319       c_ast_t *const type_ast = ia_type_ast_peek();
4320 
4321       DUMP_START( "reference_type_c_ast", "&&" );
4322       DUMP_AST( "(type_c_ast)", type_ast );
4323       DUMP_TID( "type_qualifier_list_c_stid_opt", $2 );
4324 
4325       $$ = c_ast_new_gc( K_RVALUE_REFERENCE, &@$ );
4326       $$->type.stids = c_tid_check( $2, C_TPID_STORE );
4327       c_ast_set_parent( type_ast, $$ );
4328 
4329       DUMP_AST( "reference_type_c_ast", $$ );
4330       DUMP_END();
4331     }
4332   ;
4333 
4334 /// Gibberish typedef type declaration ////////////////////////////////////////
4335 
4336 typedef_type_decl_c_ast
4337   : // in_attr: type_c_ast
4338     typedef_type_c_ast
4339     {
4340       c_ast_t *const type_ast = ia_type_ast_peek();
4341 
4342       DUMP_START( "typedef_type_decl_c_ast", "typedef_type_c_ast" );
4343       DUMP_AST( "(type_c_ast)", type_ast );
4344       DUMP_AST( "typedef_type_c_ast", $1 );
4345 
4346       if ( c_type_is_tid_any( &type_ast->type, TS_TYPEDEF ) ) {
4347         //
4348         // If we're defining a type, return the type as-is.
4349         //
4350         $$ = $1;
4351       }
4352       else {
4353         //
4354         // Otherwise, return the type that it's typedef'd as.
4355         //
4356         $$ = CONST_CAST( c_ast_t*, c_ast_untypedef( $1 ) );
4357       }
4358 
4359       DUMP_AST( "typedef_type_c_ast", $$ );
4360       DUMP_END();
4361     }
4362   ;
4363 
4364 /// Gibberish C++ user-defined conversion operator declaration ////////////////
4365 
4366 user_defined_conversion_decl_c_astp
4367   : // in_attr: type_c_ast
4368     scope_sname_c_opt Y_OPERATOR type_c_ast
4369     {
4370       ia_type_ast_push( $3 );
4371     }
4372     udc_decl_c_ast_opt lparen_exp rparen_func_qualifier_list_c_stid_opt
4373     noexcept_c_stid_opt func_equals_c_stid_opt
4374     {
4375       ia_type_ast_pop();
4376       c_ast_t *const type_ast = ia_type_ast_peek();
4377 
4378       DUMP_START( "user_defined_conversion_decl_c_astp",
4379                   "scope_sname_c_opt OPERATOR "
4380                   "type_c_ast udc_decl_c_ast_opt '(' ')' "
4381                   "func_qualifier_list_c_stid_opt noexcept_c_stid_opt "
4382                   "func_equals_c_stid_opt" );
4383       DUMP_AST( "(type_c_ast)", type_ast );
4384       DUMP_SNAME( "scope_sname_c_opt", $1 );
4385       DUMP_AST( "type_c_ast", $3 );
4386       DUMP_AST( "udc_decl_c_ast_opt", $5 );
4387       DUMP_TID( "func_qualifier_list_c_stid_opt", $7 );
4388       DUMP_TID( "noexcept_c_stid_opt", $8 );
4389       DUMP_TID( "func_equals_c_stid_opt", $9 );
4390 
4391       $$.ast = c_ast_new_gc( K_USER_DEF_CONVERSION, &@$ );
4392       $$.ast->sname = $1;
4393       $$.ast->type.stids = c_tid_check( $7 | $8 | $9, C_TPID_STORE );
4394       if ( type_ast != NULL )
4395         c_type_or_eq( &$$.ast->type, &type_ast->type );
4396       $$.ast->as.udef_conv.conv_ast = $5 != NULL ? $5 : $3;
4397       $$.target_ast = $$.ast->as.udef_conv.conv_ast;
4398 
4399       DUMP_AST( "user_defined_conversion_decl_c_astp", $$.ast );
4400       DUMP_END();
4401     }
4402   ;
4403 
4404 /// C++ user-definer literal declaration //////////////////////////////////////
4405 
4406 user_defined_literal_decl_c_astp
4407   : // in_attr: type_c_ast
4408     user_defined_literal_c_ast lparen_exp param_list_c_ast_exp ')'
4409     noexcept_c_stid_opt trailing_return_type_c_ast_opt
4410     {
4411       c_ast_t *const udl_c_ast = $1;
4412       c_tid_t  const noexcept_stid = $5;
4413       c_ast_t *const trailing_ret_ast = $6;
4414       c_ast_t *const type_ast = ia_type_ast_peek();
4415 
4416       DUMP_START( "user_defined_literal_decl_c_astp",
4417                   "user_defined_literal_c_ast '(' param_list_c_ast_exp ')' "
4418                   "noexcept_c_stid_opt trailing_return_type_c_ast_opt" );
4419       DUMP_AST( "(type_c_ast)", type_ast );
4420       DUMP_AST( "user_defined_literal_c_ast", udl_c_ast );
4421       DUMP_AST_LIST( "param_list_c_ast_exp", $3 );
4422       DUMP_TID( "noexcept_c_stid_opt", noexcept_stid );
4423       DUMP_AST( "trailing_return_type_c_ast_opt", trailing_ret_ast );
4424 
4425       c_ast_t *const udl_ast = c_ast_new_gc( K_USER_DEF_LITERAL, &@$ );
4426       udl_ast->type.stids = c_tid_check( noexcept_stid, C_TPID_STORE );
4427       udl_ast->as.udef_lit.param_ast_list = $3;
4428 
4429       $$.ast = c_ast_add_func(
4430         udl_c_ast,
4431         udl_ast,
4432         trailing_ret_ast != NULL ? trailing_ret_ast : type_ast
4433       );
4434 
4435       $$.target_ast = udl_ast->as.udef_lit.ret_ast;
4436 
4437       DUMP_AST( "user_defined_literal_decl_c_astp", $$.ast );
4438       DUMP_END();
4439     }
4440   ;
4441 
4442 user_defined_literal_c_ast
4443   : // in_attr: type_c_ast
4444     scope_sname_c_opt Y_OPERATOR quote2_exp name_exp
4445     {
4446       c_ast_t *const type_ast = ia_type_ast_peek();
4447 
4448       DUMP_START( "user_defined_literal_c_ast", "OPERATOR \"\" NAME" );
4449       DUMP_AST( "(type_c_ast)", type_ast );
4450       DUMP_SNAME( "scope_sname_c_opt", $1 );
4451       DUMP_STR( "name", $4 );
4452 
4453       $$ = type_ast;
4454       c_sname_set( &$$->sname, &$1 );
4455       c_sname_append_name( &$$->sname, $4 );
4456 
4457       DUMP_AST( "user_defined_literal_c_ast", $$ );
4458       DUMP_END();
4459     }
4460   ;
4461 
4462 ///////////////////////////////////////////////////////////////////////////////
4463 //  C/C++ CASTS
4464 ///////////////////////////////////////////////////////////////////////////////
4465 
4466 cast_c_astp_opt
4467   : /* empty */                   { $$ = (c_ast_pair_t){ NULL, NULL }; }
4468   | cast_c_astp
4469   ;
4470 
4471 cast_c_astp
4472   : cast2_c_astp
4473   | pointer_cast_c_astp
4474   | pointer_to_member_cast_c_astp
4475   | reference_cast_c_astp
4476   ;
4477 
4478 cast2_c_astp
4479   : array_cast_c_astp
4480   | block_cast_c_astp
4481   | func_cast_c_astp
4482   | nested_cast_c_astp
4483 //| oper_cast_c_astp                    // can't cast to an operator
4484   | sname_c_ast                   { $$ = (c_ast_pair_t){ $1, NULL }; }
4485 //| typedef_type_cast_c_ast             // can't cast to a typedef
4486 //| user_defined_conversion_cast_c_astp // can't cast to a user-defined conv.
4487 //| user_defined_literal_cast_c_astp    // can't cast to a user-defined literal
4488   ;
4489 
4490 /// Gibberish C/C++ array cast ////////////////////////////////////////////////
4491 
4492 array_cast_c_astp
4493   : // in_attr: type_c_ast
4494     cast_c_astp_opt array_size_c_ast
4495     {
4496       c_ast_t *const type_ast = ia_type_ast_peek();
4497       c_ast_t *const array_ast = $2;
4498 
4499       DUMP_START( "array_cast_c_astp", "cast_c_astp_opt array_size_c_ast" );
4500       DUMP_AST( "(type_c_ast)", type_ast );
4501       DUMP_AST( "cast_c_astp_opt", $1.ast );
4502       DUMP_AST( "target_ast", $1.target_ast );
4503       DUMP_AST( "array_size_c_ast", array_ast );
4504 
4505       c_ast_set_parent( c_ast_new_gc( K_PLACEHOLDER, &@1 ), array_ast );
4506 
4507       if ( $1.target_ast != NULL ) {    // array-of or function-like-ret type
4508         $$.ast = $1.ast;
4509         $$.target_ast = c_ast_add_array( $1.target_ast, array_ast, type_ast );
4510       } else {
4511         c_ast_t *const ast = $1.ast != NULL ? $1.ast : type_ast;
4512         $$.ast = c_ast_add_array( ast, array_ast, type_ast );
4513         $$.target_ast = NULL;
4514       }
4515 
4516       DUMP_AST( "array_cast_c_astp", $$.ast );
4517       DUMP_END();
4518     }
4519   ;
4520 
4521 array_size_c_ast
4522   : array_size_c_int
4523     {
4524       $$ = c_ast_new_gc( K_ARRAY, &@$ );
4525       $$->as.array.size = $1;
4526     }
4527   | '[' type_qualifier_list_c_stid rbracket_exp
4528     {
4529       $$ = c_ast_new_gc( K_ARRAY, &@$ );
4530       $$->as.array.size = C_ARRAY_SIZE_NONE;
4531       $$->as.array.stids = c_tid_check( $2, C_TPID_STORE );
4532     }
4533   | '[' type_qualifier_list_c_stid static_stid_opt Y_INT_LIT rbracket_exp
4534     {
4535       $$ = c_ast_new_gc( K_ARRAY, &@$ );
4536       $$->as.array.size = $4;
4537       $$->as.array.stids = c_tid_check( $2 | $3, C_TPID_STORE );
4538     }
4539   | '[' type_qualifier_list_c_stid_opt '*' rbracket_exp
4540     {
4541       $$ = c_ast_new_gc( K_ARRAY, &@$ );
4542       $$->as.array.size = C_ARRAY_SIZE_VARIABLE;
4543       $$->as.array.stids = c_tid_check( $2, C_TPID_STORE );
4544     }
4545   | '[' Y_STATIC type_qualifier_list_c_stid_opt Y_INT_LIT rbracket_exp
4546     {
4547       $$ = c_ast_new_gc( K_ARRAY, &@$ );
4548       $$->as.array.size = $4;
4549       $$->as.array.stids = c_tid_check( $2 | $3, C_TPID_STORE );
4550     }
4551   ;
4552 
4553 /// Gibberish block cast (Apple extension) ////////////////////////////////////
4554 
4555 block_cast_c_astp                       // Apple extension
4556   : // in_attr: type_c_ast
4557     '(' Y_CIRC
4558     { //
4559       // A block AST has to be the type inherited attribute for cast_c_astp_opt
4560       // so we have to create it here.
4561       //
4562       ia_type_ast_push( c_ast_new_gc( K_APPLE_BLOCK, &@$ ) );
4563     }
4564     type_qualifier_list_c_stid_opt cast_c_astp_opt rparen_exp
4565     lparen_exp param_list_c_ast_opt ')'
4566     {
4567       c_ast_t *const block_ast = ia_type_ast_pop();
4568       c_ast_t *const type_ast = ia_type_ast_peek();
4569 
4570       DUMP_START( "block_cast_c_astp",
4571                   "'(' '^' type_qualifier_list_c_stid_opt cast_c_astp_opt ')' "
4572                   "'(' param_list_c_ast_opt ')'" );
4573       DUMP_AST( "(type_c_ast)", type_ast );
4574       DUMP_TID( "type_qualifier_list_c_stid_opt", $4 );
4575       DUMP_AST( "cast_c_astp_opt", $5.ast );
4576       DUMP_AST_LIST( "param_list_c_ast_opt", $8 );
4577 
4578       C_TYPE_ADD_TID( &block_ast->type, $4, @4 );
4579       block_ast->as.block.param_ast_list = $8;
4580       $$.ast = c_ast_add_func( $5.ast, block_ast, type_ast );
4581       $$.target_ast = block_ast->as.block.ret_ast;
4582 
4583       DUMP_AST( "block_cast_c_astp", $$.ast );
4584       DUMP_END();
4585     }
4586   ;
4587 
4588 /// Gibberish C/C++ function cast /////////////////////////////////////////////
4589 
4590 func_cast_c_astp
4591   : // in_attr: type_c_ast
4592     cast2_c_astp '(' param_list_c_ast_opt rparen_func_qualifier_list_c_stid_opt
4593     trailing_return_type_c_ast_opt
4594     {
4595       c_ast_t *const cast2_c_ast = $1.ast;
4596       c_tid_t  const func_ref_qualifier_stid = $4;
4597       c_ast_t *const trailing_ret_ast = $5;
4598       c_ast_t *const type_ast = ia_type_ast_peek();
4599 
4600       DUMP_START( "func_cast_c_astp",
4601                   "cast2_c_astp '(' param_list_c_ast_opt ')' "
4602                   "func_qualifier_list_c_stid_opt "
4603                   "trailing_return_type_c_ast_opt" );
4604       DUMP_AST( "(type_c_ast)", type_ast );
4605       DUMP_AST( "cast2_c_ast", cast2_c_ast );
4606       DUMP_AST_LIST( "param_list_c_ast_opt", $3 );
4607       DUMP_TID( "func_qualifier_list_c_stid_opt", func_ref_qualifier_stid );
4608       DUMP_AST( "trailing_return_type_c_ast_opt", trailing_ret_ast );
4609       DUMP_AST( "target_ast", $1.target_ast );
4610 
4611       c_tid_t const func_stid = func_ref_qualifier_stid;
4612 
4613       c_ast_t *const func_ast = c_ast_new_gc( K_FUNCTION, &@$ );
4614       func_ast->type.stids = c_tid_check( func_stid, C_TPID_STORE );
4615       func_ast->as.func.param_ast_list = $3;
4616 
4617       if ( $1.target_ast != NULL ) {
4618         $$.ast = cast2_c_ast;
4619         PJL_IGNORE_RV( c_ast_add_func( $1.target_ast, func_ast, type_ast ) );
4620       }
4621       else {
4622         $$.ast = c_ast_add_func(
4623           cast2_c_ast,
4624           func_ast,
4625           trailing_ret_ast != NULL ? trailing_ret_ast : type_ast
4626         );
4627       }
4628 
4629       $$.target_ast = func_ast->as.func.ret_ast;
4630 
4631       DUMP_AST( "func_cast_c_astp", $$.ast );
4632       DUMP_END();
4633     }
4634   ;
4635 
4636 /// Gibberish C/C++ nested cast ///////////////////////////////////////////////
4637 
4638 nested_cast_c_astp
4639   : '('
4640     {
4641       ia_type_ast_push( c_ast_new_gc( K_PLACEHOLDER, &@$ ) );
4642       ++ast_depth;
4643     }
4644     cast_c_astp_opt rparen_exp
4645     {
4646       ia_type_ast_pop();
4647       --ast_depth;
4648 
4649       DUMP_START( "nested_cast_c_astp", "'(' cast_c_astp_opt ')'" );
4650       DUMP_AST( "cast_c_astp_opt", $3.ast );
4651 
4652       $$ = $3;
4653       $$.ast->loc = @$;
4654 
4655       DUMP_AST( "nested_cast_c_astp", $$.ast );
4656       DUMP_END();
4657     }
4658   ;
4659 
4660 /// Gibberish C/C++ pointer cast //////////////////////////////////////////////
4661 
4662 pointer_cast_c_astp
4663   : pointer_type_c_ast { ia_type_ast_push( $1 ); } cast_c_astp_opt
4664     {
4665       ia_type_ast_pop();
4666 
4667       DUMP_START( "pointer_cast_c_astp", "pointer_type_c_ast cast_c_astp_opt" );
4668       DUMP_AST( "pointer_type_c_ast", $1 );
4669       DUMP_AST( "cast_c_astp_opt", $3.ast );
4670 
4671       $$.ast = c_ast_patch_placeholder( $1, $3.ast );
4672       $$.target_ast = $3.target_ast;
4673 
4674       DUMP_AST( "pointer_cast_c_astp", $$.ast );
4675       DUMP_END();
4676     }
4677   ;
4678 
4679 /// Gibberish C/C++ pointer-to-member cast ////////////////////////////////////
4680 
4681 pointer_to_member_cast_c_astp
4682   : pointer_to_member_type_c_ast { ia_type_ast_push( $1 ); } cast_c_astp_opt
4683     {
4684       ia_type_ast_pop();
4685 
4686       DUMP_START( "pointer_to_member_cast_c_astp",
4687                   "pointer_to_member_type_c_ast cast_c_astp_opt" );
4688       DUMP_AST( "pointer_to_member_type_c_ast", $1 );
4689       DUMP_AST( "cast_c_astp_opt", $3.ast );
4690 
4691       $$.ast = c_ast_patch_placeholder( $1, $3.ast );
4692       $$.target_ast = $3.target_ast;
4693 
4694       DUMP_AST( "pointer_to_member_cast_c_astp", $$.ast );
4695       DUMP_END();
4696     }
4697   ;
4698 
4699 /// Gibberish C/C++ reference cast ////////////////////////////////////////////
4700 
4701 reference_cast_c_astp
4702   : reference_type_c_ast { ia_type_ast_push( $1 ); } cast_c_astp_opt
4703     {
4704       ia_type_ast_pop();
4705 
4706       DUMP_START( "reference_cast_c_astp",
4707                   "reference_type_c_ast cast_c_astp_opt" );
4708       DUMP_AST( "reference_type_c_ast", $1 );
4709       DUMP_AST( "cast_c_astp_opt", $3.ast );
4710 
4711       $$.ast = c_ast_patch_placeholder( $1, $3.ast );
4712       $$.target_ast = $3.target_ast;
4713 
4714       DUMP_AST( "reference_cast_c_astp", $$.ast );
4715       DUMP_END();
4716     }
4717   ;
4718 
4719 ///////////////////////////////////////////////////////////////////////////////
4720 //  C++ USER-DEFINED CONVERSIONS                                             //
4721 //                                                                           //
4722 //  These productions are a subset of C/C++ cast productions, specifically   //
4723 //  without arrays, blocks, functions, or nested declarations, all of which  //
4724 //  are either illegal or ambiguous.                                         //
4725 ///////////////////////////////////////////////////////////////////////////////
4726 
4727 udc_decl_c_ast_opt
4728   : /* empty */                   { $$ = NULL; }
4729   | udc_decl_c_ast
4730   ;
4731 
4732 udc_decl_c_ast
4733   : pointer_udc_decl_c_ast
4734   | pointer_to_member_udc_decl_c_ast
4735   | reference_udc_decl_c_ast
4736   | sname_c_ast
4737   ;
4738 
4739 pointer_udc_decl_c_ast
4740   : pointer_type_c_ast { ia_type_ast_push( $1 ); } udc_decl_c_ast_opt
4741     {
4742       ia_type_ast_pop();
4743 
4744       DUMP_START( "pointer_udc_decl_c_ast",
4745                   "pointer_type_c_ast udc_decl_c_ast_opt" );
4746       DUMP_AST( "pointer_type_c_ast", $1 );
4747       DUMP_AST( "udc_decl_c_ast_opt", $3 );
4748 
4749       $$ = c_ast_patch_placeholder( $1, $3 );
4750 
4751       DUMP_AST( "pointer_udc_decl_c_ast", $$ );
4752       DUMP_END();
4753     }
4754   ;
4755 
4756 pointer_to_member_udc_decl_c_ast
4757   : pointer_to_member_type_c_ast { ia_type_ast_push( $1 ); } udc_decl_c_ast_opt
4758     {
4759       ia_type_ast_pop();
4760 
4761       DUMP_START( "pointer_to_member_udc_decl_c_ast",
4762                   "pointer_to_member_type_c_ast udc_decl_c_ast_opt" );
4763       DUMP_AST( "pointer_to_member_type_c_ast", $1 );
4764       DUMP_AST( "udc_decl_c_ast_opt", $3 );
4765 
4766       $$ = c_ast_patch_placeholder( $1, $3 );
4767 
4768       DUMP_AST( "pointer_to_member_udc_decl_c_ast", $$ );
4769       DUMP_END();
4770     }
4771   ;
4772 
4773 reference_udc_decl_c_ast
4774   : reference_type_c_ast { ia_type_ast_push( $1 ); } udc_decl_c_ast_opt
4775     {
4776       ia_type_ast_pop();
4777 
4778       DUMP_START( "reference_udc_decl_c_ast",
4779                   "reference_type_c_ast udc_decl_c_ast_opt" );
4780       DUMP_AST( "reference_type_c_ast", $1 );
4781       DUMP_AST( "udc_decl_c_ast_opt", $3 );
4782 
4783       $$ = c_ast_patch_placeholder( $1, $3 );
4784 
4785       DUMP_AST( "reference_udc_decl_c_ast", $$ );
4786       DUMP_END();
4787     }
4788   ;
4789 
4790 ///////////////////////////////////////////////////////////////////////////////
4791 //  C/C++ TYPES                                                              //
4792 ///////////////////////////////////////////////////////////////////////////////
4793 
4794 type_c_ast
4795     /*
4796      * Type-modifier-only (implicit int) declarations:
4797      *
4798      *      unsigned i;
4799      */
4800   : type_modifier_list_c_type           // allows implicit int in K&R C
4801     {
4802       DUMP_START( "type_c_ast", "type_modifier_list_c_type" );
4803       DUMP_TYPE( "type_modifier_list_c_type", $1 );
4804 
4805       //
4806       // Prior to C99, typeless declarations are implicitly int, so we set it
4807       // here.  In C99 and later, however, implicit int is an error, so we
4808       // don't set it here and c_ast_check() will catch the error later.
4809       //
4810       // Note that type modifiers, e.g., unsigned, count as a type since that
4811       // means unsigned int; however, neither qualifiers, e.g., const, nor
4812       // storage classes, e.g., register, by themselves count as a type:
4813       //
4814       //      unsigned i;   // legal in C99
4815       //      const    j;   // illegal in C99
4816       //      register k;   // illegal in C99
4817       //
4818       c_type_t type = opt_lang < LANG_C_99 ? C_TYPE_LIT_B( TB_INT ) : T_NONE;
4819 
4820       C_TYPE_ADD( &type, &$1, @1 );
4821 
4822       $$ = c_ast_new_gc( K_BUILTIN, &@$ );
4823       $$->type = type;
4824 
4825       DUMP_AST( "type_c_ast", $$ );
4826       DUMP_END();
4827     }
4828 
4829     /*
4830      * Type-modifier type with optional trailing type-modifier(s) declarations:
4831      *
4832      *      unsigned int const i;       // uncommon, but legal
4833      */
4834   | type_modifier_list_c_type east_modified_type_c_ast
4835     {
4836       DUMP_START( "type_c_ast",
4837                   "type_modifier_list_c_type east_modified_type_c_ast " );
4838       DUMP_TYPE( "type_modifier_list_c_type", $1 );
4839       DUMP_AST( "east_modified_type_c_ast", $2 );
4840 
4841       $$ = $2;
4842       $$->loc = @$;
4843       C_TYPE_ADD( &$$->type, &$1, @1 );
4844 
4845       DUMP_AST( "type_c_ast", $$ );
4846       DUMP_END();
4847     }
4848 
4849   | east_modified_type_c_ast
4850   ;
4851 
4852 type_modifier_list_c_type_opt
4853   : /* empty */                   { $$ = T_NONE; }
4854   | type_modifier_list_c_type
4855   ;
4856 
4857 type_modifier_list_c_type
4858   : type_modifier_list_c_type type_modifier_c_type
4859     {
4860       DUMP_START( "type_modifier_list_c_type",
4861                   "type_modifier_list_c_type type_modifier_c_type" );
4862       DUMP_TYPE( "type_modifier_list_c_type", $1 );
4863       DUMP_TYPE( "type_modifier_c_type", $2 );
4864 
4865       $$ = $1;
4866       C_TYPE_ADD( &$$, &$2, @2 );
4867 
4868       DUMP_TYPE( "type_modifier_list_c_type", $$ );
4869       DUMP_END();
4870     }
4871 
4872   | type_modifier_c_type
4873   ;
4874 
4875 type_modifier_c_type
4876   : type_modifier_base_type
4877     {
4878       $$ = $1;
4879       //
4880       // This is for a case like:
4881       //
4882       //      explain typedef unsigned long size_t
4883       //
4884       // that is: explain a redefinition of a typedef'd type with the same type
4885       // that contains only one or more type_modifier_base_type.  The problem
4886       // is that, without an east_modified_type_c_ast (like int), the parser
4887       // would ordinarily take the typedef'd type (here, the size_t) as part of
4888       // the type_c_ast and then be out of tokens for the decl_c_astp -- at
4889       // which time it'll complain.
4890       //
4891       // Since type modifiers can't apply to a typedef'd type (e.g., "long
4892       // size_t" is illegal), we tell the lexer not to return either
4893       // Y_TYPEDEF_NAME or Y_TYPEDEF_SNAME if we encounter at least one type
4894       // modifier (except "register" since it's is really a storage class --
4895       // see the comment in type_modifier_base_type about "register").
4896       //
4897       if ( $$.stids == TS_REGISTER )
4898         lexer_find |= LEXER_FIND_TYPEDEFS;
4899       else
4900         lexer_find &= ~LEXER_FIND_TYPEDEFS;
4901     }
4902   | type_qualifier_c_stid         { $$ = C_TYPE_LIT_S( $1 ); }
4903   | storage_class_c_type
4904   | attribute_specifier_list_c_atid
4905     {
4906       $$ = C_TYPE_LIT_A( $1 );
4907     }
4908   ;
4909 
4910 type_modifier_base_type
4911   : Y__COMPLEX                    { $$ = C_TYPE_LIT_B( $1 ); }
4912   | Y__IMAGINARY                  { $$ = C_TYPE_LIT_B( $1 ); }
4913   | Y_LONG                        { $$ = C_TYPE_LIT_B( $1 ); }
4914   | Y_SHORT                       { $$ = C_TYPE_LIT_B( $1 ); }
4915   | Y_SIGNED                      { $$ = C_TYPE_LIT_B( $1 ); }
4916   | Y_UNSIGNED                    { $$ = C_TYPE_LIT_B( $1 ); }
4917   | Y_EMC__SAT                    { $$ = C_TYPE_LIT_B( $1 ); }
4918     /*
4919      * Register is here (rather than in storage_class_c_type) because it's the
4920      * only storage class that can be specified for function parameters.
4921      * Therefore, it's simpler to treat it as any other type modifier.
4922      */
4923   | Y_REGISTER                    { $$ = C_TYPE_LIT_S( $1 ); }
4924   ;
4925 
4926 east_modified_type_c_ast
4927   : atomic_builtin_typedef_type_c_ast type_modifier_list_c_type_opt
4928     {
4929       DUMP_START( "east_modified_type_c_ast",
4930                   "atomic_builtin_typedef_type_c_ast "
4931                   "type_modifier_list_c_type_opt" );
4932       DUMP_AST( "atomic_builtin_typedef_type_c_ast", $1 );
4933       DUMP_TYPE( "type_modifier_list_c_type_opt", $2 );
4934 
4935       $$ = $1;
4936       $$->loc = @$;
4937       C_TYPE_ADD( &$$->type, &$2, @2 );
4938 
4939       DUMP_AST( "type_c_ast", $$ );
4940       DUMP_END();
4941     }
4942 
4943   | enum_class_struct_union_c_ast cv_qualifier_list_stid_opt
4944     {
4945       DUMP_START( "east_modified_type_c_ast",
4946                   "enum_class_struct_union_c_ast cv_qualifier_list_stid_opt" );
4947       DUMP_AST( "enum_class_struct_union_c_ast", $1 );
4948       DUMP_TID( "cv_qualifier_list_stid_opt", $2 );
4949 
4950       $$ = $1;
4951       $$->loc = @$;
4952       C_TYPE_ADD_TID( &$$->type, $2, @2 );
4953 
4954       DUMP_AST( "east_modified_type_c_ast", $$ );
4955       DUMP_END();
4956     }
4957   ;
4958 
4959 atomic_builtin_typedef_type_c_ast
4960   : atomic_specifier_type_c_ast
4961   | builtin_type_ast
4962   | typedef_type_c_ast
4963   ;
4964 
4965 /// C Gibberish _Atomic types /////////////////////////////////////////////////
4966 
4967 atomic_specifier_type_c_ast
4968   : Y__ATOMIC_SPEC lparen_exp type_c_ast
4969     {
4970       ia_type_ast_push( $3 );
4971     }
4972     cast_c_astp_opt rparen_exp
4973     {
4974       ia_type_ast_pop();
4975 
4976       DUMP_START( "atomic_specifier_type_c_ast",
4977                   "ATOMIC '(' type_c_ast cast_c_astp_opt ')'" );
4978       DUMP_AST( "type_c_ast", $3 );
4979       DUMP_AST( "cast_c_astp_opt", $5.ast );
4980 
4981       $$ = $5.ast != NULL ? $5.ast : $3;
4982       $$->loc = @$;
4983 
4984       //
4985       // Ensure the _Atomic() specifier type doesn't have either a storage
4986       // class or attributes:
4987       //
4988       //      const _Atomic(int) x;     // OK
4989       //      _Atomic(const int) y;     // error
4990       //
4991       // This check has to be done now in the parser rather than later in the
4992       // AST since the type would be stored as "atomic const int" either way so
4993       // the AST has no "memory" of which it was.
4994       //
4995       if ( $$->type.stids != TS_NONE || $$->type.atids != TA_NONE ) {
4996         static c_type_t const TSA_ANY = { TB_NONE, TS_ANY, TA_ANY };
4997         c_type_t const error_type = c_type_and( &$$->type, &TSA_ANY );
4998         print_error( &@3,
4999           "%s can not be of \"%s\"\n",
5000           L__ATOMIC, c_type_name_c( &error_type )
5001         );
5002         PARSE_ABORT();
5003       }
5004 
5005       C_TYPE_ADD_TID( &$$->type, TS_ATOMIC, @1 );
5006 
5007       DUMP_AST( "atomic_specifier_type_c_ast", $$ );
5008       DUMP_END();
5009     }
5010   ;
5011 
5012 /// Gibberish C/C++ built-in types ////////////////////////////////////////////
5013 
5014 builtin_type_ast
5015   : builtin_btid
5016     {
5017       DUMP_START( "builtin_type_ast", "builtin_btid" );
5018       DUMP_TID( "builtin_btid", $1 );
5019 
5020       $$ = c_ast_new_gc( K_BUILTIN, &@$ );
5021       $$->type.btids = c_tid_check( $1, C_TPID_BASE );
5022 
5023       DUMP_AST( "builtin_type_ast", $$ );
5024       DUMP_END();
5025     }
5026   ;
5027 
5028 builtin_btid
5029   : Y_VOID
5030   | Y_AUTO_TYPE
5031   | Y__BOOL
5032   | Y_BOOL
5033   | Y_CHAR
5034   | Y_CHAR8_T
5035   | Y_CHAR16_T
5036   | Y_CHAR32_T
5037   | Y_WCHAR_T
5038   | Y_INT
5039   | Y_FLOAT
5040   | Y_DOUBLE
5041   | Y_EMC__ACCUM
5042   | Y_EMC__FRACT
5043   ;
5044 
5045 /// Gibberish C/C++ enum, class, struct, & union types ////////////////////////
5046 
5047 enum_class_struct_union_c_ast
5048   : enum_class_struct_union_c_btid attribute_specifier_list_c_atid_opt
5049     any_sname_c_exp enum_fixed_type_c_ast_opt
5050     {
5051       DUMP_START( "enum_class_struct_union_c_ast",
5052                   "enum_class_struct_union_c_btid "
5053                   "attribute_specifier_list_c_atid_opt sname" );
5054       DUMP_TID( "enum_class_struct_union_c_btid", $1 );
5055       DUMP_TID( "attribute_specifier_list_c_atid_opt", $2 );
5056       DUMP_SNAME( "any_sname_c", $3 );
5057       DUMP_AST( "enum_fixed_type_c_ast_opt", $4 );
5058 
5059       $$ = c_ast_new_gc( K_ENUM_CLASS_STRUCT_UNION, &@$ );
5060       $$->type.btids = c_tid_check( $1, C_TPID_BASE );
5061       $$->type.atids = c_tid_check( $2, C_TPID_ATTR );
5062       $$->as.ecsu.of_ast = $4;
5063       $$->as.ecsu.ecsu_sname = $3;
5064 
5065       DUMP_AST( "enum_class_struct_union_c_ast", $$ );
5066       DUMP_END();
5067     }
5068 
5069   | enum_class_struct_union_c_btid attribute_specifier_list_c_atid_opt
5070     any_sname_c_opt '{'
5071     {
5072       print_error( &@4,
5073         "explaining %s declarations not supported by %s\n",
5074         c_tid_name_c( $1 ), CDECL
5075       );
5076       c_sname_cleanup( &$3 );
5077       PARSE_ABORT();
5078     }
5079   ;
5080 
5081 enum_class_struct_union_c_btid
5082   : enum_btid
5083   | class_struct_union_btid
5084   ;
5085 
5086 /// Gibberish C/C++ enum type /////////////////////////////////////////////////
5087 
5088 enum_btid
5089   : Y_ENUM class_struct_btid_opt  { $$ = $1 | $2; }
5090   ;
5091 
5092 enum_fixed_type_c_ast_opt
5093   : /* empty */                   { $$ = NULL; }
5094   | ':' enum_fixed_type_c_ast     { $$ = $2; }
5095   | ':' error
5096     {
5097       elaborate_error( "type name expected" );
5098     }
5099   ;
5100 
5101     /*
5102      * These rules are a subset of type_c_ast for an enum's fixed type to
5103      * decrease the number of shift/reduce conflicts.
5104      */
5105 enum_fixed_type_c_ast
5106     /*
5107      * Type-modifier-only (implicit int):
5108      *
5109      *      enum E : unsigned
5110      */
5111   : enum_fixed_type_modifier_list_btid
5112     {
5113       DUMP_START( "enum_fixed_type_c_ast",
5114                   "enum_fixed_type_modifier_list_btid" );
5115       DUMP_TID( "enum_fixed_type_modifier_list_btid", $1 );
5116 
5117       $$ = c_ast_new_gc( K_BUILTIN, &@1 );
5118       $$->type.btids = c_tid_check( $1, C_TPID_BASE );
5119 
5120       DUMP_AST( "enum_fixed_type_c_ast", $$ );
5121       DUMP_END();
5122     }
5123 
5124     /*
5125      * Type-modifier(s) type with optional training type-modifier(s):
5126      *
5127      *      enum E : short int unsigned // uncommon, but legal
5128      */
5129   | enum_fixed_type_modifier_list_btid enum_unmodified_fixed_type_c_ast
5130     enum_fixed_type_modifier_list_btid_opt
5131     {
5132       DUMP_START( "enum_fixed_type_c_ast",
5133                   "enum_fixed_type_modifier_list_btid "
5134                   "enum_unmodified_fixed_type_c_ast "
5135                   "enum_fixed_type_modifier_list_btid_opt" );
5136       DUMP_TID( "enum_fixed_type_modifier_list_btid", $1 );
5137       DUMP_AST( "enum_unmodified_fixed_type_c_ast", $2 );
5138       DUMP_TID( "enum_fixed_type_modifier_list_btid_opt", $3 );
5139 
5140       $$ = $2;
5141       $$->loc = @$;
5142       C_TYPE_ADD_TID( &$$->type, $1, @1 );
5143       C_TYPE_ADD_TID( &$$->type, $3, @3 );
5144 
5145       DUMP_AST( "enum_fixed_type_c_ast", $$ );
5146       DUMP_END();
5147     }
5148 
5149     /*
5150      * Type with trailing type-modifier(s):
5151      *
5152      *      enum E : int unsigned       // uncommon, but legal
5153      */
5154   | enum_unmodified_fixed_type_c_ast enum_fixed_type_modifier_list_btid_opt
5155     {
5156       DUMP_START( "enum_fixed_type_c_ast",
5157                   "enum_unmodified_fixed_type_c_ast "
5158                   "enum_fixed_type_modifier_list_btid_opt" );
5159       DUMP_AST( "enum_unmodified_fixed_type_c_ast", $1 );
5160       DUMP_TID( "enum_fixed_type_modifier_list_btid_opt", $2 );
5161 
5162       $$ = $1;
5163       $$->loc = @$;
5164       C_TYPE_ADD_TID( &$$->type, $2, @2 );
5165 
5166       DUMP_AST( "enum_fixed_type_c_ast", $$ );
5167       DUMP_END();
5168     }
5169   ;
5170 
5171 enum_fixed_type_modifier_list_btid_opt
5172   : /* empty */                   { $$ = TB_NONE; }
5173   | enum_fixed_type_modifier_list_btid
5174   ;
5175 
5176 enum_fixed_type_modifier_list_btid
5177   : enum_fixed_type_modifier_list_btid enum_fixed_type_modifier_btid
5178     {
5179       DUMP_START( "enum_fixed_type_modifier_list_btid",
5180                   "enum_fixed_type_modifier_list_btid "
5181                   "enum_fixed_type_modifier_btid" );
5182       DUMP_TID( "enum_fixed_type_modifier_list_btid", $1 );
5183       DUMP_TID( "enum_fixed_type_modifier_btid", $2 );
5184 
5185       $$ = $1;
5186       C_TID_ADD( &$$, $2, @2 );
5187 
5188       DUMP_TID( "enum_fixed_type_modifier_list_btid", $$ );
5189       DUMP_END();
5190     }
5191 
5192   | enum_fixed_type_modifier_btid
5193   ;
5194 
5195 enum_fixed_type_modifier_btid
5196   : Y_LONG
5197   | Y_SHORT
5198   | Y_SIGNED
5199   | Y_UNSIGNED
5200   ;
5201 
5202 enum_unmodified_fixed_type_c_ast
5203   : builtin_type_ast
5204   | typedef_type_c_ast
5205   ;
5206 
5207 /// Gibberish C/C++ class, struct, & union types //////////////////////////////
5208 
5209 class_struct_btid_opt
5210   : /* empty */                   { $$ = TB_NONE; }
5211   | class_struct_btid
5212   ;
5213 
5214 class_struct_btid
5215   : Y_CLASS
5216   | Y_STRUCT
5217   ;
5218 
5219 class_struct_union_btid
5220   : class_struct_btid
5221   | Y_UNION
5222   ;
5223 
5224 /// Gibberish C/C++ type qualifiers ///////////////////////////////////////////
5225 
5226 type_qualifier_list_c_stid_opt
5227   : /* empty */                   { $$ = TS_NONE; }
5228   | type_qualifier_list_c_stid
5229   ;
5230 
5231 type_qualifier_list_c_stid
5232   : type_qualifier_list_c_stid type_qualifier_c_stid
5233     gnu_or_msc_attribute_specifier_list_c_opt
5234     {
5235       DUMP_START( "type_qualifier_list_c_stid",
5236                   "type_qualifier_list_c_stid type_qualifier_c_stid" );
5237       DUMP_TID( "type_qualifier_list_c_stid", $1 );
5238       DUMP_TID( "type_qualifier_c_stid", $2 );
5239 
5240       $$ = $1;
5241       C_TID_ADD( &$$, $2, @2 );
5242 
5243       DUMP_TID( "type_qualifier_list_c_stid", $$ );
5244       DUMP_END();
5245     }
5246 
5247   | gnu_or_msc_attribute_specifier_list_c type_qualifier_c_stid
5248     {
5249       $$ = $2;
5250     }
5251 
5252   | type_qualifier_c_stid gnu_or_msc_attribute_specifier_list_c_opt
5253     {
5254       $$ = $1;
5255     }
5256   ;
5257 
5258 type_qualifier_c_stid
5259   : Y__ATOMIC_QUAL
5260   | cv_qualifier_stid
5261   | restrict_qualifier_c_stid
5262   | Y_UPC_RELAXED
5263   | Y_UPC_SHARED                  %prec Y_PREC_LESS_THAN_upc_layout_qualifier
5264   | Y_UPC_SHARED upc_layout_qualifier_c
5265   | Y_UPC_STRICT
5266   ;
5267 
5268 cv_qualifier_stid
5269   : Y_CONST
5270   | Y_VOLATILE
5271   ;
5272 
5273 cv_qualifier_list_stid_opt
5274   : /* empty */                   { $$ = TS_NONE; }
5275   | cv_qualifier_list_stid_opt cv_qualifier_stid
5276     {
5277       DUMP_START( "cv_qualifier_list_stid_opt",
5278                   "cv_qualifier_list_stid_opt cv_qualifier_stid" );
5279       DUMP_TID( "cv_qualifier_list_stid_opt", $1 );
5280       DUMP_TID( "cv_qualifier_stid", $2 );
5281 
5282       $$ = $1;
5283       C_TID_ADD( &$$, $2, @2 );
5284 
5285       DUMP_TID( "cv_qualifier_list_stid_opt", $$ );
5286       DUMP_END();
5287     }
5288   ;
5289 
5290 restrict_qualifier_c_stid
5291   : Y_RESTRICT                          // C only
5292     { //
5293       // This check has to be done now in the parser rather than later in the
5294       // AST since both "restrict" and "__restrict" map to TS_RESTRICT and the
5295       // AST has no "memory" of which it was.
5296       //
5297       if ( OPT_LANG_IS(CPP_ANY) ) {
5298         print_error( &@1,
5299           "\"%s\" not supported in C++; use \"%s\" instead\n",
5300           L_RESTRICT, L_GNU___RESTRICT
5301         );
5302         PARSE_ABORT();
5303       }
5304     }
5305   | Y_GNU___RESTRICT                    // GNU C/C++ extension
5306   ;
5307 
5308 upc_layout_qualifier_c
5309   : '[' ']'
5310   | '[' Y_INT_LIT rbracket_exp
5311   | '[' '*' rbracket_exp
5312   | '[' error ']'
5313     {
5314       elaborate_error( "one of nothing, integer, or '*' expected" );
5315     }
5316   ;
5317 
5318 /// Gibberish C/C++ storage classes ///////////////////////////////////////////
5319 
5320 storage_class_c_type
5321   : Y_AUTO_STORAGE                { $$ = C_TYPE_LIT_S( $1 ); }
5322   | Y_APPLE___BLOCK               { $$ = C_TYPE_LIT_S( $1 ); }
5323   | Y_CONSTEVAL                   { $$ = C_TYPE_LIT_S( $1 ); }
5324   | Y_CONSTEXPR                   { $$ = C_TYPE_LIT_S( $1 ); }
5325   | Y_CONSTINIT                   { $$ = C_TYPE_LIT_S( $1 ); }
5326   | Y_EXPLICIT                    { $$ = C_TYPE_LIT_S( $1 ); }
5327   | Y_EXPORT                      { $$ = C_TYPE_LIT_S( $1 ); }
5328   | Y_EXTERN                      { $$ = C_TYPE_LIT_S( $1 ); }
5329   | extern_linkage_c_stid         { $$ = C_TYPE_LIT_S( $1 ); }
5330   | Y_FINAL                       { $$ = C_TYPE_LIT_S( $1 ); }
5331   | Y_FRIEND                      { $$ = C_TYPE_LIT_S( $1 ); }
5332   | Y_INLINE                      { $$ = C_TYPE_LIT_S( $1 ); }
5333   | Y_MUTABLE                     { $$ = C_TYPE_LIT_S( $1 ); }
5334   | Y__NORETURN                   { $$ = C_TYPE_LIT_A( $1 ); }
5335   | Y_NORETURN                    { $$ = C_TYPE_LIT_A( $1 ); }
5336   | Y_OVERRIDE                    { $$ = C_TYPE_LIT_S( $1 ); }
5337 //| Y_REGISTER                          // in type_modifier_base_type
5338   | Y_STATIC                      { $$ = C_TYPE_LIT_S( $1 ); }
5339   | Y_TYPEDEF                     { $$ = C_TYPE_LIT_S( $1 ); }
5340   | Y__THREAD_LOCAL               { $$ = C_TYPE_LIT_S( $1 ); }
5341   | Y_THREAD_LOCAL                { $$ = C_TYPE_LIT_S( $1 ); }
5342   | Y_VIRTUAL                     { $$ = C_TYPE_LIT_S( $1 ); }
5343   ;
5344 
5345 /// Gibberish C/C++ attributes ////////////////////////////////////////////////
5346 
5347 attribute_specifier_list_c_atid_opt
5348   : /* empty */                   { $$ = TA_NONE; }
5349   | attribute_specifier_list_c_atid
5350   ;
5351 
5352 attribute_specifier_list_c_atid
5353   : Y_ATTR_BEGIN '['
5354     {
5355       if ( unsupported( LANG_C_CPP_MIN(2X,11) ) ) {
5356         print_error( &@1,
5357           "\"[[\" attribute syntax not supported%s\n",
5358           c_lang_which( LANG_C_CPP_MIN(2X,11) )
5359         );
5360         PARSE_ABORT();
5361       }
5362       lexer_keyword_ctx = C_KW_CTX_ATTRIBUTE;
5363     }
5364     using_opt attribute_list_c_atid_opt ']' rbracket_exp
5365     {
5366       lexer_keyword_ctx = C_KW_CTX_DEFAULT;
5367 
5368       DUMP_START( "attribute_specifier_list_c_atid",
5369                   "'[[' using_opt attribute_list_c_atid_opt ']]'" );
5370       DUMP_TID( "attribute_list_c_atid_opt", $5 );
5371 
5372       $$ = $5;
5373 
5374       DUMP_END();
5375     }
5376 
5377   | gnu_or_msc_attribute_specifier_list_c
5378     {
5379       $$ = TA_NONE;
5380     }
5381   ;
5382 
5383 using_opt
5384   : /* empty */
5385   | Y_USING name_exp colon_exp
5386     {
5387       print_warning( &@1,
5388         "\"%s\" in attributes not supported by %s (ignoring)\n",
5389         L_USING, CDECL
5390       );
5391       free( $2 );
5392     }
5393   ;
5394 
5395 attribute_list_c_atid_opt
5396   : /* empty */                   { $$ = TA_NONE; }
5397   | attribute_list_c_atid
5398   ;
5399 
5400 attribute_list_c_atid
5401   : attribute_list_c_atid comma_exp attribute_c_atid
5402     {
5403       DUMP_START( "attribute_list_c_atid",
5404                   "attribute_list_c_atid , attribute_c_atid" );
5405       DUMP_TID( "attribute_list_c_atid", $1 );
5406       DUMP_TID( "attribute_c_atid", $3 );
5407 
5408       $$ = $1;
5409       C_TID_ADD( &$$, $3, @3 );
5410 
5411       DUMP_TID( "attribute_list_c_atid", $$ );
5412       DUMP_END();
5413     }
5414 
5415   | attribute_c_atid
5416   ;
5417 
5418 attribute_c_atid
5419   : Y_CARRIES_DEPENDENCY
5420   | Y_DEPRECATED attribute_str_arg_c_opt
5421   | Y_MAYBE_UNUSED
5422   | Y_NODISCARD attribute_str_arg_c_opt
5423   | Y_NORETURN
5424   | Y_NO_UNIQUE_ADDRESS
5425   | sname_c
5426     {
5427       if ( c_sname_count( &$1 ) > 1 ) {
5428         print_warning( &@1,
5429           "\"%s\": namespaced attributes not supported by %s\n",
5430           c_sname_full_name( &$1 ), CDECL
5431         );
5432       }
5433       else {
5434         char const *adj = "unknown";
5435         c_lang_id_t lang_ids = LANG_NONE;
5436 
5437         char const *const name = c_sname_local_name( &$1 );
5438         c_keyword_t const *const k =
5439           c_keyword_find( name, opt_lang_newer(), C_KW_CTX_ATTRIBUTE );
5440         if ( k != NULL && c_tid_tpid( k->tid ) == C_TPID_ATTR ) {
5441           adj = "unsupported";
5442           lang_ids = k->lang_ids;
5443         }
5444         print_warning( &@1,
5445           "\"%s\": %s attribute%s",
5446           name, adj, c_lang_which( lang_ids )
5447         );
5448 
5449         print_suggestions( DYM_C_ATTRIBUTES, name );
5450         EPUTC( '\n' );
5451       }
5452 
5453       $$ = TA_NONE;
5454       c_sname_cleanup( &$1 );
5455     }
5456   | error
5457     {
5458       elaborate_error_dym( DYM_C_ATTRIBUTES, "attribute name expected" );
5459     }
5460   ;
5461 
5462 attribute_str_arg_c_opt
5463   : /* empty */
5464   | '(' str_lit_exp rparen_exp
5465     {
5466       print_warning( &@1,
5467         "attribute arguments not supported by %s (ignoring)\n", CDECL
5468       );
5469       free( $2 );
5470     }
5471   ;
5472 
5473 gnu_or_msc_attribute_specifier_list_c_opt
5474   : /* empty */
5475   | gnu_or_msc_attribute_specifier_list_c
5476   ;
5477 
5478 gnu_or_msc_attribute_specifier_list_c
5479   : gnu_attribute_specifier_list_c
5480   | msc_attribute_specifier_list_c
5481   ;
5482 
5483 gnu_attribute_specifier_list_c_opt
5484   : /* empty */
5485   | gnu_attribute_specifier_list_c
5486   ;
5487 
5488 gnu_attribute_specifier_list_c
5489   : gnu_attribute_specifier_list_c gnu_attribute_specifier_c
5490   | gnu_attribute_specifier_c
5491   ;
5492 
5493 gnu_attribute_specifier_c
5494   : Y_GNU___ATTRIBUTE__
5495     {
5496       attr_syntax_not_supported( &@1, L_GNU___ATTRIBUTE__ );
5497       //
5498       // Temporariy disabling finding keywords allows GNU attributes that are C
5499       // keywords (e.g., const) to be found as ordinary string literals.
5500       //
5501       lexer_find &= ~LEXER_FIND_C_KEYWORDS;
5502     }
5503     lparen_exp lparen_exp gnu_attribute_list_c_opt ')' rparen_exp
5504     {
5505       lexer_find |= LEXER_FIND_C_KEYWORDS;
5506     }
5507   ;
5508 
5509 gnu_attribute_list_c_opt
5510   : /* empty */
5511   | gnu_attribuet_list_c
5512   ;
5513 
5514 gnu_attribuet_list_c
5515   : gnu_attribuet_list_c comma_exp gnu_attribute_c
5516   | gnu_attribute_c
5517   ;
5518 
5519 gnu_attribute_c
5520   : Y_NAME gnu_attribute_decl_arg_list_c_opt
5521     {
5522       free( $1 );
5523     }
5524   | error
5525     {
5526       elaborate_error( "attribute name expected" );
5527     }
5528   ;
5529 
5530 gnu_attribute_decl_arg_list_c_opt
5531   : /* empty */
5532   | '(' gnu_attribute_arg_list_c_opt ')'
5533   ;
5534 
5535 gnu_attribute_arg_list_c_opt
5536   : /* empty */
5537   | gnu_attribute_arg_list_c
5538   ;
5539 
5540 gnu_attribute_arg_list_c
5541   : gnu_attribute_arg_list_c comma_exp gnu_attribute_arg_c
5542   | gnu_attribute_arg_c
5543   ;
5544 
5545 gnu_attribute_arg_c
5546   : Y_NAME                        { free( $1 ); }
5547   | Y_INT_LIT
5548   | Y_CHAR_LIT                    { free( $1 ); }
5549   | Y_STR_LIT                     { free( $1 ); }
5550   | '(' gnu_attribute_arg_list_c rparen_exp
5551   | Y_LEXER_ERROR
5552     {
5553       PARSE_ABORT();
5554     }
5555   ;
5556 
5557 msc_attribute_specifier_list_c
5558   : msc_attribute_specifier_list_c msc_attribute_specifier_c
5559   | msc_attribute_specifier_c
5560   ;
5561 
5562 msc_attribute_specifier_c
5563   : Y_MSC___DECLSPEC
5564     {
5565       attr_syntax_not_supported( &@1, L_MSC___DECLSPEC );
5566       // See comment in gnu_attribute_specifier_c.
5567       lexer_find &= ~LEXER_FIND_C_KEYWORDS;
5568     }
5569     lparen_exp msc_attribute_list_c_opt ')'
5570     {
5571       lexer_find |= LEXER_FIND_C_KEYWORDS;
5572     }
5573   ;
5574 
5575 msc_attribute_list_c_opt
5576   : /* empty */
5577   | msc_attribuet_list_c
5578   ;
5579 
5580 msc_attribuet_list_c
5581     /*
5582      * Microsoft's syntax for individual attributes is the same as GNU's, so we
5583      * can just use gnu_attribute_c here.
5584      *
5585      * Note that Microsoft attributes are separated by whitespace, not commas
5586      * as in GNU's, so that's why msc_attribuet_list_c is needed.
5587      */
5588   : msc_attribuet_list_c gnu_attribute_c
5589   | gnu_attribute_c
5590   ;
5591 
5592 ///////////////////////////////////////////////////////////////////////////////
5593 //  ENGLISH DECLARATIONS                                                     //
5594 ///////////////////////////////////////////////////////////////////////////////
5595 
5596 decl_english_ast
5597   : array_decl_english_ast
5598   | constructor_decl_english_ast
5599   | destructor_decl_english_ast
5600   | qualified_decl_english_ast
5601   | user_defined_literal_decl_english_ast
5602   | var_decl_english_ast
5603   ;
5604 
5605 /// English C/C++ array declaration ///////////////////////////////////////////
5606 
5607 array_decl_english_ast
5608   : Y_ARRAY static_stid_opt array_qualifier_list_english_stid_opt
5609     array_size_int_opt of_exp decl_english_ast
5610     {
5611       DUMP_START( "array_decl_english_ast",
5612                   "ARRAY static_stid_opt array_qualifier_list_english_stid_opt "
5613                   "array_size_num_opt OF decl_english_ast" );
5614       DUMP_TID( "static_stid_opt", $2 );
5615       DUMP_TID( "array_qualifier_list_english_stid_opt", $3 );
5616       DUMP_INT( "array_size_int_opt", $4 );
5617       DUMP_AST( "decl_english_ast", $6 );
5618 
5619       $$ = c_ast_new_gc( K_ARRAY, &@$ );
5620       $$->as.array.size = $4;
5621       $$->as.array.stids = c_tid_check( $2 | $3, C_TPID_STORE );
5622       c_ast_set_parent( $6, $$ );
5623 
5624       DUMP_AST( "array_decl_english_ast", $$ );
5625       DUMP_END();
5626     }
5627 
5628   | Y_VARIABLE length_opt array_exp array_qualifier_list_english_stid_opt
5629     of_exp decl_english_ast
5630     {
5631       DUMP_START( "array_decl_english_ast",
5632                   "VARIABLE LENGTH ARRAY array_qualifier_list_english_stid_opt "
5633                   "OF decl_english_ast" );
5634       DUMP_TID( "array_qualifier_list_english_stid_opt", $4 );
5635       DUMP_AST( "decl_english_ast", $6 );
5636 
5637       $$ = c_ast_new_gc( K_ARRAY, &@$ );
5638       $$->as.array.size = C_ARRAY_SIZE_VARIABLE;
5639       $$->as.array.stids = c_tid_check( $4, C_TPID_STORE );
5640       c_ast_set_parent( $6, $$ );
5641 
5642       DUMP_AST( "array_decl_english_ast", $$ );
5643       DUMP_END();
5644     }
5645   ;
5646 
5647 array_qualifier_list_english_stid_opt
5648   : /* empty */                   { $$ = TS_NONE; }
5649   | array_qualifier_list_english_stid
5650   ;
5651 
5652 array_qualifier_list_english_stid
5653   : cv_qualifier_stid
5654   ;
5655 
5656 array_size_int_opt
5657   : /* empty */                   { $$ = C_ARRAY_SIZE_NONE; }
5658   | Y_INT_LIT
5659   | '*'                           { $$ = C_ARRAY_SIZE_VARIABLE; }
5660   ;
5661 
5662 length_opt
5663   : /* empty */
5664   | Y_LENGTH
5665   ;
5666 
5667 /// English block declaration (Apple extension) ///////////////////////////////
5668 
5669 block_decl_english_ast                  // Apple extension
5670   : // in_attr: qualifier
5671     Y_APPLE_BLOCK paren_decl_list_english_opt returning_english_ast_opt
5672     {
5673       DUMP_START( "block_decl_english_ast",
5674                   "BLOCK paren_decl_list_english_opt "
5675                   "returning_english_ast_opt" );
5676       DUMP_AST_LIST( "paren_decl_list_english_opt", $2 );
5677       DUMP_AST( "returning_english_ast_opt", $3 );
5678 
5679       $$ = c_ast_new_gc( K_APPLE_BLOCK, &@$ );
5680       $$->as.block.param_ast_list = $2;
5681       c_ast_set_parent( $3, $$ );
5682 
5683       DUMP_AST( "block_decl_english_ast", $$ );
5684       DUMP_END();
5685     }
5686   ;
5687 
5688 /// English C++ constructor declaration ///////////////////////////////////////
5689 
5690 constructor_decl_english_ast
5691   : Y_CONSTRUCTOR paren_decl_list_english_opt
5692     {
5693       DUMP_START( "constructor_decl_english_ast",
5694                   "CONSTRUCTOR paren_decl_list_english_opt" );
5695       DUMP_AST_LIST( "paren_decl_list_english_opt", $2 );
5696 
5697       $$ = c_ast_new_gc( K_CONSTRUCTOR, &@$ );
5698       $$->as.constructor.param_ast_list = $2;
5699 
5700       DUMP_AST( "constructor_decl_english_ast", $$ );
5701       DUMP_END();
5702     }
5703   ;
5704 
5705 /// English C++ destructor declaration ////////////////////////////////////////
5706 
5707 destructor_decl_english_ast
5708   : Y_DESTRUCTOR parens_opt
5709     {
5710       DUMP_START( "destructor_decl_english_ast", "DESTRUCTOR" );
5711 
5712       $$ = c_ast_new_gc( K_DESTRUCTOR, &@$ );
5713 
5714       DUMP_AST( "destructor_decl_english_ast", $$ );
5715       DUMP_END();
5716     }
5717   ;
5718 
5719 parens_opt
5720   : /* empty */
5721   | '(' rparen_exp
5722   ;
5723 
5724 /// English C/C++ function declaration ////////////////////////////////////////
5725 
5726 func_decl_english_ast
5727   : // in_attr: qualifier
5728     func_qualifier_english_type_opt member_or_non_member_mask_opt
5729     Y_FUNCTION paren_decl_list_english_opt returning_english_ast_opt
5730     {
5731       DUMP_START( "func_decl_english_ast",
5732                   "ref_qualifier_english_stid_opt "
5733                   "member_or_non_member_mask_opt "
5734                   "FUNCTION paren_decl_list_english_opt "
5735                   "returning_english_ast_opt" );
5736       DUMP_TYPE( "func_qualifier_english_type_opt", $1 );
5737       DUMP_INT( "member_or_non_member_mask_opt", $2 );
5738       DUMP_AST_LIST( "paren_decl_list_english_opt", $4 );
5739       DUMP_AST( "returning_english_ast_opt", $5 );
5740 
5741       $$ = c_ast_new_gc( K_FUNCTION, &@$ );
5742       $$->type = $1;
5743       $$->as.func.param_ast_list = $4;
5744       $$->as.func.flags = $2;
5745       c_ast_set_parent( $5, $$ );
5746 
5747       DUMP_AST( "func_decl_english_ast", $$ );
5748       DUMP_END();
5749     }
5750   ;
5751 
5752 func_qualifier_english_type_opt
5753   : ref_qualifier_english_stid_opt
5754     {
5755       $$ = C_TYPE_LIT_S( $1 );
5756     }
5757   | msc_calling_convention_atid
5758     {
5759       $$ = C_TYPE_LIT_A( $1 );
5760     }
5761   ;
5762 
5763 msc_calling_convention_atid
5764   : Y_MSC___CDECL
5765   | Y_MSC___CLRCALL
5766   | Y_MSC___FASTCALL
5767   | Y_MSC___STDCALL
5768   | Y_MSC___THISCALL
5769   | Y_MSC___VECTORCALL
5770   ;
5771 
5772 /// English C++ operator declaration //////////////////////////////////////////
5773 
5774 oper_decl_english_ast
5775   : type_qualifier_list_english_type_opt ref_qualifier_english_stid_opt
5776     member_or_non_member_mask_opt operator_exp paren_decl_list_english_opt
5777     returning_english_ast_opt
5778     {
5779       DUMP_START( "oper_decl_english_ast",
5780                   "type_qualifier_list_english_type_opt "
5781                   "ref_qualifier_english_stid_opt "
5782                   "member_or_non_member_mask_opt "
5783                   "OPERATOR paren_decl_list_english_opt "
5784                   "returning_english_ast_opt" );
5785       DUMP_TYPE( "type_qualifier_list_english_type_opt", $1 );
5786       DUMP_TID( "ref_qualifier_english_stid_opt", $2 );
5787       DUMP_INT( "member_or_non_member_mask_opt", $3 );
5788       DUMP_AST_LIST( "paren_decl_list_english_opt", $5 );
5789       DUMP_AST( "returning_english_ast_opt", $6 );
5790 
5791       $$ = c_ast_new_gc( K_OPERATOR, &@$ );
5792       C_TYPE_ADD( &$$->type, &$1, @1 );
5793       C_TYPE_ADD_TID( &$$->type, $2, @2 );
5794       $$->as.oper.param_ast_list = $5;
5795       $$->as.oper.flags = $3;
5796       c_ast_set_parent( $6, $$ );
5797 
5798       DUMP_AST( "oper_decl_english_ast", $$ );
5799       DUMP_END();
5800     }
5801   ;
5802 
5803 /// English C/C++ parenthesized declaration ///////////////////////////////////
5804 
5805 paren_decl_list_english_opt
5806   : /* empty */                   { slist_init( &$$ ); }
5807   | paren_decl_list_english
5808   ;
5809 
5810 paren_decl_list_english
5811   : '(' decl_list_english_opt ')'
5812     {
5813       DUMP_START( "paren_decl_list_english",
5814                   "'(' decl_list_english_opt ')'" );
5815       DUMP_AST_LIST( "decl_list_english_opt", $2 );
5816 
5817       $$ = $2;
5818 
5819       DUMP_AST_LIST( "paren_decl_list_english", $$ );
5820       DUMP_END();
5821     }
5822   ;
5823 
5824 decl_list_english_opt
5825   : /* empty */                   { slist_init( &$$ ); }
5826   | decl_list_english
5827   ;
5828 
5829 decl_list_english
5830   : decl_list_english comma_exp decl_english_ast
5831     {
5832       DUMP_START( "decl_list_english",
5833                   "decl_list_english ',' decl_english_ast" );
5834       DUMP_AST_LIST( "decl_list_english", $1 );
5835       DUMP_AST( "decl_english_ast", $3 );
5836 
5837       $$ = $1;
5838       slist_push_tail( &$$, $3 );
5839 
5840       DUMP_AST_LIST( "decl_list_english", $$ );
5841       DUMP_END();
5842     }
5843 
5844   | decl_english_ast
5845     {
5846       DUMP_START( "decl_list_english", "decl_english_ast" );
5847       DUMP_AST( "decl_english_ast", $1 );
5848 
5849       if ( $1->kind == K_FUNCTION ) {
5850         //
5851         // From the C11 standard, section 6.3.2.1(4):
5852         //
5853         //    [A] function designator with type "function returning type" is
5854         //    converted to an expression that has type "pointer to function
5855         //    returning type."
5856         //
5857         $1 = c_ast_pointer( $1, &gc_ast_list );
5858       }
5859 
5860       slist_init( &$$ );
5861       slist_push_tail( &$$, $1 );
5862 
5863       DUMP_AST_LIST( "decl_list_english", $$ );
5864       DUMP_END();
5865     }
5866   ;
5867 
5868 /// English C++ reference qualifier declaration ///////////////////////////////
5869 
5870 ref_qualifier_english_stid_opt
5871   : /* empty */                   { $$ = TS_NONE; }
5872   | Y_REFERENCE                   { $$ = TS_REFERENCE; }
5873   | Y_RVALUE reference_exp        { $$ = TS_RVALUE_REFERENCE; }
5874   ;
5875 
5876 /// English C/C++ function(like) returning declaration ////////////////////////
5877 
5878 returning_english_ast_opt
5879   : /* empty */
5880     {
5881       DUMP_START( "returning_english_ast_opt", "<empty>" );
5882 
5883       $$ = c_ast_new_gc( K_BUILTIN, &@$ );
5884       // see the comment in "type_c_ast"
5885       $$->type.btids = opt_lang < LANG_C_99 ? TB_INT : TB_VOID;
5886 
5887       DUMP_AST( "returning_english_ast_opt", $$ );
5888       DUMP_END();
5889     }
5890 
5891   | returning_english_ast
5892   ;
5893 
5894 returning_english_ast
5895   : Y_RETURNING decl_english_ast
5896     {
5897       DUMP_START( "returning_english_ast", "RETURNING decl_english_ast" );
5898       DUMP_AST( "decl_english_ast", $2 );
5899 
5900       $$ = $2;
5901 
5902       DUMP_AST( "returning_english_ast", $$ );
5903       DUMP_END();
5904     }
5905 
5906   | Y_RETURNING error
5907     {
5908       elaborate_error( "English expected after \"%s\"", L_RETURNING );
5909     }
5910   ;
5911 
5912 /// English C/C++ qualified declaration ///////////////////////////////////////
5913 
5914 qualified_decl_english_ast
5915   : type_qualifier_list_english_type_opt qualifiable_decl_english_ast
5916     {
5917       DUMP_START( "qualified_decl_english_ast",
5918                   "type_qualifier_list_english_type_opt "
5919                   "qualifiable_decl_english_ast" );
5920       DUMP_TYPE( "type_qualifier_list_english_type_opt", $1 );
5921       DUMP_AST( "qualifiable_decl_english_ast", $2 );
5922 
5923       $$ = $2;
5924       if ( !c_type_is_none( &$1 ) )
5925         $$->loc = @$;
5926       C_TYPE_ADD( &$$->type, &$1, @1 );
5927 
5928       DUMP_AST( "qualified_decl_english_ast", $$ );
5929       DUMP_END();
5930     }
5931   ;
5932 
5933 type_qualifier_list_english_type_opt
5934   : /* empty */                   { $$ = T_NONE; }
5935   | type_qualifier_list_english_type
5936   ;
5937 
5938 type_qualifier_list_english_type
5939   : type_qualifier_list_english_type type_qualifier_english_type
5940     {
5941       DUMP_START( "type_qualifier_list_english_type",
5942                   "type_qualifier_list_english_type "
5943                   "type_qualifier_english_type" );
5944       DUMP_TYPE( "type_qualifier_list_english_type", $1 );
5945       DUMP_TYPE( "type_qualifier_english_type", $2 );
5946 
5947       $$ = $1;
5948       C_TYPE_ADD( &$$, &$2, @2 );
5949 
5950       DUMP_TYPE( "type_qualifier_list_english_type", $$ );
5951       DUMP_END();
5952     }
5953 
5954   | type_qualifier_english_type
5955   ;
5956 
5957 type_qualifier_english_type
5958   : attribute_english_atid        { $$ = C_TYPE_LIT_A( $1 ); }
5959   | type_qualifier_english_stid   { $$ = C_TYPE_LIT_S( $1 ); }
5960   ;
5961 
5962 type_qualifier_english_stid
5963   : Y__ATOMIC_QUAL
5964   | cv_qualifier_stid
5965   | restrict_qualifier_c_stid
5966   | Y_UPC_RELAXED
5967   | Y_UPC_SHARED                  %prec Y_PREC_LESS_THAN_upc_layout_qualifier
5968   | Y_UPC_SHARED upc_layout_qualifier_english
5969   | Y_UPC_STRICT
5970   ;
5971 
5972 upc_layout_qualifier_english
5973   : Y_INT_LIT
5974   | '*'
5975   ;
5976 
5977 qualifiable_decl_english_ast
5978   : block_decl_english_ast
5979   | func_decl_english_ast
5980   | pointer_decl_english_ast
5981   | reference_decl_english_ast
5982   | type_english_ast
5983   ;
5984 
5985 /// English C/C++ pointer declaration /////////////////////////////////////////
5986 
5987 pointer_decl_english_ast
5988     /*
5989      * Ordinary pointer declaration.
5990      */
5991   : // in_attr: qualifier
5992     Y_POINTER to_exp decl_english_ast
5993     {
5994       DUMP_START( "pointer_decl_english_ast", "POINTER TO decl_english_ast" );
5995       DUMP_AST( "decl_english_ast", $3 );
5996 
5997       if ( $3->kind == K_NAME ) {       // see the comment in "declare_command"
5998         assert( !c_sname_empty( &$3->sname ) );
5999         print_error_unknown_name( &@3, &$3->sname );
6000         PARSE_ABORT();
6001       }
6002 
6003       $$ = c_ast_new_gc( K_POINTER, &@$ );
6004       c_ast_set_parent( $3, $$ );
6005 
6006       DUMP_AST( "pointer_decl_english_ast", $$ );
6007       DUMP_END();
6008     }
6009 
6010     /*
6011      * C++ pointer-to-member declaration.
6012      */
6013   | // in_attr: qualifier
6014     Y_POINTER to_exp Y_MEMBER of_exp class_struct_union_btid_exp
6015     sname_english_exp decl_english_ast
6016     {
6017       DUMP_START( "pointer_to_member_decl_english",
6018                   "POINTER TO MEMBER OF "
6019                   "class_struct_union_btid_exp "
6020                   "sname_english decl_english_ast" );
6021       DUMP_TID( "class_struct_union_btid_exp", $5 );
6022       DUMP_SNAME( "sname_english_exp", $6 );
6023       DUMP_AST( "decl_english_ast", $7 );
6024 
6025       $$ = c_ast_new_gc( K_POINTER_TO_MEMBER, &@$ );
6026       $$->as.ptr_mbr.class_sname = $6;
6027       c_ast_set_parent( $7, $$ );
6028       C_TYPE_ADD_TID( &$$->type, $5, @5 );
6029 
6030       DUMP_AST( "pointer_to_member_decl_english", $$ );
6031       DUMP_END();
6032     }
6033 
6034   | Y_POINTER to_exp error
6035     {
6036       if ( OPT_LANG_IS(CPP_ANY) )
6037         elaborate_error( "type name or \"%s\" expected", L_MEMBER );
6038       else
6039         elaborate_error( "type name expected" );
6040     }
6041   ;
6042 
6043 /// English C++ reference declaration /////////////////////////////////////////
6044 
6045 reference_decl_english_ast
6046   : // in_attr: qualifier
6047     reference_english_ast to_exp decl_english_ast
6048     {
6049       DUMP_START( "reference_decl_english_ast",
6050                   "reference_english_ast TO decl_english_ast" );
6051       DUMP_AST( "reference_english_ast", $1 );
6052       DUMP_AST( "decl_english_ast", $3 );
6053 
6054       $$ = $1;
6055       $$->loc = @$;
6056       c_ast_set_parent( $3, $$ );
6057 
6058       DUMP_AST( "reference_decl_english_ast", $$ );
6059       DUMP_END();
6060     }
6061   ;
6062 
6063 reference_english_ast
6064   : Y_REFERENCE
6065     {
6066       $$ = c_ast_new_gc( K_REFERENCE, &@$ );
6067     }
6068 
6069   | Y_RVALUE reference_exp
6070     {
6071       $$ = c_ast_new_gc( K_RVALUE_REFERENCE, &@$ );
6072     }
6073   ;
6074 
6075 /// English C++ user-defined literal declaration //////////////////////////////
6076 
6077 user_defined_literal_decl_english_ast
6078   : Y_USER_DEFINED literal_exp paren_decl_list_english_opt
6079     returning_english_ast_opt
6080     { //
6081       // User-defined literals are supported only in C++11 and later.
6082       // (However, we always allow them in configuration files.)
6083       //
6084       // This check is better to do now in the parser rather than later in the
6085       // AST because it has to be done in fewer places in the code plus gives a
6086       // better error location.
6087       //
6088       if ( unsupported( LANG_CPP_MIN(11) ) ) {
6089         print_error( &@1,
6090           "%s %s not supported%s\n",
6091           H_USER_DEFINED, L_LITERAL, c_lang_which( LANG_CPP_MIN(11) )
6092         );
6093         PARSE_ABORT();
6094       }
6095 
6096       DUMP_START( "user_defined_literal_decl_english_ast",
6097                   "USER-DEFINED LITERAL paren_decl_list_english_opt "
6098                   "returning_english_ast_opt" );
6099       DUMP_AST_LIST( "paren_decl_list_english_opt", $3 );
6100       DUMP_AST( "returning_english_ast_opt", $4 );
6101 
6102       $$ = c_ast_new_gc( K_USER_DEF_LITERAL, &@$ );
6103       $$->as.udef_lit.param_ast_list = $3;
6104       c_ast_set_parent( $4, $$ );
6105 
6106       DUMP_AST( "user_defined_literal_decl_english_ast", $$ );
6107       DUMP_END();
6108     }
6109   ;
6110 
6111 /// English C/C++ variable declaration ////////////////////////////////////////
6112 
6113 var_decl_english_ast
6114     /*
6115      * Ordinary variable declaration.
6116      */
6117   : sname_c Y_AS decl_english_ast
6118     {
6119       DUMP_START( "var_decl_english_ast", "NAME AS decl_english_ast" );
6120       DUMP_SNAME( "sname", $1 );
6121       DUMP_AST( "decl_english_ast", $3 );
6122 
6123       if ( $3->kind == K_NAME ) {       // see the comment in "declare_command"
6124         assert( !c_sname_empty( &$3->sname ) );
6125         print_error_unknown_name( &@3, &$3->sname );
6126         c_sname_cleanup( &$1 );
6127         PARSE_ABORT();
6128       }
6129 
6130       $$ = $3;
6131       $$->loc = @$;
6132       c_sname_set( &$$->sname, &$1 );
6133 
6134       DUMP_AST( "var_decl_english_ast", $$ );
6135       DUMP_END();
6136     }
6137 
6138     /*
6139      * K&R C type-less parameter declaration.
6140      */
6141   | sname_english_ast
6142 
6143     /*
6144      * Varargs declaration.
6145      */
6146   | "..."
6147     {
6148       DUMP_START( "var_decl_english_ast", "..." );
6149 
6150       $$ = c_ast_new_gc( K_VARIADIC, &@$ );
6151 
6152       DUMP_AST( "var_decl_english_ast", $$ );
6153       DUMP_END();
6154     }
6155   ;
6156 
6157 ///////////////////////////////////////////////////////////////////////////////
6158 //  ENGLISH TYPES                                                            //
6159 ///////////////////////////////////////////////////////////////////////////////
6160 
6161 type_english_ast
6162   : // in_attr: qualifier
6163     type_modifier_list_english_type_opt unmodified_type_english_ast
6164     {
6165       DUMP_START( "type_english_ast",
6166                   "type_modifier_list_english_type_opt "
6167                   "unmodified_type_english_ast" );
6168       DUMP_TYPE( "type_modifier_list_english_type_opt", $1 );
6169       DUMP_AST( "unmodified_type_english_ast", $2 );
6170 
6171       $$ = $2;
6172       if ( !c_type_is_none( &$1 ) ) {
6173         // Set the AST's location to the entire rule only if the leading
6174         // optional rule is actually present, otherwise @$ refers to a column
6175         // before $2.
6176         $$->loc = @$;
6177         C_TYPE_ADD( &$$->type, &$1, @1 );
6178       }
6179 
6180       DUMP_AST( "type_english_ast", $$ );
6181       DUMP_END();
6182     }
6183 
6184   | // in_attr: qualifier
6185     type_modifier_list_english_type     // allows implicit int in K&R C
6186     {
6187       DUMP_START( "type_english_ast", "type_modifier_list_english_type" );
6188       DUMP_TYPE( "type_modifier_list_english_type", $1 );
6189 
6190       // see the comment in "type_c_ast"
6191       c_type_t type = C_TYPE_LIT_B( opt_lang < LANG_C_99 ? TB_INT : TB_NONE );
6192 
6193       C_TYPE_ADD( &type, &$1, @1 );
6194 
6195       $$ = c_ast_new_gc( K_BUILTIN, &@$ );
6196       $$->type = type;
6197 
6198       DUMP_AST( "type_english_ast", $$ );
6199       DUMP_END();
6200     }
6201   ;
6202 
6203 type_modifier_list_english_type_opt
6204   : /* empty */                   { $$ = T_NONE; }
6205   | type_modifier_list_english_type
6206   ;
6207 
6208 type_modifier_list_english_type
6209   : type_modifier_list_english_type type_modifier_english_type
6210     {
6211       DUMP_START( "type_modifier_list_english_type",
6212                   "type_modifier_list_english_type "
6213                   "type_modifier_english_type" );
6214       DUMP_TYPE( "type_modifier_list_english_type", $1 );
6215       DUMP_TYPE( "type_modifier_english_type", $2 );
6216 
6217       $$ = $1;
6218       C_TYPE_ADD( &$$, &$2, @2 );
6219 
6220       DUMP_TYPE( "type_modifier_list_english_type", $$ );
6221       DUMP_END();
6222     }
6223 
6224   | type_modifier_english_type
6225   ;
6226 
6227 type_modifier_english_type
6228   : type_modifier_base_type
6229   ;
6230 
6231 unmodified_type_english_ast
6232   : builtin_type_ast
6233   | enum_class_struct_union_english_ast
6234   | typedef_type_c_ast
6235   ;
6236 
6237 enum_class_struct_union_english_ast
6238   : enum_class_struct_union_c_btid any_sname_c_exp
6239     of_type_enum_fixed_type_english_ast_opt
6240     {
6241       DUMP_START( "enum_class_struct_union_english_ast",
6242                   "enum_class_struct_union_c_btid sname" );
6243       DUMP_TID( "enum_class_struct_union_c_btid", $1 );
6244       DUMP_SNAME( "sname", $2 );
6245       DUMP_AST( "enum_fixed_type_english_ast", $3 );
6246 
6247       $$ = c_ast_new_gc( K_ENUM_CLASS_STRUCT_UNION, &@$ );
6248       $$->type.btids = c_tid_check( $1, C_TPID_BASE );
6249       $$->as.ecsu.of_ast = $3;
6250       $$->as.ecsu.ecsu_sname = $2;
6251 
6252       DUMP_AST( "enum_class_struct_union_english_ast", $$ );
6253       DUMP_END();
6254     }
6255   ;
6256 
6257 of_type_enum_fixed_type_english_ast_opt
6258   : /* empty */                         { $$ = NULL; }
6259   | Y_OF type_opt enum_fixed_type_english_ast
6260     {
6261       $$ = $3;
6262     }
6263   ;
6264 
6265 enum_fixed_type_english_ast
6266   : enum_fixed_type_modifier_list_english_btid_opt
6267     enum_unmodified_fixed_type_english_ast
6268     {
6269       DUMP_START( "enum_fixed_type_english_ast",
6270                   "enum_fixed_type_modifier_list_stid" );
6271       DUMP_TID( "enum_fixed_type_modifier_list_stid", $1 );
6272       DUMP_AST( "enum_unmodified_fixed_type_english_ast", $2 );
6273 
6274       $$ = $2;
6275       if ( $1 != TB_NONE ) {            // See comment in type_english_ast.
6276         $$->loc = @$;
6277         C_TYPE_ADD_TID( &$$->type, $1, @1 );
6278       }
6279 
6280       DUMP_AST( "enum_fixed_type_english_ast", $$ );
6281       DUMP_END();
6282     }
6283 
6284   | enum_fixed_type_modifier_list_english_btid
6285     {
6286       DUMP_START( "enum_fixed_type_english_ast",
6287                   "enum_fixed_type_modifier_list_english_btid" );
6288       DUMP_TID( "enum_fixed_type_modifier_list_english_btid", $1 );
6289 
6290       $$ = c_ast_new_gc( K_BUILTIN, &@$ );
6291       $$->type.btids = c_tid_check( $1, C_TPID_BASE );
6292 
6293       DUMP_AST( "enum_fixed_type_english_ast", $$ );
6294       DUMP_END();
6295     }
6296   ;
6297 
6298 enum_fixed_type_modifier_list_english_btid_opt
6299   : /* empty */                   { $$ = TB_NONE; }
6300   | enum_fixed_type_modifier_list_english_btid
6301   ;
6302 
6303 enum_fixed_type_modifier_list_english_btid
6304   : enum_fixed_type_modifier_list_english_btid enum_fixed_type_modifier_btid
6305     {
6306       DUMP_START( "enum_fixed_type_modifier_list_english_btid",
6307                   "enum_fixed_type_modifier_list_english_btid "
6308                   "enum_fixed_type_modifier_btid" );
6309       DUMP_TID( "enum_fixed_type_modifier_list_english_btid", $1 );
6310       DUMP_TID( "enum_fixed_type_modifier_btid", $2 );
6311 
6312       $$ = $1;
6313       C_TID_ADD( &$$, $2, @2 );
6314 
6315       DUMP_TID( "enum_fixed_type_modifier_list_english_btid", $$ );
6316       DUMP_END();
6317     }
6318 
6319   | enum_fixed_type_modifier_btid
6320   ;
6321 
6322 enum_unmodified_fixed_type_english_ast
6323   : builtin_type_ast
6324   | sname_english_ast
6325   ;
6326 
6327 ///////////////////////////////////////////////////////////////////////////////
6328 //  NAMES                                                                    //
6329 ///////////////////////////////////////////////////////////////////////////////
6330 
6331 any_name
6332   : Y_NAME
6333   | Y_TYPEDEF_NAME
6334     {
6335       assert( c_sname_count( &$1->ast->sname ) == 1 );
6336       $$ = check_strdup( c_sname_local_name( &$1->ast->sname ) );
6337     }
6338   ;
6339 
6340 any_name_exp
6341   : any_name
6342   | error
6343     {
6344       $$ = NULL;
6345       elaborate_error( "name expected" );
6346     }
6347   ;
6348 
6349 any_sname_c
6350   : sname_c
6351   | typedef_sname_c
6352   ;
6353 
6354 any_sname_c_exp
6355   : any_sname_c
6356   | error
6357     {
6358       c_sname_init( &$$ );
6359       elaborate_error( "name expected" );
6360     }
6361   ;
6362 
6363 any_sname_c_opt
6364   : /* empty */                   { c_sname_init( &$$ ); }
6365   | any_sname_c
6366   ;
6367 
6368 any_typedef
6369   : Y_TYPEDEF_NAME
6370   | Y_TYPEDEF_SNAME
6371   ;
6372 
6373 name_ast
6374   : Y_NAME
6375     {
6376       DUMP_START( "name_ast", "NAME" );
6377       DUMP_STR( "NAME", $1 );
6378 
6379       $$ = c_ast_new_gc( K_NAME, &@$ );
6380       c_sname_append_name( &$$->sname, $1 );
6381 
6382       DUMP_AST( "name_ast", $$ );
6383       DUMP_END();
6384     }
6385   ;
6386 
6387 name_exp
6388   : Y_NAME
6389   | error
6390     {
6391       $$ = NULL;
6392       elaborate_error( "name expected" );
6393     }
6394   ;
6395 
6396 typedef_type_c_ast
6397   : any_typedef sub_scope_sname_c_opt
6398     {
6399       c_ast_t *const type_ast = ia_type_ast_peek();
6400       c_ast_t const *type_for_ast = $1->ast;
6401 
6402       DUMP_START( "typedef_type_c_ast", "any_typedef" );
6403       DUMP_AST( "(type_c_ast)", type_ast );
6404       DUMP_AST( "any_typedef.ast", type_for_ast );
6405       DUMP_SNAME( "sub_scope_sname_c_opt", $2 );
6406 
6407       if ( c_sname_empty( &$2 ) ) {
6408 ttntd:  $$ = c_ast_new_gc( K_TYPEDEF, &@$ );
6409         $$->type.btids = TB_TYPEDEF;
6410         $$->as.tdef.for_ast = type_for_ast;
6411       }
6412       else {
6413         c_sname_t temp_name = c_sname_dup( &$1->ast->sname );
6414         c_sname_append_sname( &temp_name, &$2 );
6415 
6416         if ( type_ast == NULL ) {
6417           //
6418           // This is for a case like:
6419           //
6420           //      define S as struct S
6421           //      explain S::T x
6422           //
6423           // that is: a typedef'd type followed by ::T where T is an unknown
6424           // name used as a type. Just assume the T is a type and create a name
6425           // for it.
6426           //
6427           c_ast_t *const name_ast = c_ast_new_gc( K_NAME, &@2 );
6428           c_sname_set( &name_ast->sname, &temp_name );
6429           type_for_ast = name_ast;
6430           goto ttntd;
6431         }
6432 
6433         //
6434         // Otherwise, this is for cases like:
6435         //
6436         //  1. A typedef'd type used for a scope:
6437         //
6438         //          define S as struct S
6439         //          explain int S::x
6440         //
6441         //  2. A typedef'd type used for an intermediate scope:
6442         //
6443         //          define S as struct S
6444         //          define T as struct T
6445         //          explain int S::T::x
6446         //
6447         $$ = type_ast;
6448         c_sname_set( &$$->sname, &temp_name );
6449       }
6450 
6451       DUMP_AST( "typedef_type_c_ast", $$ );
6452       DUMP_END();
6453     }
6454   ;
6455 
6456 sub_scope_sname_c_opt
6457   : /* empty */                   { c_sname_init( &$$ ); }
6458   | Y_COLON2 any_sname_c          { $$ = $2; }
6459   ;
6460 
6461 scope_sname_c_opt
6462   : /* empty */                   { c_sname_init( &$$ ); }
6463 
6464   | sname_c Y_COLON2
6465     {
6466       $$ = $1;
6467       c_sname_set_local_type( &$$, &C_TYPE_LIT_B( TB_SCOPE ) );
6468     }
6469 
6470   | any_typedef Y_COLON2
6471     { //
6472       // This is for a case like:
6473       //
6474       //      define S as struct S
6475       //      explain bool S::operator!() const
6476       //
6477       // that is: a typedef'd type used for a scope.
6478       //
6479       $$ = c_sname_dup( &$1->ast->sname );
6480     }
6481   ;
6482 
6483 sname_c
6484   : sname_c Y_COLON2 Y_NAME
6485     {
6486       // see the comment in "of_scope_english"
6487       if ( unsupported( LANG_CPP_ANY ) ) {
6488         print_error( &@2, "scoped names not supported in C\n" );
6489         c_sname_cleanup( &$1 );
6490         free( $3 );
6491         PARSE_ABORT();
6492       }
6493 
6494       DUMP_START( "sname_c", "sname_c '::' NAME" );
6495       DUMP_SNAME( "sname_c", $1 );
6496       DUMP_STR( "name", $3 );
6497 
6498       $$ = $1;
6499       c_sname_set_local_type( &$$, &C_TYPE_LIT_B( TB_SCOPE ) );
6500       c_sname_append_name( &$$, $3 );
6501 
6502       DUMP_SNAME( "sname_c", $$ );
6503       DUMP_END();
6504     }
6505 
6506   | sname_c Y_COLON2 any_typedef
6507     { //
6508       // This is for a case like:
6509       //
6510       //      define S::int8_t as char
6511       //
6512       // that is: the type int8_t is an existing type in no scope being defined
6513       // as a distinct type in a new scope.
6514       //
6515       DUMP_START( "sname_c", "sname_c '::' any_typedef" );
6516       DUMP_SNAME( "sname_c", $1 );
6517       DUMP_AST( "any_typedef.ast", $3->ast );
6518 
6519       $$ = $1;
6520       c_sname_set_local_type( &$$, &C_TYPE_LIT_B( TB_SCOPE ) );
6521       c_sname_t temp_sname = c_sname_dup( &$3->ast->sname );
6522       c_sname_append_sname( &$$, &temp_sname );
6523 
6524       DUMP_SNAME( "sname_c", $$ );
6525       DUMP_END();
6526     }
6527 
6528   | Y_NAME
6529     {
6530       DUMP_START( "sname_c", "NAME" );
6531       DUMP_STR( "NAME", $1 );
6532 
6533       c_sname_init_name( &$$, $1 );
6534 
6535       DUMP_SNAME( "sname_c", $$ );
6536       DUMP_END();
6537     }
6538   ;
6539 
6540 sname_c_ast
6541   : // in_attr: type_c_ast
6542     sname_c bit_field_c_int_opt
6543     {
6544       c_ast_t *const type_ast = ia_type_ast_peek();
6545 
6546       DUMP_START( "sname_c_ast", "sname_c" );
6547       DUMP_AST( "(type_c_ast)", type_ast );
6548       DUMP_SNAME( "sname", $1 );
6549       DUMP_INT( "bit_field_c_int_opt", $2 );
6550 
6551       $$ = type_ast;
6552       c_sname_set( &$$->sname, &$1 );
6553 
6554       bool ok = true;
6555       //
6556       // This check has to be done now in the parser rather than later in the
6557       // AST since we need to use the builtin union member now.
6558       //
6559       if ( $2 != 0 && (ok = c_ast_is_builtin_any( $$, TB_ANY_INTEGRAL )) )
6560         $$->as.builtin.bit_width = (c_bit_width_t)$2;
6561 
6562       DUMP_AST( "sname_c_ast", $$ );
6563       DUMP_END();
6564 
6565       if ( !ok ) {
6566         print_error( &@2, "bit-fields can be only of integral types\n" );
6567         PARSE_ABORT();
6568       }
6569     }
6570   ;
6571 
6572 bit_field_c_int_opt
6573   : /* empty */                   { $$ = 0; }
6574   | ':' int_exp
6575     { //
6576       // This check has to be done now in the parser rather than later in the
6577       // AST since we use 0 to mean "no bit-field."
6578       //
6579       if ( $2 == 0 ) {
6580         print_error( &@2, "bit-field width must be > 0\n" );
6581         PARSE_ABORT();
6582       }
6583       $$ = $2;
6584     }
6585   ;
6586 
6587 sname_c_exp
6588   : sname_c
6589   | error
6590     {
6591       c_sname_init( &$$ );
6592       elaborate_error( "name expected" );
6593     }
6594   ;
6595 
6596 sname_c_opt
6597   : /* empty */                   { c_sname_init( &$$ ); }
6598   | sname_c
6599   ;
6600 
6601 sname_english
6602   : any_sname_c of_scope_list_english_opt
6603     {
6604       DUMP_START( "sname_english", "any_sname_c of_scope_list_english_opt" );
6605       DUMP_SNAME( "any_sname_c", $1 );
6606       DUMP_SNAME( "of_scope_list_english_opt", $2 );
6607 
6608       c_type_t const *local_type = c_sname_local_type( &$2 );
6609       if ( c_type_is_none( local_type ) )
6610         local_type = c_sname_local_type( &$1 );
6611       $$ = $2;
6612       c_sname_append_sname( &$$, &$1 );
6613       c_sname_set_local_type( &$$, local_type );
6614 
6615       DUMP_SNAME( "sname_english", $$ );
6616       DUMP_END();
6617     }
6618   ;
6619 
6620 sname_english_ast
6621   : Y_NAME of_scope_list_english_opt
6622     {
6623       DUMP_START( "sname_english_ast", "NAME of_scope_list_english_opt" );
6624       DUMP_STR( "NAME", $1 );
6625       DUMP_SNAME( "of_scope_list_english_opt", $2 );
6626 
6627       c_sname_t sname = $2;
6628       c_sname_append_name( &sname, $1 );
6629 
6630       //
6631       // See if the full name is the name of a typedef'd type.
6632       //
6633       c_typedef_t const *const tdef = c_typedef_find_sname( &sname );
6634       if ( tdef != NULL ) {
6635         $$ = c_ast_new_gc( K_TYPEDEF, &@$ );
6636         $$->type.btids = TB_TYPEDEF;
6637         $$->as.tdef.for_ast = tdef->ast;
6638         c_sname_cleanup( &sname );
6639       } else {
6640         $$ = c_ast_new_gc( K_NAME, &@$ );
6641         c_sname_set( &$$->sname, &sname );
6642       }
6643 
6644       DUMP_AST( "sname_english_ast", $$ );
6645       DUMP_END();
6646     }
6647   ;
6648 
6649 sname_english_exp
6650   : sname_english
6651   | error
6652     {
6653       c_sname_init( &$$ );
6654       elaborate_error( "name expected" );
6655     }
6656   ;
6657 
6658 sname_list_english
6659   : sname_list_english ',' sname_english
6660     {
6661       DUMP_START( "sname_list_english", "sname_english" );
6662       DUMP_SNAME_LIST( "sname_list_english", $1 );
6663       DUMP_SNAME( "sname_english", $3 );
6664 
6665       $$ = $1;
6666       c_sname_t *const temp_sname = MALLOC( c_sname_t, 1 );
6667       *temp_sname = $3;
6668       slist_push_tail( &$$, temp_sname );
6669 
6670       DUMP_SNAME_LIST( "sname_list_english", $$ );
6671       DUMP_END();
6672     }
6673 
6674   | sname_english
6675     {
6676       DUMP_START( "sname_list_english", "sname_english" );
6677       DUMP_SNAME( "sname_english", $1 );
6678 
6679       slist_init( &$$ );
6680       c_sname_t *const temp_sname = MALLOC( c_sname_t, 1 );
6681       *temp_sname = $1;
6682       slist_push_tail( &$$, temp_sname );
6683 
6684       DUMP_SNAME_LIST( "sname_list_english", $$ );
6685       DUMP_END();
6686     }
6687   ;
6688 
6689 typedef_sname_c
6690   : typedef_sname_c Y_COLON2 sname_c
6691     {
6692       DUMP_START( "typedef_sname_c", "typedef_sname_c '::' sname_c" );
6693       DUMP_SNAME( "typedef_sname_c", $1 );
6694       DUMP_SNAME( "sname_c", $3 );
6695 
6696       //
6697       // This is for a case like:
6698       //
6699       //      define S as struct S
6700       //      define S::T as struct T
6701       //
6702       $$ = $1;
6703       c_sname_append_sname( &$$, &$3 );
6704 
6705       DUMP_SNAME( "typedef_sname_c", $$ );
6706       DUMP_END();
6707     }
6708 
6709   | typedef_sname_c Y_COLON2 any_typedef
6710     {
6711       DUMP_START( "typedef_sname_c", "typedef_sname_c '::' any_typedef" );
6712       DUMP_SNAME( "typedef_sname_c", $1 );
6713       DUMP_AST( "any_typedef", $3->ast );
6714 
6715       //
6716       // This is for a case like:
6717       //
6718       //      define S as struct S
6719       //      define T as struct T
6720       //      define S::T as struct S_T
6721       //
6722       $$ = $1;
6723       c_sname_set_local_type( &$$, c_sname_local_type( &$3->ast->sname ) );
6724       c_sname_t temp_sname = c_sname_dup( &$3->ast->sname );
6725       c_sname_append_sname( &$$, &temp_sname );
6726 
6727       DUMP_SNAME( "typedef_sname_c", $$ );
6728       DUMP_END();
6729     }
6730 
6731   | any_typedef                   { $$ = c_sname_dup( &$1->ast->sname ); }
6732   ;
6733 
6734 ///////////////////////////////////////////////////////////////////////////////
6735 //  MISCELLANEOUS                                                            //
6736 ///////////////////////////////////////////////////////////////////////////////
6737 
6738 address_exp
6739   : Y_ADDRESS
6740   | error
6741     {
6742       keyword_expected( L_ADDRESS );
6743     }
6744   ;
6745 
6746 array_exp
6747   : Y_ARRAY
6748   | error
6749     {
6750       keyword_expected( L_ARRAY );
6751     }
6752   ;
6753 
6754 as_exp
6755   : Y_AS
6756     {
6757       if ( OPT_LANG_IS(CPP_ANY) ) {
6758         //
6759         // For either "declare" or "define", neither "override" nor "final"
6760         // must be matched initially to allow for cases like:
6761         //
6762         //      c++decl> declare final as int
6763         //      int final;
6764         //
6765         // (which is legal).  However, in C++, after parsing "as", the keyword
6766         // context has to be set to C_KW_CTX_MBR_FUNC to be able to match
6767         // "override" and "final", e.g.:
6768         //
6769         //      c++decl> declare f as final function
6770         //      void f() final;
6771         //
6772         lexer_keyword_ctx = C_KW_CTX_MBR_FUNC;
6773       }
6774     }
6775   | error
6776     {
6777       keyword_expected( L_AS );
6778     }
6779   ;
6780 
6781 as_into_to_exp
6782   : Y_AS
6783   | Y_INTO
6784   | Y_TO
6785   | error
6786     {
6787       elaborate_error(
6788         "\"%s\", \"%s\", or \"%s\" expected",
6789         L_AS, L_INTO, L_TO
6790       );
6791     }
6792   ;
6793 
6794 cast_exp
6795   : Y_CAST
6796   | error
6797     {
6798       keyword_expected( L_CAST );
6799     }
6800   ;
6801 
6802 class_struct_union_btid_exp
6803   : class_struct_union_btid
6804   | error
6805     {
6806       elaborate_error(
6807         "\"%s\", \"%s\" or \"%s\" expected",
6808         L_CLASS, L_STRUCT, L_UNION
6809       );
6810     }
6811   ;
6812 
6813 colon_exp
6814   : ':'
6815   | error
6816     {
6817       punct_expected( ':' );
6818     }
6819   ;
6820 
6821 comma_exp
6822   : ','
6823   | error
6824     {
6825       punct_expected( ',' );
6826     }
6827   ;
6828 
6829 conversion_exp
6830   : Y_CONVERSION
6831   | error
6832     {
6833       keyword_expected( L_CONVERSION );
6834     }
6835   ;
6836 
6837 c_operator
6838   : Y_NEW                           { $$ = C_OP_NEW             ; }
6839   | Y_NEW '[' rbracket_exp          { $$ = C_OP_NEW_ARRAY       ; }
6840   | Y_DELETE                        { $$ = C_OP_DELETE          ; }
6841   | Y_DELETE '[' rbracket_exp       { $$ = C_OP_DELETE_ARRAY    ; }
6842   | Y_EXCLAM                        { $$ = C_OP_EXCLAM          ; }
6843   | Y_EXCLAM_EQ                     { $$ = C_OP_EXCLAM_EQ       ; }
6844   | '%'                             { $$ = C_OP_PERCENT         ; }
6845   | Y_PERCENT_EQ                    { $$ = C_OP_PERCENT_EQ      ; }
6846   | Y_AMPER                         { $$ = C_OP_AMPER           ; }
6847   | Y_AMPER2                        { $$ = C_OP_AMPER2          ; }
6848   | Y_AMPER_EQ                      { $$ = C_OP_AMPER_EQ        ; }
6849   | '(' rparen_exp                  { $$ = C_OP_PARENS          ; }
6850   | '*'                             { $$ = C_OP_STAR            ; }
6851   | Y_STAR_EQ                       { $$ = C_OP_STAR_EQ         ; }
6852   | '+'                             { $$ = C_OP_PLUS            ; }
6853   | Y_PLUS2                         { $$ = C_OP_PLUS2           ; }
6854   | Y_PLUS_EQ                       { $$ = C_OP_PLUS_EQ         ; }
6855   | ','                             { $$ = C_OP_COMMA           ; }
6856   | '-'                             { $$ = C_OP_MINUS           ; }
6857   | Y_MINUS2                        { $$ = C_OP_MINUS2          ; }
6858   | Y_MINUS_EQ                      { $$ = C_OP_MINUS_EQ        ; }
6859   | Y_ARROW                         { $$ = C_OP_ARROW           ; }
6860   | Y_ARROW_STAR                    { $$ = C_OP_ARROW_STAR      ; }
6861   | '.'                             { $$ = C_OP_DOT             ; }
6862   | Y_DOT_STAR                      { $$ = C_OP_DOT_STAR        ; }
6863   | '/'                             { $$ = C_OP_SLASH           ; }
6864   | Y_SLASH_EQ                      { $$ = C_OP_SLASH_EQ        ; }
6865   | Y_COLON2                        { $$ = C_OP_COLON2          ; }
6866   | '<'                             { $$ = C_OP_LESS            ; }
6867   | Y_LESS2                         { $$ = C_OP_LESS2           ; }
6868   | Y_LESS2_EQ                      { $$ = C_OP_LESS2_EQ        ; }
6869   | Y_LESS_EQ                       { $$ = C_OP_LESS_EQ         ; }
6870   | Y_LESS_EQ_GREATER               { $$ = C_OP_LESS_EQ_GREATER ; }
6871   | '='                             { $$ = C_OP_EQ              ; }
6872   | Y_EQ2                           { $$ = C_OP_EQ2             ; }
6873   | '>'                             { $$ = C_OP_GREATER         ; }
6874   | Y_GREATER2                      { $$ = C_OP_GREATER2        ; }
6875   | Y_GREATER2_EQ                   { $$ = C_OP_GREATER2_EQ     ; }
6876   | Y_GREATER_EQ                    { $$ = C_OP_GREATER_EQ      ; }
6877   | Y_QMARK_COLON                   { $$ = C_OP_QMARK_COLON     ; }
6878   | '[' rbracket_exp                { $$ = C_OP_BRACKETS        ; }
6879   | Y_CIRC                          { $$ = C_OP_CIRC            ; }
6880   | Y_CIRC_EQ                       { $$ = C_OP_CIRC_EQ         ; }
6881   | Y_PIPE                          { $$ = C_OP_PIPE            ; }
6882   | Y_PIPE2                         { $$ = C_OP_PIPE2           ; }
6883   | Y_PIPE_EQ                       { $$ = C_OP_PIPE_EQ         ; }
6884   | Y_TILDE                         { $$ = C_OP_TILDE           ; }
6885   ;
6886 
6887 dependency_exp
6888   : Y_DEPENDENCY
6889   | error
6890     {
6891       keyword_expected( L_DEPENDENCY );
6892     }
6893   ;
6894 
6895 equals_exp
6896   : '='
6897   | error
6898     {
6899       punct_expected( '=' );
6900     }
6901   ;
6902 
6903 extern_linkage_c_stid
6904   : Y_EXTERN linkage_stid         { $$ = $2; }
6905   | Y_EXTERN linkage_stid '{'
6906     {
6907       print_error( &@3,
6908         "scoped linkage declarations not supported by %s\n",
6909         CDECL
6910       );
6911       PARSE_ABORT();
6912     }
6913   ;
6914 
6915 extern_linkage_c_stid_opt
6916   : /* empty */                   { $$ = TS_NONE; }
6917   | extern_linkage_c_stid
6918   ;
6919 
6920 glob
6921   : Y_GLOB
6922     {
6923       if ( OPT_LANG_IS(C_ANY) && strchr( $1, ':' ) != NULL ) {
6924         print_error( &@1, "scoped names not supported in C\n" );
6925         free( $1 );
6926         PARSE_ABORT();
6927       }
6928       $$ = $1;
6929     }
6930   ;
6931 
6932 glob_opt
6933   : /* empty */                   { $$ = NULL; }
6934   | glob
6935   ;
6936 
6937 gt_exp
6938   : '>'
6939   | error
6940     {
6941       punct_expected( '>' );
6942     }
6943   ;
6944 
6945 inline_stid_opt
6946   : /* empty */                   { $$ = TS_NONE; }
6947   | Y_INLINE
6948   ;
6949 
6950 int_exp
6951   : Y_INT_LIT
6952   | error
6953     {
6954       elaborate_error( "integer expected" );
6955     }
6956   ;
6957 
6958 literal_exp
6959   : Y_LITERAL
6960   | error
6961     {
6962       keyword_expected( L_LITERAL );
6963     }
6964   ;
6965 
6966 local_exp
6967   : Y_LOCAL
6968   | error
6969     {
6970       keyword_expected( L_LOCAL );
6971     }
6972   ;
6973 
6974 lparen_exp
6975   : '('
6976   | error
6977     {
6978       punct_expected( '(' );
6979     }
6980   ;
6981 
6982 lt_exp
6983   : '<'
6984   | error
6985     {
6986       punct_expected( '<' );
6987     }
6988   ;
6989 
6990 member_or_non_member_mask_opt
6991   : /* empty */                   { $$ = C_FN_UNSPECIFIED; }
6992   | Y_MEMBER                      { $$ = C_FN_MEMBER     ; }
6993   | Y_NON_MEMBER                  { $$ = C_FN_NON_MEMBER ; }
6994   ;
6995 
6996 namespace_btid_exp
6997   : Y_NAMESPACE
6998   | error
6999     {
7000       keyword_expected( L_NAMESPACE );
7001     }
7002   ;
7003 
7004 namespace_type
7005   : Y_NAMESPACE                   { $$ = C_TYPE_LIT_B( $1 ); }
7006   | Y_INLINE namespace_btid_exp   { $$ = C_TYPE_LIT( $2, $1, TA_NONE ); }
7007   ;
7008 
7009 of_exp
7010   : Y_OF
7011   | error
7012     {
7013       keyword_expected( L_OF );
7014     }
7015   ;
7016 
7017 of_scope_english
7018   : Y_OF scope_english_type_exp any_sname_c_exp
7019     { //
7020       // Scoped names are supported only in C++.  (However, we always allow
7021       // them in configuration files.)
7022       //
7023       // This check is better to do now in the parser rather than later in the
7024       // AST because it has to be done in fewer places in the code plus gives a
7025       // better error location.
7026       //
7027       if ( unsupported( LANG_CPP_ANY ) ) {
7028         print_error( &@2, "scoped names not supported in C\n" );
7029         c_sname_cleanup( &$3 );
7030         PARSE_ABORT();
7031       }
7032       $$ = $3;
7033       c_sname_set_local_type( &$$, &$2 );
7034     }
7035   ;
7036 
7037 of_scope_list_english
7038   : of_scope_list_english of_scope_english
7039     {
7040       $$ = $2;                          // "of scope X of scope Y" means Y::X
7041       c_sname_append_sname( &$$, &$1 );
7042       c_sname_fill_in_namespaces( &$$ );
7043       if ( !c_sname_check( &$$, &@1 ) ) {
7044         c_sname_cleanup( &$$ );
7045         PARSE_ABORT();
7046       }
7047     }
7048   | of_scope_english
7049   ;
7050 
7051 of_scope_list_english_opt
7052   : /* empty */                   { c_sname_init( &$$ ); }
7053   | of_scope_list_english
7054   ;
7055 
7056 operator_exp
7057   : Y_OPERATOR
7058   | error
7059     {
7060       keyword_expected( L_OPERATOR );
7061     }
7062   ;
7063 
7064 operator_opt
7065   : /* empty */
7066   | Y_OPERATOR
7067   ;
7068 
7069 quote2_exp
7070   : Y_QUOTE2
7071   | error
7072     {
7073       elaborate_error( "\"\" expected" );
7074     }
7075   ;
7076 
7077 rbrace_exp
7078   : '}'
7079   | error
7080     {
7081       punct_expected( '}' );
7082     }
7083   ;
7084 
7085 rbracket_exp
7086   : ']'
7087   | error
7088     {
7089       punct_expected( ']' );
7090     }
7091   ;
7092 
7093 reference_exp
7094   : Y_REFERENCE
7095   | error
7096     {
7097       keyword_expected( L_REFERENCE );
7098     }
7099   ;
7100 
7101 returning_exp
7102   : Y_RETURNING
7103   | error
7104     {
7105       keyword_expected( L_RETURNING );
7106     }
7107   ;
7108 
7109 rparen_exp
7110   : ')'
7111   | error
7112     {
7113       punct_expected( ')' );
7114     }
7115   ;
7116 
7117 scope_english_type
7118   : class_struct_union_btid       { $$ = C_TYPE_LIT_B( $1 ); }
7119   | namespace_type
7120   | Y_SCOPE                       { $$ = C_TYPE_LIT_B( TB_SCOPE ); }
7121   ;
7122 
7123 scope_english_type_exp
7124   : scope_english_type
7125   | error
7126     {
7127       elaborate_error(
7128         "\"%s\", \"%s\", \"%s\", \"%s\", or \"%s\" expected",
7129         L_CLASS, L_NAMESPACE, L_SCOPE, L_STRUCT, L_UNION
7130       );
7131     }
7132   ;
7133 
7134 semi_exp
7135   : ';'
7136   | error
7137     {
7138       punct_expected( ';' );
7139     }
7140   ;
7141 
7142 semi_opt
7143   : /* empty */
7144   | ';'
7145   ;
7146 
7147 semi_or_end
7148   : ';'
7149   | Y_END
7150   ;
7151 
7152 static_stid_opt
7153   : /* empty */                   { $$ = TS_NONE; }
7154   | Y_STATIC
7155   ;
7156 
7157 str_lit
7158   : Y_STR_LIT
7159   | Y_LEXER_ERROR
7160     {
7161       $$ = NULL;
7162       PARSE_ABORT();
7163     }
7164   ;
7165 
7166 str_lit_exp
7167   : str_lit
7168   | error
7169     {
7170       $$ = NULL;
7171       elaborate_error( "string literal expected" );
7172     }
7173   ;
7174 
7175 to_exp
7176   : Y_TO
7177   | error
7178     {
7179       keyword_expected( L_TO );
7180     }
7181   ;
7182 
7183 type_opt
7184   : /* empty */
7185   | Y_TYPEDEF
7186   ;
7187 
7188 typename_flag_opt
7189   : /* empty */                   { $$ = false; }
7190   | Y_TYPENAME                    { $$ = true; }
7191   ;
7192 
7193 unused_exp
7194   : Y_UNUSED
7195   | error
7196     {
7197       keyword_expected( L_UNUSED );
7198     }
7199   ;
7200 
7201 virtual_stid_exp
7202   : Y_VIRTUAL
7203   | error
7204     {
7205       keyword_expected( L_VIRTUAL );
7206     }
7207   ;
7208 
7209 virtual_stid_opt
7210   : /* empty */                   { $$ = TS_NONE; }
7211   | Y_VIRTUAL
7212   ;
7213 
7214 %%
7215 
7216 /// @endcond
7217 
7218 ////////// extern functions ///////////////////////////////////////////////////
7219 
7220 /**
7221  * Cleans up global parser data at program termination.
7222  */
7223 void parser_cleanup( void ) {
7224   c_ast_list_gc( &typedef_ast_list );
7225 }
7226 
7227 ///////////////////////////////////////////////////////////////////////////////
7228 /* vim:set et sw=2 ts=2: */
7229