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