1 /*
2 **      cdecl -- C gibberish translator
3 **      src/c_ast_util.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 various cdecl-specific algorithms for construcing an
24  * Abstract Syntax Tree (AST) for parsed C/C++ declarations.
25  */
26 
27 // local
28 #include "pjl_config.h"                 /* must go first */
29 /// @cond DOXYGEN_IGNORE
30 #define C_AST_UTIL_INLINE _GL_EXTERN_INLINE
31 /// @endcond
32 #include "c_ast_util.h"
33 #include "c_typedef.h"
34 #include "gibberish.h"
35 #include "literals.h"
36 #include "print.h"
37 
38 /// @cond DOXYGEN_IGNORE
39 
40 // standard
41 #include <assert.h>
42 
43 /// @endcond
44 
45 // local functions
46 PJL_WARN_UNUSED_RESULT
47 static c_ast_t* c_ast_append_array( c_ast_t*, c_ast_t*, c_ast_t* );
48 
49 ////////// local functions ////////////////////////////////////////////////////
50 
51 /**
52  * Adds an array to the AST being built.
53  *
54  * @param ast The AST to append to; may be NULL.
55  * @param array_ast The array AST to append.  Its `of_ast` must be of kind
56  * #K_PLACEHOLDER.
57  * @param of_ast The AST to become the `of_ast` of \a array_ast.
58  * @return Returns the AST to be used as the grammar production's return value.
59  */
60 PJL_WARN_UNUSED_RESULT
c_ast_add_array_impl(c_ast_t * ast,c_ast_t * array_ast,c_ast_t * of_ast)61 static c_ast_t* c_ast_add_array_impl( c_ast_t *ast, c_ast_t *array_ast,
62                                       c_ast_t *of_ast ) {
63   assert( array_ast != NULL );
64   assert( array_ast->kind == K_ARRAY );
65   assert( array_ast->as.array.of_ast != NULL );
66   assert( array_ast->as.array.of_ast->kind == K_PLACEHOLDER );
67   assert( of_ast != NULL );
68 
69   if ( ast == NULL )
70     return array_ast;
71 
72   switch ( ast->kind ) {
73     case K_ARRAY:
74       return c_ast_append_array( ast, array_ast, of_ast );
75 
76     case K_PLACEHOLDER:
77       //
78       // Before:
79       //
80       //      [array_ast]
81       //      [placeholder] --> [placeholder-parent]
82       //      [of_ast]
83       //
84       // After:
85       //
86       //      [of_ast] --> [array_ast] --> [placeholder-parent]
87       //
88       if ( ast->parent_ast != NULL )
89         c_ast_set_parent( array_ast, ast->parent_ast );
90       c_ast_set_parent( of_ast, array_ast );
91       return array_ast;
92 
93     case K_POINTER:
94       if ( ast->depth > array_ast->depth ) {
95         PJL_IGNORE_RV(
96           c_ast_add_array_impl( ast->as.ptr_ref.to_ast, array_ast, of_ast )
97         );
98         return ast;
99       }
100       PJL_FALLTHROUGH;
101 
102     default:
103       //
104       // An AST node's "depth" says how nested within () it is and controls the
105       // precedence of what is an array of what.
106       //
107       if ( ast->depth > array_ast->depth ) {
108         //
109         // Before:
110         //
111         //      [ast-child] --> [ast]
112         //      [array_ast]
113         //
114         // After:
115         //
116         //      [ast-child] --> [array_ast] --> [ast]
117         //
118         if ( c_ast_is_parent( ast ) )
119           c_ast_set_parent( ast->as.parent.of_ast, array_ast );
120         c_ast_set_parent( array_ast, ast );
121         return ast;
122       }
123       else {
124         //
125         // Before:
126         //
127         //      [ast] --> [ast-parent]
128         //      [array_ast]
129         //
130         // After:
131         //
132         //      [ast] --> [array_ast] --> [ast-parent]
133         //
134         if ( ast->parent_ast != NULL )
135           c_ast_set_parent( array_ast, ast->parent_ast );
136         c_ast_set_parent( ast, array_ast );
137         return array_ast;
138       }
139   } // switch
140 }
141 
142 /**
143  * If \a ast is:
144  *  + Not an array, makes \a array_ast an array of \a ast.
145  *  + An array, appends \a array_ast to the end of the array AST chain.
146  *
147  * For example, given:
148  *
149  *  + \a ast = `array 3 of array 5 of int`
150  *  + \a array_ast = `array 7 of NULL`
151  *
152  * this function returns:
153  *
154  *  + `array 3 of array 5 of array 7 of int`
155  *
156  * @param ast The AST to append to.
157  * @param array_ast The array AST to append.  Its `of_ast` must be of kind
158  * #K_PLACEHOLDER.
159  * @param of_ast The AST to become the `of_ast` of \a array_ast.
160  * @return If \a ast is an array, returns \a ast; otherwise returns \a
161  * array_ast.
162  */
163 PJL_WARN_UNUSED_RESULT
c_ast_append_array(c_ast_t * ast,c_ast_t * array_ast,c_ast_t * of_ast)164 static c_ast_t* c_ast_append_array( c_ast_t *ast, c_ast_t *array_ast,
165                                     c_ast_t *of_ast ) {
166   assert( ast != NULL );
167   assert( array_ast != NULL );
168   assert( array_ast->kind == K_ARRAY );
169   assert( array_ast->as.array.of_ast != NULL );
170   assert( array_ast->as.array.of_ast->kind == K_PLACEHOLDER );
171   assert( of_ast != NULL );
172 
173   switch ( ast->kind ) {
174     case K_POINTER:
175       //
176       // If there's an intervening pointer, e.g.:
177       //
178       //      type (*(*x)[3])[5]
179       //
180       // (where 'x' is a "pointer to array 3 of pointer to array 5 of int"), we
181       // have to recurse "through" it if its depth < the array's depth; else
182       // we'd end up with a "pointer to array 3 of array 5 of pointer to int."
183       //
184       if ( array_ast->depth >= ast->depth )
185         break;
186       PJL_FALLTHROUGH;
187 
188     case K_ARRAY: {
189       //
190       // On the next-to-last recursive call, this sets this array to be an
191       // array of the new array; for all prior recursive calls, it's a no-op.
192       //
193       c_ast_t *const temp_ast =
194         c_ast_append_array( ast->as.array.of_ast, array_ast, of_ast );
195       c_ast_set_parent( temp_ast, ast );
196       return ast;
197     }
198 
199     default:
200       /* suppress warning */;
201   } // switch
202 
203   //
204   // We've reached the end of the array chain: make the new array be an array
205   // of this AST node and return the array so the parent will now point to it
206   // instead.
207   //
208   c_ast_set_parent( ast, array_ast );
209   return array_ast;
210 }
211 
212 /**
213  * Adds a function-like AST to the AST being built.
214  *
215  * @param ast The AST to append to.
216  * @param func_ast The function-like AST to append.  Its `ret_ast` must be
217  * NULL.
218  * @param ret_ast The AST to become the `ret_ast` of \a func_ast.
219  * @return Returns the AST to be used as the grammar production's return value.
220  */
221 PJL_WARN_UNUSED_RESULT
c_ast_add_func_impl(c_ast_t * ast,c_ast_t * func_ast,c_ast_t * ret_ast)222 static c_ast_t* c_ast_add_func_impl( c_ast_t *ast, c_ast_t *func_ast,
223                                      c_ast_t *ret_ast ) {
224   assert( ast != NULL );
225   assert( func_ast != NULL );
226   assert( c_ast_is_kind_any( func_ast, K_ANY_FUNCTION_LIKE ) );
227   assert( func_ast->as.func.ret_ast == NULL );
228   assert( ret_ast != NULL );
229 
230   if ( c_ast_is_kind_any( ast, K_ARRAY | K_ANY_POINTER | K_ANY_REFERENCE ) ) {
231     switch ( ast->as.parent.of_ast->kind ) {
232       case K_ARRAY:
233       case K_POINTER:
234       case K_POINTER_TO_MEMBER:
235       case K_REFERENCE:
236       case K_RVALUE_REFERENCE:
237         if ( ast->depth > func_ast->depth ) {
238           PJL_IGNORE_RV(
239             c_ast_add_func_impl( ast->as.ptr_ref.to_ast, func_ast, ret_ast )
240           );
241           return ast;
242         }
243         PJL_FALLTHROUGH;
244 
245       default:
246         if ( ast->kind == K_ARRAY ) {
247           //
248           // Before:
249           //
250           //      [ast(K_ARRAY)] --> [of_ast]
251           //      [func_ast]
252           //
253           // After:
254           //
255           //      [ast(K_ARRAY)] --> [func_ast] --> [of_ast]
256           //
257           // Note that an array of function is illegal, but we still construct
258           // the AST properly and let c_ast_check_array() catch the error.
259           //
260           c_ast_set_parent( ast->as.array.of_ast, func_ast );
261           c_ast_set_parent( func_ast, ast );
262           return ast;
263         }
264         break;
265 
266       case K_PLACEHOLDER:
267         if ( ret_ast == ast )
268           break;
269         c_ast_set_parent( func_ast, ast );
270         PJL_FALLTHROUGH;
271 
272       case K_APPLE_BLOCK:
273         c_ast_set_parent( ret_ast, func_ast );
274         return ast;
275     } // switch
276   }
277 
278   c_ast_set_parent( ret_ast, func_ast );
279   return func_ast;
280 }
281 
282 /**
283  * Only if \a ast is a \ref K_POINTER, un-pointers \a ast.
284  *
285  * @param ast The AST to un-pointer.
286  * @param cv_stids If \a ast is a pointer, receives the `const` and `volatile`
287  * (cv) qualifiers (only) of the first pointed-to type.  For a declaration like
288  * <code>const&nbsp;S&nbsp;*x</code> (where `S` is a `struct`), the `const` is
289  * associated with the `typedef` for the `struct` and _not_ the actual `struct`
290  * the `typedef` is a `typedef` for:
291  * ```
292  * decl_c = {
293  *   sname = "x" (none),
294  *   kind = "pointer",
295  *   ...
296  *   type = "" (base = 0x1, store = 0x2, attr = 0x4),
297  *   to_ast = {
298  *     sname = "",
299  *     kind = "typedef",
300  *     ...
301  *     type = "const" (base = 0x10000001, store = 0x20000002, attr = 0x4),
302  *     for_ast = {
303  *       sname = "S" (struct),
304  *       kind = "enum, class, struct, or union",
305  *       ...
306  *       type = "struct" (base = 0x800001, store = 0x2, attr = 0x4),
307  *       ecsu_sname = "S" (none)
308  *     },
309  *     ...
310  *   }
311  * }
312  * ```
313  * Therefore, we need to copy the cv qualifiers of the `typedef` before we
314  * un-`typedef` it.
315  * @return Returns the pointed-to AST or NULL if \a ast is not a pointer.
316  *
317  * @sa c_ast_if_unreference()
318  * @sa c_ast_unpointer()
319  */
320 PJL_WARN_UNUSED_RESULT
c_ast_if_unpointer(c_ast_t const * ast,c_tid_t * cv_stids)321 static c_ast_t const* c_ast_if_unpointer( c_ast_t const *ast,
322                                           c_tid_t *cv_stids ) {
323   ast = c_ast_untypedef( ast );
324   if ( ast->kind != K_POINTER )
325     return NULL;
326 
327   ast = ast->as.ptr_ref.to_ast;
328   assert( ast != NULL );
329   assert( cv_stids != NULL );
330   *cv_stids = ast->type.stids & TS_CV;
331   //
332   // Now that we've gotten the cv qualifiers of the first pointed-to type, we
333   // can just call the ordinary c_ast_untypedef() to peel off any remaining
334   // typedef layers.
335   //
336   return c_ast_untypedef( ast );
337 }
338 
339 /**
340  * Only if \a ast is a \ref K_REFERENCE, un-references \a ast.
341  *
342  * @param ast The AST to un-reference.
343  * @param cv_stids If \a ast is a reference, receives the `const` and
344  * `volatile` (cv) qualifiers (only) of the first referred-to type.  For a
345  * declaration like <code>const&nbsp;S&nbsp;&x</code> (where `S` is a
346  * `struct`), the `const` is associated with the `typedef` for the `struct` and
347  * _not_ the actual `struct` the `typedef` is a `typedef` for:
348  * ```
349  * decl_c = {
350  *   sname = "x" (none),
351  *   kind = "reference",
352  *   ...
353  *   type = "" (base = 0x1, store = 0x2, attr = 0x4),
354  *   to_ast = {
355  *     sname = "",
356  *     kind = "typedef",
357  *     ...
358  *     type = "const" (base = 0x10000001, store = 0x20000002, attr = 0x4),
359  *     for_ast = {
360  *       sname = "S" (struct),
361  *       kind = "enum, class, struct, or union",
362  *       ...
363  *       type = "struct" (base = 0x800001, store = 0x2, attr = 0x4),
364  *       ecsu_sname = "S" (none)
365  *     },
366  *     bit_width = 0
367  *   }
368  * }
369  * ```
370  * Therefore, we need to copy the cv qualifiers of the `typedef` before we
371  * un-`typedef` it.
372  * @return Returns the referenced AST or NULL if \a ast is not a reference.
373  *
374  * @sa c_ast_if_unpointer()
375  * @sa c_ast_unreference()
376  */
377 PJL_WARN_UNUSED_RESULT
c_ast_if_unreference(c_ast_t const * ast,c_tid_t * cv_stids)378 static c_ast_t const* c_ast_if_unreference( c_ast_t const *ast,
379                                             c_tid_t *cv_stids ) {
380   ast = c_ast_untypedef( ast );
381   if ( ast->kind != K_REFERENCE )
382     return NULL;
383 
384   ast = ast->as.ptr_ref.to_ast;
385   assert( ast != NULL );
386   assert( cv_stids != NULL );
387   *cv_stids = ast->type.stids & TS_CV;
388   //
389   // Now that we've gotten the cv qualifiers of the first referred-to type, we
390   // can just call the ordinary c_ast_unreference() to peel off any remaining
391   // typedef/reference layers.
392   //
393   return c_ast_unreference( ast );
394 }
395 
396 /**
397  * Helper function that checks whether the type of \a ast is one of \a tids.
398  *
399  * @param ast The AST to check; may be NULL.
400  * @param ast_cv_stids The `const`/`volatiile` qualifier(s) of the `typedef`
401  * for \a ast, if any.
402  * @param tids The bitwise-or of type(s) to check against.
403  * @return If \a ast is not NULL and the type of \a ast is one of \a tids,
404  * returns \a ast; otherwise returns NULL.
405  */
406 PJL_WARN_UNUSED_RESULT
c_ast_is_tid_any_impl(c_ast_t const * ast,c_tid_t ast_cv_stids,c_tid_t tids)407 static c_ast_t const* c_ast_is_tid_any_impl( c_ast_t const *ast,
408                                              c_tid_t ast_cv_stids,
409                                              c_tid_t tids ) {
410   if ( ast != NULL ) {
411     c_tid_t ast_stids = c_type_get_tid( &ast->type, tids );
412     ast_stids = c_tid_normalize( ast_stids );
413     if ( c_tid_tpid( tids ) == C_TPID_STORE )
414       ast_stids |= ast_cv_stids;
415     if ( c_tid_is_any( ast_stids, tids ) )
416       return ast;
417   }
418   return NULL;
419 }
420 
421 /**
422  * Takes the storage (and attributes), if any, away from \a ast
423  * (with the intent of giving them to another AST).
424  * This is used is cases like:
425  * @code
426  *  explain static int f()
427  * @endcode
428  * that should be explained as:
429  * @code
430  *  declare f as static function () returning int
431  * @endcode
432  * and _not_:
433  * @code
434  *  declare f as function () returning static int
435  * @endcode
436  * i.e., the `static` has to be taken away from `int` and given to the function
437  * because it's the function that's `static`, not the `int`.
438  *
439  * @param ast The AST to take from.
440  * @return Returns said storage (and attributes) or \ref T_NONE.
441  */
442 PJL_WARN_UNUSED_RESULT
c_ast_take_storage(c_ast_t * ast)443 static c_type_t c_ast_take_storage( c_ast_t *ast ) {
444   assert( ast != NULL );
445   c_type_t rv_type = T_NONE;
446   c_ast_t *const found_ast =
447     c_ast_find_kind_any( ast, C_VISIT_DOWN, K_BUILTIN | K_TYPEDEF );
448   if ( found_ast != NULL ) {
449     rv_type.stids = found_ast->type.stids & TS_MASK_STORAGE;
450     rv_type.atids = found_ast->type.atids;
451     found_ast->type.stids &= c_tid_compl( TS_MASK_STORAGE );
452     found_ast->type.atids = TA_NONE;
453   }
454   return rv_type;
455 }
456 
457 /**
458  * A visitor function to find an AST node having a particular kind(s).
459  *
460  * @param ast The AST to check.
461  * @param v_data The bitwise-or of the kind(s) \a ast can be.
462  * @return Returns `true` only if the kind of \a ast is one of the kinds.
463  */
464 PJL_WARN_UNUSED_RESULT
c_ast_vistor_kind_any(c_ast_t * ast,c_ast_visit_data_t v_data)465 static bool c_ast_vistor_kind_any( c_ast_t *ast, c_ast_visit_data_t v_data ) {
466   assert( ast != NULL );
467   c_ast_kind_t const kinds = REINTERPRET_CAST( c_ast_kind_t, v_data );
468   return c_ast_is_kind_any( ast, kinds );
469 }
470 
471 /**
472  * A visitor function to find an AST node having a non-empty name.
473  *
474  * @param ast The AST to check.
475  * @param v_data Not used.
476  * @return Returns `true` only if \a ast has such a scoped name.
477  */
478 PJL_WARN_UNUSED_RESULT
c_ast_visitor_name(c_ast_t * ast,c_ast_visit_data_t v_data)479 static bool c_ast_visitor_name( c_ast_t *ast, c_ast_visit_data_t v_data ) {
480   assert( ast != NULL );
481   (void)v_data;
482   return !c_sname_empty( &ast->sname );
483 }
484 
485 /**
486  * A visitor function to find an AST node having a particular type(s).
487  *
488  * @param ast The AST to check.
489  * @param v_data A pointer to a type where each type part is the bitwise-or of
490  * type IDs to find.
491  * @return Returns `true` only if the type of \a ast is one of the types.
492  */
493 PJL_WARN_UNUSED_RESULT
c_ast_vistor_type_any(c_ast_t * ast,c_ast_visit_data_t v_data)494 static bool c_ast_vistor_type_any( c_ast_t *ast, c_ast_visit_data_t v_data ) {
495   assert( ast != NULL );
496   c_type_t const *const type = REINTERPRET_CAST( c_type_t*, v_data );
497   return c_type_is_any( &ast->type, type );
498 }
499 
500 ////////// extern functions ///////////////////////////////////////////////////
501 
c_ast_add_array(c_ast_t * ast,c_ast_t * array_ast,c_ast_t * of_ast)502 c_ast_t* c_ast_add_array( c_ast_t *ast, c_ast_t *array_ast, c_ast_t *of_ast ) {
503   assert( ast != NULL );
504   c_ast_t *const rv_ast = c_ast_add_array_impl( ast, array_ast, of_ast );
505   assert( rv_ast != NULL );
506   if ( c_sname_empty( &rv_ast->sname ) )
507     rv_ast->sname = c_ast_take_name( ast );
508   c_type_t const taken_type = c_ast_take_storage( array_ast->as.array.of_ast );
509   c_type_or_eq( &array_ast->type, &taken_type );
510   return rv_ast;
511 }
512 
c_ast_add_func(c_ast_t * ast,c_ast_t * func_ast,c_ast_t * ret_ast)513 c_ast_t* c_ast_add_func( c_ast_t *ast, c_ast_t *func_ast, c_ast_t *ret_ast ) {
514   c_ast_t *const rv_ast = c_ast_add_func_impl( ast, func_ast, ret_ast );
515   assert( rv_ast != NULL );
516   if ( c_sname_empty( &rv_ast->sname ) )
517     rv_ast->sname = c_ast_take_name( ast );
518   c_type_t const taken_type = c_ast_take_storage( func_ast->as.func.ret_ast );
519   c_type_or_eq( &rv_ast->type, &taken_type );
520   return rv_ast;
521 }
522 
c_ast_find_kind_any(c_ast_t * ast,c_visit_dir_t dir,c_ast_kind_t kinds)523 c_ast_t* c_ast_find_kind_any( c_ast_t *ast, c_visit_dir_t dir,
524                               c_ast_kind_t kinds ) {
525   assert( kinds != 0 );
526   c_ast_visit_data_t const v_data =
527     REINTERPRET_CAST( c_ast_visit_data_t, kinds );
528   return c_ast_visit( ast, dir, c_ast_vistor_kind_any, v_data );
529 }
530 
c_ast_find_name(c_ast_t const * ast,c_visit_dir_t dir)531 c_sname_t* c_ast_find_name( c_ast_t const *ast, c_visit_dir_t dir ) {
532   c_ast_t *const found_ast =
533     c_ast_visit( CONST_CAST( c_ast_t*, ast ), dir, c_ast_visitor_name, 0 );
534   return found_ast != NULL ? &found_ast->sname : NULL;
535 }
536 
c_ast_find_type_any(c_ast_t * ast,c_visit_dir_t dir,c_type_t const * type)537 c_ast_t* c_ast_find_type_any( c_ast_t *ast, c_visit_dir_t dir,
538                               c_type_t const *type ) {
539   c_ast_visit_data_t const v_data =
540     REINTERPRET_CAST( c_ast_visit_data_t, type );
541   return c_ast_visit( ast, dir, c_ast_vistor_type_any, v_data );
542 }
543 
c_ast_is_builtin_any(c_ast_t const * ast,c_tid_t btids)544 bool c_ast_is_builtin_any( c_ast_t const *ast, c_tid_t btids ) {
545   assert( ast != NULL );
546   assert( c_tid_tpid( btids ) == C_TPID_BASE );
547 
548   ast = c_ast_untypedef( ast );
549   if ( ast->kind != K_BUILTIN )
550     return false;
551   c_tid_t const ast_btids = c_tid_normalize( ast->type.btids );
552   return only_bits_set( ast_btids, btids );
553 }
554 
c_ast_is_ptr_to_kind(c_ast_t const * ast,c_ast_kind_t kind)555 bool c_ast_is_ptr_to_kind( c_ast_t const *ast, c_ast_kind_t kind ) {
556   assert( ast != NULL );
557   ast = c_ast_unpointer( ast );
558   return ast != NULL && ast->kind == kind;
559 }
560 
c_ast_is_ptr_to_type_any(c_ast_t const * ast,c_type_t const * mask_type,c_type_t const * type)561 bool c_ast_is_ptr_to_type_any( c_ast_t const *ast, c_type_t const *mask_type,
562                                c_type_t const *type ) {
563   assert( mask_type != NULL );
564 
565   c_tid_t cv_stids;
566   ast = c_ast_if_unpointer( ast, &cv_stids );
567   if ( ast == NULL )
568     return false;
569   c_type_t const masked_type = {
570     c_tid_normalize( ast->type.btids ) & mask_type->btids,
571     (ast->type.stids | cv_stids)       & mask_type->stids,
572     ast->type.atids                    & mask_type->atids
573   };
574   return c_type_is_any( &masked_type, type );
575 }
576 
c_ast_is_ptr_to_tid_any(c_ast_t const * ast,c_tid_t tids)577 c_ast_t const* c_ast_is_ptr_to_tid_any( c_ast_t const *ast, c_tid_t tids ) {
578   c_tid_t cv_stids;
579   ast = c_ast_if_unpointer( ast, &cv_stids );
580   return c_ast_is_tid_any_impl( ast, cv_stids, tids );
581 }
582 
c_ast_is_ref_to_class_sname(c_ast_t const * ast,c_sname_t const * sname)583 bool c_ast_is_ref_to_class_sname( c_ast_t const *ast, c_sname_t const *sname ) {
584   ast = c_ast_is_ref_to_tid_any( ast, TB_ANY_CLASS );
585   if ( ast == NULL )
586     return false;
587   return  c_sname_cmp( &ast->sname, sname ) == 0 ||
588           c_sname_cmp( &ast->as.ecsu.ecsu_sname, sname ) == 0;
589 }
590 
c_ast_is_ref_to_tid_any(c_ast_t const * ast,c_tid_t tids)591 c_ast_t const* c_ast_is_ref_to_tid_any( c_ast_t const *ast, c_tid_t tids ) {
592   c_tid_t cv_stids;
593   ast = c_ast_if_unreference( ast, &cv_stids );
594   return c_ast_is_tid_any_impl( ast, cv_stids, tids );
595 }
596 
c_ast_is_ref_to_type_any(c_ast_t const * ast,c_type_t const * type)597 c_ast_t const* c_ast_is_ref_to_type_any( c_ast_t const *ast,
598                                          c_type_t const *type ) {
599   c_tid_t cv_stids;
600   ast = c_ast_if_unreference( ast, &cv_stids );
601   if ( ast == NULL )
602     return NULL;
603 
604   c_type_t const ast_cv_type = {
605     c_tid_normalize( ast->type.btids ),
606     ast->type.stids | cv_stids,
607     ast->type.atids
608   };
609 
610   return c_type_is_any( &ast_cv_type, type ) ? ast : NULL;
611 }
612 
c_ast_is_tid_any(c_ast_t const * ast,c_tid_t tids)613 c_ast_t const* c_ast_is_tid_any( c_ast_t const *ast, c_tid_t tids ) {
614   ast = c_ast_untypedef( ast );
615   return c_ast_is_tid_any_impl( ast, TS_NONE, tids );
616 }
617 
c_ast_is_typename_ok(c_ast_t const * ast)618 bool c_ast_is_typename_ok( c_ast_t const *ast ) {
619   assert( ast != NULL );
620 
621   c_sname_t const *const sname = ast->kind == K_TYPEDEF ?
622     &ast->as.tdef.for_ast->sname :
623     &ast->sname;
624 
625   if ( c_sname_count( sname ) < 2 ) {
626     print_error( &ast->loc,
627       "qualified name expected after \"%s\"\n", L_TYPENAME
628     );
629     return false;
630   }
631   return true;
632 }
633 
c_ast_join_type_decl(bool has_typename,c_alignas_t const * align,c_ast_t * type_ast,c_ast_t * decl_ast)634 c_ast_t* c_ast_join_type_decl( bool has_typename, c_alignas_t const *align,
635                                c_ast_t *type_ast, c_ast_t *decl_ast ) {
636   assert( type_ast != NULL );
637   assert( decl_ast != NULL );
638 
639   if ( has_typename && !c_ast_is_typename_ok( type_ast ) )
640     return NULL;
641 
642   c_type_t type = c_ast_take_type_any( type_ast, &T_TS_TYPEDEF );
643 
644   if ( c_type_is_tid_any( &type, TS_TYPEDEF ) &&
645        decl_ast->kind == K_TYPEDEF ) {
646     //
647     // This is for a case like:
648     //
649     //      explain typedef int int32_t;
650     //
651     // that is: explaining an existing typedef.  In order to do that, we have
652     // to un-typedef it so we explain the type that it's typedef'd as.
653     //
654     decl_ast = CONST_CAST( c_ast_t*, c_ast_untypedef( decl_ast ) );
655 
656     //
657     // However, we also have to check whether the typedef being explained is
658     // not equivalent to the existing typedef.  This is for a case like:
659     //
660     //      explain typedef char int32_t;
661     //
662     if ( !c_ast_equal( type_ast, decl_ast ) ) {
663       print_error( &decl_ast->loc,
664         "\"%s\": \"%s\" redefinition with different type; original is: ",
665         c_sname_full_name( &decl_ast->sname ), L_TYPEDEF
666       );
667       //
668       // When printing the existing type in C/C++ as part of an error message,
669       // we always want to omit the trailing semicolon.
670       //
671       bool const orig_semicolon = opt_semicolon;
672       opt_semicolon = false;
673 
674       c_typedef_t const temp_tdef = { decl_ast, LANG_ANY, false, false };
675       c_typedef_gibberish( &temp_tdef, C_GIB_TYPEDEF, stderr );
676 
677       opt_semicolon = orig_semicolon;
678       return NULL;
679     }
680   }
681 
682   c_ast_t *const ast = c_ast_patch_placeholder( type_ast, decl_ast );
683   c_type_t const type2 = c_ast_take_type_any( ast, &T_TS_TYPEDEF );
684   c_type_or_eq( &type, &type2 );
685   c_type_or_eq( &ast->type, &type );
686 
687   if ( align != NULL && align->kind != C_ALIGNAS_NONE ) {
688     ast->align = *align;
689     if ( c_type_is_tid_any( &type, TS_TYPEDEF ) ) {
690       //
691       // We check for illegal aligned typedef here rather than in errors.c
692       // because the "typedef-ness" needed to be removed previously before the
693       // eventual call to c_ast_check().
694       //
695       print_error( &align->loc, "%s can not be %s\n", L_TYPEDEF, L_ALIGNED );
696       return NULL;
697     }
698   }
699 
700   if ( ast->kind == K_USER_DEF_CONVERSION &&
701        c_sname_local_type( &ast->sname )->btids == TB_SCOPE ) {
702     //
703     // User-defined conversions don't have names, but they can still have a
704     // scope.  Since only classes can have them, if the scope is still
705     // TB_SCOPE, change it to TB_CLASS.
706     //
707     c_sname_set_local_type( &ast->sname, &C_TYPE_LIT_B( TB_CLASS ) );
708   }
709 
710   return ast;
711 }
712 
c_ast_oper_overload(c_ast_t const * ast)713 unsigned c_ast_oper_overload( c_ast_t const *ast ) {
714   assert( ast != NULL );
715   assert( ast->kind == K_OPERATOR );
716 
717   //
718   // If the operator is either member or non-member only, then it's that.
719   //
720   c_operator_t const *const op = c_oper_get( ast->as.oper.oper_id );
721   unsigned const op_overload_flags = op->flags & C_OP_MASK_OVERLOAD;
722   switch ( op_overload_flags ) {
723     case C_OP_MEMBER:
724     case C_OP_NON_MEMBER:
725     case C_OP_NOT_OVERLOADABLE:
726       return op_overload_flags;
727   } // switch
728 
729   //
730   // Otherwise, the operator can be either: see if the user specified which one
731   // explicitly.
732   //
733   unsigned const user_overload_flags = ast->as.oper.flags & C_OP_MASK_OVERLOAD;
734   switch ( user_overload_flags ) {
735     case C_OP_MEMBER:
736     case C_OP_NON_MEMBER:
737       return user_overload_flags;
738   } // switch
739 
740   //
741   // The user didn't specify either member or non-member explicitly: see if it
742   // has a member-only type qualifier.
743   //
744   if ( c_type_is_tid_any( &ast->type, TS_MEMBER_FUNC_ONLY ) )
745     return C_OP_MEMBER;
746 
747   size_t const n_params = c_ast_params_count( ast );
748 
749   switch ( ast->as.oper.oper_id ) {
750     case C_OP_NEW:
751     case C_OP_NEW_ARRAY:
752     case C_OP_DELETE:
753     case C_OP_DELETE_ARRAY:
754       //
755       // Special case for new and delete operators: they're member operators if
756       // they have a name (of a class) or declared static.
757       //
758       return  !c_sname_empty( &ast->sname ) ||
759               c_type_is_tid_any( &ast->type, TS_STATIC ) ?
760         C_OP_MEMBER : C_OP_NON_MEMBER;
761 
762     case C_OP_MINUS2:
763     case C_OP_PLUS2:
764       //
765       // Special case for ++ and -- operators: if the number of parameters is:
766       //
767       //  0. Member.
768       //  1. If the type of the argument is int, member; else, non-member.
769       //  2. Non-member.
770       //
771       if ( n_params == 1 ) {
772         c_ast_t const *const param_ast = c_param_ast( c_ast_params( ast ) );
773         return c_ast_is_builtin_any( param_ast, TB_INT ) ?
774           C_OP_MEMBER : C_OP_NON_MEMBER;
775       }
776       // The 0 and 2 cases are handled below.
777       break;
778 
779     default:
780       /* suppress warning */;
781   } // switch
782 
783   //
784   // Try to infer whether it's a member or non-member based on the number of
785   // parameters given.
786   //
787   if ( n_params == op->params_min )
788     return C_OP_MEMBER;
789   if ( n_params == op->params_max )
790     return C_OP_NON_MEMBER;
791 
792   //
793   // We can't determine which one, so give up.
794   //
795   return C_OP_UNSPECIFIED;
796 }
797 
c_ast_patch_placeholder(c_ast_t * type_ast,c_ast_t * decl_ast)798 c_ast_t* c_ast_patch_placeholder( c_ast_t *type_ast, c_ast_t *decl_ast ) {
799   assert( type_ast != NULL );
800   if ( decl_ast == NULL )
801     return type_ast;
802 
803   if ( type_ast->parent_ast == NULL ) {
804     c_ast_t *const placeholder_ast =
805       c_ast_find_kind_any( decl_ast, C_VISIT_DOWN, K_PLACEHOLDER );
806     if ( placeholder_ast != NULL ) {
807       if ( type_ast->depth >= decl_ast->depth ) {
808         //
809         // The type_ast is the final AST -- decl_ast (containing a placeholder)
810         // is discarded.
811         //
812         if ( c_sname_empty( &type_ast->sname ) )
813           type_ast->sname = c_ast_take_name( decl_ast );
814         return type_ast;
815       }
816       //
817       // Otherwise, excise the K_PLACEHOLDER.
818       // Before:
819       //
820       //      [type_ast] --> ... --> [type_root_ast]
821       //      [placeholder] --> [placeholder-parent]
822       //
823       // After:
824       //
825       //      [type_ast] --> ... --> [type_root_ast] --> [placeholder-parent]
826       //
827       c_ast_t *const type_root_ast = c_ast_root( type_ast );
828       c_ast_set_parent( type_root_ast, placeholder_ast->parent_ast );
829     }
830   }
831 
832   //
833   // The decl_ast is the final AST -- type_ast may be discarded (if it wasn't
834   // patched in), so take its storage, attributes, and name (if it doesn't have
835   // one already).
836   //
837   c_type_t const taken_type = c_ast_take_storage( type_ast );
838   decl_ast->type.stids |= taken_type.stids;
839   decl_ast->type.atids |= taken_type.atids;
840 
841   if ( c_sname_empty( &decl_ast->sname ) )
842     decl_ast->sname = c_ast_take_name( type_ast );
843 
844   return decl_ast;
845 }
846 
c_ast_pointer(c_ast_t * ast,c_ast_list_t * ast_list)847 c_ast_t* c_ast_pointer( c_ast_t *ast, c_ast_list_t *ast_list ) {
848   assert( ast != NULL );
849   c_ast_t *const ptr_ast =
850     c_ast_new( K_POINTER, ast->depth, &ast->loc, ast_list );
851   ptr_ast->sname = c_ast_take_name( ast );
852   c_ast_set_parent( ast, ptr_ast );
853   return ptr_ast;
854 }
855 
c_ast_root(c_ast_t * ast)856 c_ast_t* c_ast_root( c_ast_t *ast ) {
857   assert( ast != NULL );
858   while ( ast->parent_ast != NULL )
859     ast = ast->parent_ast;
860   return ast;
861 }
862 
c_ast_take_name(c_ast_t * ast)863 c_sname_t c_ast_take_name( c_ast_t *ast ) {
864   assert( ast != NULL );
865   c_sname_t *const found_sname = c_ast_find_name( ast, C_VISIT_DOWN );
866   c_sname_t rv_sname;
867   if ( found_sname == NULL ) {
868     c_sname_init( &rv_sname );
869   } else {
870     rv_sname = *found_sname;
871     c_sname_init( found_sname );
872   }
873   return rv_sname;
874 }
875 
c_ast_take_type_any(c_ast_t * ast,c_type_t const * type)876 c_type_t c_ast_take_type_any( c_ast_t *ast, c_type_t const *type ) {
877   assert( ast != NULL );
878   assert( type != NULL );
879   c_ast_t *const found_ast = c_ast_find_type_any( ast, C_VISIT_DOWN, type );
880   if ( found_ast == NULL )
881     return T_NONE;
882   c_type_t const rv_type = c_type_and( &found_ast->type, type );
883   c_type_and_eq_compl( &found_ast->type, type );
884   return rv_type;
885 }
886 
c_ast_unpointer(c_ast_t const * ast)887 c_ast_t const* c_ast_unpointer( c_ast_t const *ast ) {
888   ast = c_ast_untypedef( ast );
889   return  ast->kind == K_POINTER ?
890           c_ast_untypedef( ast->as.ptr_ref.to_ast ) : NULL;
891 }
892 
c_ast_unreference(c_ast_t const * ast)893 c_ast_t const* c_ast_unreference( c_ast_t const *ast ) {
894   // This is a loop to implement the reference-collapsing rule.
895   for (;;) {
896     ast = c_ast_untypedef( ast );
897     if ( ast->kind != K_REFERENCE )
898       return ast;
899     ast = ast->as.ptr_ref.to_ast;
900   } // for
901 }
902 
c_ast_unrvalue_reference(c_ast_t const * ast)903 c_ast_t const* c_ast_unrvalue_reference( c_ast_t const *ast ) {
904   // This is a loop to implement the reference-collapsing rule.
905   for (;;) {
906     ast = c_ast_untypedef( ast );
907     if ( ast->kind != K_RVALUE_REFERENCE )
908       return ast;
909     ast = ast->as.ptr_ref.to_ast;
910   } // for
911 }
912 
c_ast_untypedef(c_ast_t const * ast)913 c_ast_t const* c_ast_untypedef( c_ast_t const *ast ) {
914   for (;;) {
915     assert( ast != NULL );
916     if ( ast->kind != K_TYPEDEF )
917       return ast;
918     ast = ast->as.tdef.for_ast;
919   } // for
920 }
921 
922 ///////////////////////////////////////////////////////////////////////////////
923 /* vim:set et sw=2 ts=2: */
924