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 S *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 S &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