1 /*
2 ** cdecl -- C gibberish translator
3 ** src/gibberish.c
4 **
5 ** Copyright (C) 2017-2021 Paul J. Lucas
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 functions for printing in gibberish, aka, a C/C++ declaration.
24 */
25
26 // local
27 #include "pjl_config.h" /* must go first */
28 #include "gibberish.h"
29 #include "c_ast.h"
30 #include "c_ast_util.h"
31 #include "c_lang.h"
32 #include "c_typedef.h"
33 #include "literals.h"
34 #include "options.h"
35 #include "util.h"
36
37 /// @cond DOXYGEN_IGNORE
38
39 // standard
40 #include <assert.h>
41 #include <ctype.h>
42 #include <stdlib.h>
43
44 /// @endcond
45
46 ///////////////////////////////////////////////////////////////////////////////
47
48 /**
49 * State maintained by c_ast_gibberish() (because there'd be too many function
50 * arguments otherwise).
51 */
52 struct g_state {
53 c_gib_flags_t flags; ///< Gibberish printing flags.
54 FILE *gout; ///< Where to write the gibberish.
55 bool postfix; ///< Doing postfix gibberish?
56 bool printed_space; ///< Printed a space yet?
57 bool printing_typedef; ///< Printing a `typedef`?
58 bool skip_name_for_using; ///< Skip type name for `using`?
59 };
60 typedef struct g_state g_state_t;
61
62 // local functions
63 static void g_init( g_state_t*, c_gib_flags_t, bool, FILE* );
64 static void g_print_ast( g_state_t*, c_ast_t const* );
65 static void g_print_ast_bit_width( g_state_t const*, c_ast_t const* );
66 static void g_print_ast_list( g_state_t const*, c_ast_list_t const* );
67 static void g_print_ast_name( g_state_t*, c_ast_t const* );
68 static void g_print_postfix( g_state_t*, c_ast_t const* );
69 static void g_print_qual_name( g_state_t*, c_ast_t const* );
70 static void g_print_space_ast_name( g_state_t*, c_ast_t const* );
71 static bool g_space_before_ptr_ref( g_state_t const*, c_ast_t const* );
72
73 ////////// inline functions ///////////////////////////////////////////////////
74
75 /**
76 * Prints a space only if we haven't printed one yet.
77 *
78 * @param g The g_state to use.
79 */
g_print_space_once(g_state_t * g)80 static inline void g_print_space_once( g_state_t *g ) {
81 if ( false_set( &g->printed_space ) )
82 FPUTC( ' ', g->gout );
83 }
84
85 ////////// local functions ////////////////////////////////////////////////////
86
87 /**
88 * Helper function for c_ast_gibberish() that prints \a ast as a C/C++
89 * declaration or cast.
90 *
91 * @param ast The AST to print.
92 * @param flags The gibberish flags to use.
93 * @param printing_typedef Printing a `typedef`?
94 * @param gout The `FILE` to print to.
95 */
c_ast_gibberish_impl(c_ast_t const * ast,c_gib_flags_t flags,bool printing_typedef,FILE * gout)96 static void c_ast_gibberish_impl( c_ast_t const *ast, c_gib_flags_t flags,
97 bool printing_typedef, FILE *gout ) {
98 assert( ast != NULL );
99 assert( gout != NULL );
100
101 g_state_t g;
102 g_init( &g, flags, printing_typedef, gout );
103 g_print_ast( &g, ast );
104 }
105
106 /**
107 * Initializes a g_state.
108 *
109 * @param g The g_state to initialize.
110 * @param flags The gibberish flags to use.
111 * @param printing_typedef Printing a `typedef`?
112 * @param gout The `FILE` to print it to.
113 */
g_init(g_state_t * g,c_gib_flags_t flags,bool printing_typedef,FILE * gout)114 static void g_init( g_state_t *g, c_gib_flags_t flags, bool printing_typedef,
115 FILE *gout ) {
116 assert( g != NULL );
117 assert( gout != NULL );
118
119 MEM_ZERO( g );
120 g->flags = flags;
121 g->gout = gout;
122 g->printing_typedef = printing_typedef;
123 if ( (flags & C_GIB_USING) != 0 )
124 g->skip_name_for_using = true;
125 if ( (flags & C_GIB_OMIT_TYPE) != 0 )
126 g->printed_space = true;
127 }
128
129 /**
130 * Prints \a ast as gibberish, aka, a C/C++ declaration.
131 *
132 * @param g The g_state to use.
133 * @param ast The AST to print.
134 */
g_print_ast(g_state_t * g,c_ast_t const * ast)135 static void g_print_ast( g_state_t *g, c_ast_t const *ast ) {
136 assert( g != NULL );
137 assert( ast != NULL );
138
139 c_type_t type = ast->type;
140
141 c_tid_t cv_qual_stid = TS_NONE;
142 bool is_default = false;
143 bool is_delete = false;
144 bool is_final = false;
145 bool is_noexcept = false;
146 bool is_override = false;
147 bool is_pure_virtual = false;
148 bool is_throw = false;
149 c_tid_t msc_call_atid = TA_NONE;
150 c_tid_t ref_qual_stid = TS_NONE;
151
152 //
153 // This isn't implemented using a visitor because c_ast_visit() visits in
154 // post-order and, in order to print gibberish, the AST has to be visited in
155 // pre-order. Since this is the only case where a pre-order traversal has to
156 // be done, it's not worth having a pre-order version of c_ast_visit().
157 //
158 switch ( ast->kind ) {
159 case K_CONSTRUCTOR:
160 case K_DESTRUCTOR:
161 case K_USER_DEF_CONVERSION:
162 //
163 // Since none of these have a return type, no space needs to be printed
164 // before the name, so lie and set the "space" flag.
165 //
166 g->printed_space = true;
167 PJL_FALLTHROUGH;
168
169 case K_FUNCTION:
170 case K_OPERATOR:
171 case K_USER_DEF_LITERAL:
172 //
173 // These things aren't printed as part of the type beforehand, so strip
174 // them out of the type here, but print them after the parameters.
175 //
176 cv_qual_stid = (type.stids & TS_MASK_QUALIFIER);
177 is_default = (type.stids & TS_DEFAULT) != TS_NONE;
178 is_delete = (type.stids & TS_DELETE) != TS_NONE;
179 is_final = (type.stids & TS_FINAL) != TS_NONE;
180 is_noexcept = (type.stids & TS_NOEXCEPT) != TS_NONE;
181 is_pure_virtual = (type.stids & TS_PURE_VIRTUAL) != TS_NONE;
182 is_throw = (type.stids & TS_THROW) != TS_NONE;
183 ref_qual_stid = (type.stids & TS_MASK_REF_QUALIFIER);
184
185 // In C++, "override" should be printed only if "final" isn't.
186 is_override = !is_final && (type.stids & TS_OVERRIDE) != TS_NONE;
187
188 type.stids &= c_tid_compl(
189 TS_MASK_QUALIFIER
190 | TS_DEFAULT
191 | TS_DELETE
192 | TS_FINAL
193 | TS_NOEXCEPT
194 | TS_OVERRIDE
195 | TS_PURE_VIRTUAL
196 | TS_THROW
197 | TS_MASK_REF_QUALIFIER
198 // In C++, if either "override" or "final" is printed,
199 // "virtual" shouldn't be.
200 | (is_override || is_final ? TS_VIRTUAL : TS_NONE)
201 );
202
203 //
204 // Microsoft calling conventions are printed specially.
205 //
206 msc_call_atid = type.atids & TA_ANY_MSC_CALL;
207 type.atids &= c_tid_compl( TA_ANY_MSC_CALL );
208
209 //
210 // Depending on the C++ language version, change noexcept to throw() or
211 // vice versa.
212 //
213 if ( opt_lang < LANG_CPP_11 ) {
214 if ( true_clear( &is_noexcept ) )
215 is_throw = true;
216 } else {
217 if ( true_clear( &is_throw ) )
218 is_noexcept = true;
219 }
220 PJL_FALLTHROUGH;
221
222 case K_ARRAY:
223 case K_APPLE_BLOCK:
224 if ( !c_type_is_none( &type ) )
225 FPRINTF( g->gout, "%s ", c_type_name_c( &type ) );
226 if ( ast->kind == K_USER_DEF_CONVERSION ) {
227 if ( !c_sname_empty( &ast->sname ) )
228 FPRINTF( g->gout, "%s::", c_sname_full_name( &ast->sname ) );
229 FPRINTF( g->gout, "%s ", L_OPERATOR );
230 }
231 if ( ast->as.parent.of_ast != NULL )
232 g_print_ast( g, ast->as.parent.of_ast );
233 if ( msc_call_atid != TA_NONE &&
234 !c_ast_parent_is_kind( ast, K_POINTER ) ) {
235 //
236 // If ast is a function having a Microsoft calling convention, but not
237 // a pointer to such a function, print the calling convention.
238 // (Pointers to such functions are handled in g_print_postfix().)
239 //
240 FPRINTF( g->gout, " %s", c_tid_name_c( msc_call_atid ) );
241 }
242 if ( false_set( &g->postfix ) ) {
243 if ( !g->skip_name_for_using && (g->flags & C_GIB_CAST) == 0 )
244 g_print_space_once( g );
245 g_print_postfix( g, ast );
246 }
247 if ( cv_qual_stid != TS_NONE )
248 FPRINTF( g->gout, " %s", c_tid_name_c( cv_qual_stid ) );
249 if ( ref_qual_stid != TS_NONE ) {
250 FPUTS(
251 c_tid_is_any( ref_qual_stid, TS_REFERENCE ) ? " &" : " &&",
252 g->gout
253 );
254 }
255 if ( is_noexcept )
256 FPRINTF( g->gout, " %s", L_NOEXCEPT );
257 else if ( is_throw )
258 FPRINTF( g->gout, " %s()", L_THROW );
259 if ( is_override )
260 FPRINTF( g->gout, " %s", L_OVERRIDE );
261 else if ( is_final )
262 FPRINTF( g->gout, " %s", L_FINAL );
263 else if ( is_pure_virtual )
264 FPUTS( " = 0", g->gout );
265 if ( is_default )
266 FPRINTF( g->gout, " = %s", L_DEFAULT );
267 else if ( is_delete )
268 FPRINTF( g->gout, " = %s", L_DELETE );
269 break;
270
271 case K_BUILTIN:
272 if ( (g->flags & C_GIB_OMIT_TYPE) == 0 )
273 FPUTS( c_type_name_c( &ast->type ), g->gout );
274 g_print_space_ast_name( g, ast );
275 g_print_ast_bit_width( g, ast );
276 break;
277
278 case K_ENUM_CLASS_STRUCT_UNION: {
279 if ( c_type_is_tid_any( &type, TB_ENUM ) ) {
280 //
281 // Special case: an enum class must be written as just "enum" when
282 // doing an elaborated-type-specifier:
283 //
284 // c++decl> declare e as enum class C
285 // enum C e; // not: enum class C e;
286 //
287 type.btids &= c_tid_compl( TB_STRUCT | TB_CLASS );
288 }
289
290 if ( opt_east_const ) {
291 cv_qual_stid = type.stids & TS_CV;
292 type.stids &= c_tid_compl( TS_CV );
293 }
294
295 char const *const type_name =
296 (g->flags & (C_GIB_CAST | C_GIB_DECL)) != 0 ?
297 c_type_name_ecsu( &type ) :
298 c_type_name_c( &type );
299
300 FPUTS( type_name, g->gout );
301
302 if ( (g->flags & C_GIB_TYPEDEF) == 0 || g->printing_typedef ) {
303 //
304 // For enum, class, struct, or union (ECSU) types, we need to print the
305 // ECSU name when either:
306 //
307 // + The AST is not a typedef, e.g.:
308 //
309 // cdecl> declare x as struct S
310 // struct S x; // ast->sname = "x"; escu_name = "S"
311 //
312 // (See the printing_typedef comment in c_typedef_gibberish()
313 // first.) Or:
314 //
315 // + We're printing an ECSU type in C only, e.g.:
316 //
317 // typedef struct S T; // ast->sname ="T"; escu_name = "S"
318 //
319 FPRINTF( g->gout,
320 "%s%s",
321 type_name[0] != '\0' ? " " : "",
322 c_sname_full_name( &ast->as.ecsu.ecsu_sname )
323 );
324 }
325
326 if ( ast->as.ecsu.of_ast != NULL ) {
327 FPUTS( " : ", g->gout );
328 g_print_ast( g, ast->as.ecsu.of_ast );
329 }
330
331 if ( cv_qual_stid != TS_NONE )
332 FPRINTF( g->gout, " %s", c_tid_name_c( cv_qual_stid ) );
333
334 g_print_space_ast_name( g, ast );
335 break;
336 }
337
338 case K_NAME:
339 assert( opt_lang < LANG_C_2X );
340 if ( opt_lang > LANG_C_KNR ) {
341 //
342 // In C89-C17, just a name for a function parameter is implicitly int:
343 //
344 // cdecl> declare f as function (x) returning double
345 // double f(int x)
346 //
347 FPUTS( L_INT, g->gout );
348 }
349 if ( (g->flags & C_GIB_CAST) == 0 ) {
350 if ( opt_lang > LANG_C_KNR )
351 FPUTC( ' ', g->gout );
352 g_print_ast_name( g, ast );
353 }
354 break;
355
356 case K_POINTER:
357 case K_REFERENCE:
358 case K_RVALUE_REFERENCE:
359 if ( (g->flags & C_GIB_OMIT_TYPE) == 0 ) {
360 c_tid_t const stid = type.stids & TS_MASK_STORAGE;
361 if ( stid != TS_NONE )
362 FPRINTF( g->gout, "%s ", c_tid_name_c( stid ) );
363 }
364 g_print_ast( g, ast->as.ptr_ref.to_ast );
365 if ( g_space_before_ptr_ref( g, ast ) )
366 g_print_space_once( g );
367 if ( !g->postfix )
368 g_print_qual_name( g, ast );
369 break;
370
371 case K_POINTER_TO_MEMBER:
372 g_print_ast( g, ast->as.ptr_mbr.of_ast );
373 if ( !g->postfix ) {
374 FPUTC( ' ', g->gout );
375 g_print_qual_name( g, ast );
376 }
377 break;
378
379 case K_TYPEDEF:
380 if ( (g->flags & C_GIB_OMIT_TYPE) == 0 ) {
381 //
382 // Of course a K_TYPEDEF AST also has a type comprising TB_TYPEDEF, but
383 // we need to see whether there's any more to the type, e.g., "const".
384 //
385 bool const is_more_than_plain_typedef =
386 !c_type_equal( &ast->type, &C_TYPE_LIT_B( TB_TYPEDEF ) );
387
388 if ( is_more_than_plain_typedef && !opt_east_const )
389 FPUTS( c_type_name_c( &ast->type ), g->gout );
390
391 //
392 // Special case: C++23 adds an _Atomic(T) macro for compatibility with
393 // C11, but while _Atomic can be printed without () in C, they're
394 // required in C++:
395 //
396 // _Atomic size_t x; // C11 only
397 // _Atomic(size_t) y; // C11 or C++23
398 //
399 // Note that this handles printing () only for typedef types; for non-
400 // typedef types, see the similar special case in c_type_name_impl().
401 //
402 bool const print_parens_for_cpp23_Atomic =
403 OPT_LANG_IS(CPP_MIN(23)) &&
404 c_tid_is_any( type.stids, TS_ATOMIC );
405
406 if ( print_parens_for_cpp23_Atomic )
407 FPUTC( '(', g->gout );
408 else if ( is_more_than_plain_typedef && !opt_east_const )
409 FPUTC( ' ', g->gout );
410
411 //
412 // Temporarily set skip_name_for_using to false to force printing of
413 // the type's name. This is necessary for when printing the name of a
414 // typedef of a typedef as a "using" declaration:
415 //
416 // c++decl> typedef int32_t foo_t
417 // c++decl> show foo_t as using
418 // using foo_t = int32_t;
419 //
420 bool const orig_skip_name_for_using = g->skip_name_for_using;
421 g->skip_name_for_using = false;
422 g_print_ast_name( g, ast->as.tdef.for_ast );
423 g->skip_name_for_using = orig_skip_name_for_using;
424
425 if ( print_parens_for_cpp23_Atomic )
426 FPUTC( ')', g->gout );
427 if ( is_more_than_plain_typedef && opt_east_const )
428 FPRINTF( g->gout, " %s", c_type_name_c( &ast->type ) );
429 }
430
431 g_print_space_ast_name( g, ast );
432 g_print_ast_bit_width( g, ast );
433 break;
434
435 case K_VARIADIC:
436 FPUTS( L_ELLIPSIS, g->gout );
437 break;
438
439 CASE_K_PLACEHOLDER;
440 } // switch
441 }
442
443 /**
444 * Helper function for g_print_ast() that prints an array's size.
445 *
446 * @param g The g_state to use.
447 * @param ast The AST that is a \ref K_ARRAY whose size to print.
448 */
g_print_ast_array_size(g_state_t const * g,c_ast_t const * ast)449 static void g_print_ast_array_size( g_state_t const *g, c_ast_t const *ast ) {
450 assert( g != NULL );
451 assert( ast != NULL );
452 assert( ast->kind == K_ARRAY );
453
454 FPUTS( graph_token_c( "[" ), g->gout );
455 if ( ast->as.array.stids != TS_NONE )
456 FPRINTF( g->gout, "%s ", c_tid_name_c( ast->as.array.stids ) );
457 switch ( ast->as.array.size ) {
458 case C_ARRAY_SIZE_NONE:
459 break;
460 case C_ARRAY_SIZE_VARIABLE:
461 FPUTC( '*', g->gout );
462 break;
463 default:
464 FPRINTF( g->gout, PRId_C_ARRAY_SIZE_T, ast->as.array.size );
465 } // switch
466 FPUTS( graph_token_c( "]" ), g->gout );
467 }
468
469 /**
470 * Helper function for c_ast_visitor_english() that prints a bit-field width,
471 * if any.
472 *
473 * @param g The g_state to use.
474 * @param ast The AST to print the bit-field width of.
475 */
g_print_ast_bit_width(g_state_t const * g,c_ast_t const * ast)476 static void g_print_ast_bit_width( g_state_t const *g, c_ast_t const *ast ) {
477 assert( g != NULL );
478 assert( ast != NULL );
479 assert( c_ast_is_kind_any( ast, K_BUILTIN | K_TYPEDEF ) );
480
481 if ( ast->as.builtin.bit_width > 0 )
482 FPRINTF( g->gout, " : " PRId_C_BIT_WIDTH_T, ast->as.builtin.bit_width );
483 }
484
485 /**
486 * Prints a list of AST nodes separated by commas.
487 *
488 * @param g The g_state to use.
489 * @param ast_list The list of AST nodes to print.
490 *
491 * @sa g_print_ast()
492 */
g_print_ast_list(g_state_t const * g,c_ast_list_t const * ast_list)493 static void g_print_ast_list( g_state_t const *g,
494 c_ast_list_t const *ast_list ) {
495 assert( g != NULL );
496 assert( ast_list != NULL );
497
498 bool comma = false;
499
500 FOREACH_SLIST_NODE( ast_node, ast_list ) {
501 if ( true_or_set( &comma ) )
502 FPUTS( ", ", g->gout );
503 g_state_t params_g;
504 g_init(
505 ¶ms_g,
506 g->flags & ~C_GIB_OMIT_TYPE, /*printing_typedef=*/false, g->gout
507 );
508 c_ast_t const *const param_ast = c_param_ast( ast_node );
509 g_print_ast( ¶ms_g, param_ast );
510 } // for
511 }
512
513 /**
514 * Prints either the full or local name of \a ast based on whether we're
515 * emitting the gibberish for a `typedef` since it can't have a scoped name.
516 *
517 * @param g The g_state to use.
518 * @param ast The AST to get the name of.
519 */
g_print_ast_name(g_state_t * g,c_ast_t const * ast)520 static void g_print_ast_name( g_state_t *g, c_ast_t const *ast ) {
521 assert( g != NULL );
522 assert( ast != NULL );
523
524 if ( true_clear( &g->skip_name_for_using ) ) {
525 //
526 // If we're printing a type as a "using" declaration, we have to skip
527 // printing the type name since it's already been printed immediately after
528 // the "using". For example, the type:
529 //
530 // typedef int (*PF)(char c);
531 //
532 // when printed as a "using":
533 //
534 // using PF = int(*)(char c);
535 //
536 // had the "using PF =" part already printed in c_typedef_gibberish(), so
537 // we don't print it again after the '*'; but we still need to print all
538 // subsequent names, if any. Hence, reset the flags and print nothing.
539 //
540 g->printed_space = true;
541 return;
542 }
543
544 FPUTS(
545 //
546 // For typedefs, the scope names (if any) were already printed in
547 // c_typedef_gibberish() so now we just print the local name.
548 //
549 (g->flags & C_GIB_TYPEDEF) != 0 ?
550 c_sname_local_name( &ast->sname ) : c_sname_full_name( &ast->sname ),
551 g->gout
552 );
553 }
554
555 /**
556 * Helper function for g_print_ast() that handles the printing of "postfix"
557 * cases:
558 *
559 * + Array of pointer to function.
560 * + Pointer to array.
561 * + Reference to array.
562 *
563 * @param g The g_state to use.
564 * @param ast The AST.
565 */
g_print_postfix(g_state_t * g,c_ast_t const * ast)566 static void g_print_postfix( g_state_t *g, c_ast_t const *ast ) {
567 assert( g != NULL );
568 assert( ast != NULL );
569 assert( c_ast_is_parent( ast ) );
570
571 c_ast_t const *const parent_ast = ast->parent_ast;
572
573 if ( parent_ast != NULL ) {
574 switch ( parent_ast->kind ) {
575 case K_ARRAY:
576 case K_APPLE_BLOCK:
577 case K_CONSTRUCTOR:
578 case K_DESTRUCTOR:
579 case K_FUNCTION:
580 case K_OPERATOR:
581 case K_USER_DEF_CONVERSION:
582 case K_USER_DEF_LITERAL:
583 g_print_postfix( g, parent_ast );
584 break;
585
586 case K_POINTER:
587 case K_POINTER_TO_MEMBER:
588 case K_REFERENCE:
589 case K_RVALUE_REFERENCE:
590 switch ( ast->kind ) {
591 case K_APPLE_BLOCK:
592 FPUTS( "(^", g->gout );
593 break;
594
595 default:
596 //
597 // Pointers are written in gibberish like:
598 //
599 // type (*a)[size] // pointer to array
600 // type (*f)() // pointer to function
601 // type (*a[size])() // array of pointer to function
602 //
603 // so we need to add parentheses.
604 //
605 FPUTC( '(', g->gout );
606
607 if ( c_type_is_tid_any( &ast->type, TA_ANY_MSC_CALL ) ) {
608 //
609 // A pointer to a function having a Microsoft calling convention
610 // has the convention printed just inside the '(':
611 //
612 // void (__stdcall *pf)(int, int)
613 //
614 c_tid_t const msc_call_atid = ast->type.atids & TA_ANY_MSC_CALL;
615 FPRINTF( g->gout, "%s ", c_tid_name_c( msc_call_atid ) );
616 }
617 break;
618
619 case K_POINTER:
620 //
621 // However, if there are consecutive pointers, omit the extra '(':
622 //
623 // type (**a)[size] // pointer to pointer to array[size]
624 //
625 // rather than:
626 //
627 // type (*(*a))[size] // extra () unnecessary
628 //
629 break;
630 } // switch
631
632 g_print_qual_name( g, parent_ast );
633 if ( c_ast_is_parent( parent_ast->parent_ast ) )
634 g_print_postfix( g, parent_ast );
635
636 if ( !c_ast_is_kind_any( ast, K_ANY_POINTER ) )
637 FPUTC( ')', g->gout );
638 break;
639
640 case K_BUILTIN:
641 case K_ENUM_CLASS_STRUCT_UNION:
642 case K_NAME:
643 case K_TYPEDEF:
644 case K_VARIADIC:
645 // nothing to do
646 break;
647
648 CASE_K_PLACEHOLDER;
649 } // switch
650 } else {
651 //
652 // We've reached the root of the AST that has the name of the thing we're
653 // printing the gibberish for.
654 //
655 if ( ast->kind == K_APPLE_BLOCK )
656 FPUTS( "(^", g->gout );
657 g_print_space_ast_name( g, ast );
658 if ( ast->kind == K_APPLE_BLOCK )
659 FPUTC( ')', g->gout );
660 }
661
662 //
663 // We're now unwinding the recursion: print the "postfix" things (size for
664 // arrays, parameters for functions) in root-to-leaf order.
665 //
666 switch ( ast->kind ) {
667 case K_ARRAY:
668 g_print_ast_array_size( g, ast );
669 break;
670 case K_APPLE_BLOCK:
671 case K_CONSTRUCTOR:
672 case K_FUNCTION:
673 case K_OPERATOR:
674 case K_USER_DEF_LITERAL:
675 FPUTC( '(', g->gout );
676 g_print_ast_list( g, &ast->as.func.param_ast_list );
677 FPUTC( ')', g->gout );
678 break;
679 case K_DESTRUCTOR:
680 case K_USER_DEF_CONVERSION:
681 FPUTS( "()", g->gout );
682 break;
683 case K_BUILTIN:
684 case K_ENUM_CLASS_STRUCT_UNION:
685 case K_NAME:
686 case K_POINTER:
687 case K_POINTER_TO_MEMBER:
688 case K_REFERENCE:
689 case K_RVALUE_REFERENCE:
690 case K_TYPEDEF:
691 case K_VARIADIC:
692 // nothing to do
693 break;
694 CASE_K_PLACEHOLDER;
695 } // switch
696 }
697
698 /**
699 * Helper function for g_print_ast() that prints a pointer, pointer-to-member,
700 * reference, or rvalue reference, its qualifier, if any, and the name, if any.
701 *
702 * @param g The g_state to use.
703 * @param ast The AST that is one of \ref K_POINTER, \ref K_POINTER_TO_MEMBER,
704 * \ref K_REFERENCE, or \ref K_RVALUE_REFERENCE whose qualifier, if any, and
705 * name, if any, to print.
706 */
g_print_qual_name(g_state_t * g,c_ast_t const * ast)707 static void g_print_qual_name( g_state_t *g, c_ast_t const *ast ) {
708 assert( g != NULL );
709 assert( ast != NULL );
710
711 c_tid_t const qual_stid = ast->type.stids & TS_MASK_QUALIFIER;
712
713 switch ( ast->kind ) {
714 case K_POINTER:
715 if ( qual_stid != TS_NONE && (g->flags & C_GIB_CAST) == 0 &&
716 !c_ast_is_ptr_to_kind( ast, K_FUNCTION ) ) {
717 //
718 // If we're printing a type as a "using" declaration and there's a
719 // qualifier for the pointer, print a space before it. For example:
720 //
721 // typedef int *const PI;
722 //
723 // when printed as a "using":
724 //
725 // using PI = int *const;
726 //
727 // However, if it's a pointer-to-function, don't. For example:
728 //
729 // typedef int (*const PF)(char c);
730 //
731 // when printed as a "using":
732 //
733 // using PF = int(*const)(char c);
734 //
735 g_print_space_once( g );
736 }
737 FPUTC( '*', g->gout );
738 break;
739
740 case K_POINTER_TO_MEMBER:
741 FPRINTF( g->gout,
742 "%s::*", c_sname_full_name( &ast->as.ptr_mbr.class_sname )
743 );
744 break;
745
746 case K_REFERENCE:
747 if ( opt_alt_tokens ) {
748 g_print_space_once( g );
749 FPRINTF( g->gout, "%s ", L_BITAND );
750 } else {
751 FPUTC( '&', g->gout );
752 }
753 break;
754
755 case K_RVALUE_REFERENCE:
756 if ( opt_alt_tokens ) {
757 g_print_space_once( g );
758 FPRINTF( g->gout, "%s ", L_AND );
759 } else {
760 FPUTS( "&&", g->gout );
761 }
762 break;
763
764 default:
765 /* suppress warning */;
766 } // switch
767
768 if ( qual_stid != TS_NONE ) {
769 FPUTS( c_tid_name_c( qual_stid ), g->gout );
770
771 if ( (g->flags & (C_GIB_DECL | C_GIB_TYPEDEF)) != 0 &&
772 c_ast_find_name( ast, C_VISIT_UP ) != NULL ) {
773 //
774 // For declarations and typedefs, if there is a qualifier and if a name
775 // has yet to be printed, we always need to print a space after the
776 // qualifier, e.g.:
777 //
778 // char *const p;
779 // ^
780 FPUTC( ' ', g->gout );
781 }
782 }
783
784 g_print_ast_name( g, ast );
785 }
786
787 /**
788 * Helper function for g_print_ast() that prints a space (if it hasn't printed
789 * one before) and an AST node's name, if any; but only if we're printing a
790 * declaration (not a cast).
791 *
792 * @param g The g_state to use.
793 * @param ast The AST to print the name (if any) of.
794 */
g_print_space_ast_name(g_state_t * g,c_ast_t const * ast)795 static void g_print_space_ast_name( g_state_t *g, c_ast_t const *ast ) {
796 assert( g != NULL );
797 assert( ast != NULL );
798
799 if ( (g->flags & C_GIB_CAST) != 0 )
800 return; // for casts, print nothing
801
802 switch ( ast->kind ) {
803 case K_CONSTRUCTOR:
804 FPUTS( c_sname_full_name( &ast->sname ), g->gout );
805 break;
806 case K_DESTRUCTOR:
807 if ( c_sname_count( &ast->sname ) > 1 )
808 FPRINTF( g->gout, "%s::", c_sname_scope_name( &ast->sname ) );
809 if ( opt_alt_tokens )
810 FPRINTF( g->gout, "%s ", L_COMPL );
811 else
812 FPUTC( '~', g->gout );
813 FPUTS( c_sname_local_name( &ast->sname ), g->gout );
814 break;
815 case K_OPERATOR: {
816 g_print_space_once( g );
817 if ( !c_sname_empty( &ast->sname ) )
818 FPRINTF( g->gout, "%s::", c_sname_full_name( &ast->sname ) );
819 char const *const token = c_oper_token_c( ast->as.oper.oper_id );
820 FPRINTF( g->gout,
821 "%s%s%s", L_OPERATOR, isalpha( token[0] ) ? " " : "", token
822 );
823 break;
824 }
825 case K_USER_DEF_CONVERSION:
826 // Do nothing since these don't have names.
827 break;
828 case K_USER_DEF_LITERAL:
829 g_print_space_once( g );
830 if ( c_sname_count( &ast->sname ) > 1 )
831 FPRINTF( g->gout, "%s::", c_sname_scope_name( &ast->sname ) );
832 FPRINTF( g->gout,
833 "%s\"\" %s", L_OPERATOR, c_sname_local_name( &ast->sname )
834 );
835 break;
836 default:
837 if ( !c_sname_empty( &ast->sname ) ) {
838 if ( !g->skip_name_for_using )
839 g_print_space_once( g );
840 g_print_ast_name( g, ast );
841 }
842 break;
843 } // switch
844 }
845
846 /**
847 * Determine whether we should print a space before the `*`, `&`, or `&&` in a
848 * declaration. For all kinds _except_ function-like ASTs, we want the output
849 * to be like:
850 *
851 * type *var
852 *
853 * i.e., the `*`, `&`, or `&&` adjacent to the variable; for function-like
854 * ASTs, when there's no name for a parameter, or when we're casting, we want
855 * the output to be like:
856 *
857 * type* func() // function
858 * type* (^block)() // block
859 * func(type*) // nameless function parameter
860 * (type*)expr // cast
861 *
862 * i.e., the `*`, `&`, or `&&` adjacent to the type.
863 *
864 * However, as an exception, if we're declaring more than one pointer to
865 * function returning a pointer or reference in the same declaration, then keep
866 * the `*`, `&`, or `&&` adjacent to the function like:
867 *
868 * type &(*f)(), &(*g)()
869 *
870 * not:
871 *
872 * type& (*f)(), &(*g)()
873 *
874 * because the latter looks inconsistent (even though it's correct).
875 *
876 * @param g The g_state to use.
877 * @param ast The current AST node.
878 * @return Returns `true` only if we should print a space after type type.
879 */
g_space_before_ptr_ref(g_state_t const * g,c_ast_t const * ast)880 static bool g_space_before_ptr_ref( g_state_t const *g, c_ast_t const *ast ) {
881 if ( g->skip_name_for_using )
882 return false;
883 if ( (g->flags & C_GIB_CAST) != 0 )
884 return false;
885 if ( c_ast_find_name( ast, C_VISIT_UP ) == NULL )
886 return false;
887 if ( c_ast_find_kind_any( ast->parent_ast, C_VISIT_UP, K_ANY_FUNCTION_LIKE ) )
888 return (g->flags & C_GIB_MULTI_DECL) != 0;
889 return true;
890 }
891
892 ////////// extern functions ///////////////////////////////////////////////////
893
c_ast_gibberish(c_ast_t const * ast,c_gib_flags_t flags,FILE * gout)894 void c_ast_gibberish( c_ast_t const *ast, c_gib_flags_t flags, FILE *gout ) {
895 assert( ast != NULL );
896 assert( (flags & (C_GIB_CAST | C_GIB_DECL )) != 0 );
897 assert( (flags & (C_GIB_TYPEDEF | C_GIB_USING)) == 0 );
898 assert( (flags & C_GIB_OMIT_TYPE ) == 0 || (flags & C_GIB_DECL) != 0 );
899 assert( (flags & C_GIB_MULTI_DECL) == 0 || (flags & C_GIB_DECL) != 0 );
900 assert( gout != NULL );
901
902 if ( (flags & C_GIB_OMIT_TYPE) == 0 ) {
903 switch ( ast->align.kind ) {
904 case C_ALIGNAS_NONE:
905 break;
906 case C_ALIGNAS_EXPR:
907 FPRINTF( gout, "%s(%u) ", alignas_lang(), ast->align.as.expr );
908 break;
909 case C_ALIGNAS_TYPE:
910 FPRINTF( gout, "%s(", alignas_lang() );
911 c_ast_gibberish( ast->align.as.type_ast, C_GIB_DECL, gout );
912 FPUTS( ") ", gout );
913 break;
914 } // switch
915 }
916
917 c_ast_gibberish_impl( ast, flags, /*printing_typedef=*/false, gout );
918 }
919
c_cast_gibberish(c_cast_kind_t kind)920 char const* c_cast_gibberish( c_cast_kind_t kind ) {
921 switch ( kind ) {
922 case C_CAST_NONE : return "none";
923 case C_CAST_C : return "C";
924 case C_CAST_CONST : return L_CONST_CAST;
925 case C_CAST_DYNAMIC : return L_DYNAMIC_CAST;
926 case C_CAST_REINTERPRET : return L_REINTERPRET_CAST;
927 case C_CAST_STATIC : return L_STATIC_CAST;
928 } // switch
929 UNEXPECTED_INT_VALUE( kind );
930 }
931
c_typedef_gibberish(c_typedef_t const * tdef,c_gib_flags_t flags,FILE * gout)932 void c_typedef_gibberish( c_typedef_t const *tdef, c_gib_flags_t flags,
933 FILE *gout ) {
934 assert( tdef != NULL );
935 assert( (flags & (C_GIB_TYPEDEF | C_GIB_USING)) != 0 );
936 assert( (flags & (C_GIB_CAST | C_GIB_DECL
937 | C_GIB_MULTI_DECL | C_GIB_OMIT_TYPE)) == 0 );
938 assert( gout != NULL );
939
940 size_t scope_close_braces_to_print = 0;
941 c_type_t scope_type = T_NONE;
942
943 c_sname_t const *sname = c_ast_find_name( tdef->ast, C_VISIT_DOWN );
944 if ( sname != NULL && c_sname_count( sname ) > 1 ) {
945 scope_type = *c_sname_first_type( sname );
946 //
947 // A type name can't be scoped in a typedef declaration, e.g.:
948 //
949 // typedef int S::T::I; // illegal
950 //
951 // so we have to wrap it in a scoped declaration, one of: class, namespace,
952 // struct, or union.
953 //
954 if ( scope_type.btids != TB_NAMESPACE ||
955 opt_lang_is_any( LANG_CPP_MIN(17) | LANG_C_ANY ) ) {
956 //
957 // All C++ versions support nested class/struct/union declarations, e.g.:
958 //
959 // struct S::T { typedef int I; }
960 //
961 // However, only C++17 and later support nested namespace declarations:
962 //
963 // namespace S::T { typedef int I; }
964 //
965 // If the current language is any version of C, also print in nested
966 // namespace form even though C doesn't have any namespaces because we
967 // might be being asked to print all types.
968 //
969 c_sname_t temp_sname;
970 if ( c_type_is_tid_any( &scope_type, TS_INLINE ) ) {
971 //
972 // For an inline namespace, the "inline" is printed like:
973 //
974 // inline namespace NS { // ...
975 //
976 // as opposed to:
977 //
978 // namespace inline NS { // ...
979 //
980 // so we have to turn off TS_INLINE on the sname's scope type.
981 //
982 temp_sname = c_sname_dup( sname );
983 c_scope_data( temp_sname.head )->type.stids &= c_tid_compl( TS_INLINE );
984 sname = &temp_sname;
985 }
986 else {
987 c_sname_init( &temp_sname ); // for unconditional c_sname_cleanup()
988 //
989 // For all other cases (non-inline namespaces, enum, class, struct, and
990 // union), the type is the scope's type, not the fisrt type used above.
991 // For example, in:
992 //
993 // struct S::T { typedef int I; }
994 // ^
995 //
996 // it's the T that's the struct; what S is doesn't matter, so we reset
997 // scope_type to be the actual scope's type of S::T::I which is T.
998 //
999 scope_type = *c_sname_scope_type( sname );
1000 if ( scope_type.btids == TB_SCOPE )
1001 scope_type.btids = TB_NAMESPACE;
1002
1003 //
1004 // Starting in C++20, non-inline namespace may still have nested inline
1005 // namespaces and they're printed like:
1006 //
1007 // namespace A::inline B { // ...
1008 //
1009 // so we turn off "inline" on the scope's type so "inline" isn't
1010 // printed before "namespace" as well.
1011 //
1012 scope_type.stids &= c_tid_compl( TS_INLINE );
1013 }
1014
1015 FPRINTF( gout,
1016 "%s %s { ", c_type_name_c( &scope_type ), c_sname_scope_name( sname )
1017 );
1018 c_sname_cleanup( &temp_sname );
1019 scope_close_braces_to_print = 1;
1020 }
1021 else {
1022 //
1023 // Namespaces in C++14 and earlier require distinct declarations:
1024 //
1025 // namespace S { namespace T { typedef int I; } }
1026 //
1027 FOREACH_SNAME_SCOPE_UNTIL( scope, sname, sname->tail ) {
1028 scope_type = c_scope_data( scope )->type;
1029 if ( scope_type.btids == TB_SCOPE )
1030 scope_type.btids = TB_NAMESPACE;
1031 FPRINTF( gout,
1032 "%s %s { ",
1033 c_type_name_c( &scope_type ), c_scope_data( scope )->name
1034 );
1035 } // for
1036 scope_close_braces_to_print = c_sname_count( sname ) - 1;
1037 }
1038 }
1039
1040 bool const is_ecsu = tdef->ast->kind == K_ENUM_CLASS_STRUCT_UNION;
1041
1042 //
1043 // When printing a type, all types except enum, class, struct, or union types
1044 // must be preceded by "typedef", e.g.:
1045 //
1046 // typedef int int32_t;
1047 //
1048 // However, enum, class, struct, and union types are preceded by "typedef"
1049 // only when the type was declared in C since those types in C without a
1050 // typedef are merely in the tags namespace and not first-class types:
1051 //
1052 // struct S; // In C, tag only -- not a type.
1053 // typedef struct S S; // Now it's a type.
1054 //
1055 // In C++, such typedefs are unnecessary since such types are first-class
1056 // types and not just tags, so we don't print "typedef".
1057 //
1058 bool const printing_typedef = (flags & C_GIB_TYPEDEF) != 0 &&
1059 (!is_ecsu || c_lang_is_c( tdef->lang_ids ) ||
1060 (OPT_LANG_IS(C_ANY) && !c_lang_is_cpp( tdef->lang_ids )));
1061
1062 //
1063 // When printing a "using", we don't have to check languages since "using" is
1064 // available only in C++.
1065 //
1066 bool const printing_using = (flags & C_GIB_USING) != 0 && !is_ecsu;
1067
1068 if ( printing_typedef )
1069 FPRINTF( gout, "%s ", L_TYPEDEF );
1070 else if ( printing_using )
1071 FPRINTF( gout, "%s %s = ", L_USING, c_sname_local_name( sname ) );
1072
1073 c_ast_gibberish_impl(
1074 tdef->ast, printing_using ? C_GIB_USING : C_GIB_TYPEDEF,
1075 printing_typedef, gout
1076 );
1077
1078 if ( scope_close_braces_to_print > 0 ) {
1079 FPUTC( ';', gout );
1080 while ( scope_close_braces_to_print-- > 0 )
1081 FPUTS( " }", gout );
1082 }
1083
1084 if ( opt_semicolon && scope_type.btids != TB_NAMESPACE )
1085 FPUTC( ';', gout );
1086 FPUTC( '\n', gout );
1087 }
1088
graph_token_c(char const * token)1089 char const* graph_token_c( char const *token ) {
1090 assert( token != NULL );
1091
1092 if ( !opt_alt_tokens ) {
1093 switch ( opt_graph ) {
1094 case C_GRAPH_NONE:
1095 break;
1096 //
1097 // Even though this could be done character-by-character, it's easier for
1098 // the calling code if multi-character tokens containing graph characters
1099 // are returned as a single string.
1100 //
1101 case C_GRAPH_DI:
1102 if ( opt_lang >= LANG_C_95 ) {
1103 switch ( token[0] ) {
1104 case '#' : return token[1] == '#' ? "%:%:" : "%:";
1105 case '[' : return token[1] == '[' ? "<:<:" : "<:";
1106 case ']' : return token[1] == ']' ? ":>:>" : ":>";
1107 case '{' : return "<%";
1108 case '}' : return "%>";
1109 } // switch
1110 }
1111 break;
1112 case C_GRAPH_TRI:
1113 if ( opt_lang >= LANG_C_89 && opt_lang <= LANG_CPP_14 ) {
1114 switch ( token[0] ) {
1115 case '#' : return "?\?=";
1116 case '[' : return token[1] == '[' ? "?\?(?\?(" : "?\?(";
1117 case ']' : return token[1] == ']' ? "?\?)?\?)" : "?\?)";
1118 case '\\' : return "?\?/";
1119 case '^' : return token[1] == '=' ? "?\?'=" : "?\?'";
1120 case '{' : return "?\?<";
1121 case '}' : return "?\?>";
1122 case '|' : switch ( token[1] ) {
1123 case '=': return "?\?!=";
1124 case '|': return "?\?!?\?!";
1125 } // switch
1126 return "?\?!";
1127 case '~' : return "?\?-";
1128 } // switch
1129 }
1130 break;
1131 } // switch
1132 }
1133
1134 return token;
1135 }
1136
1137 ///////////////////////////////////////////////////////////////////////////////
1138 /* vim:set et sw=2 ts=2: */
1139