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       &params_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( &params_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