1 /*
2 **      cdecl -- C gibberish translator
3 **      src/c_type.h
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 #ifndef cdecl_c_type_H
22 #define cdecl_c_type_H
23 
24 /**
25  * @file
26  * Declares constants, types, and functions for C/C++ types.
27  */
28 
29 // local
30 #include "pjl_config.h"                 /* must go first */
31 #include "cdecl.h"
32 #include "c_lang.h"
33 #include "options.h"
34 #include "types.h"
35 #include "util.h"
36 
37 /// @cond DOXYGEN_IGNORE
38 
39 // standard
40 #include <assert.h>
41 #include <stdbool.h>
42 #include <inttypes.h>                   /* for PRIX64, etc. */
43 
44 _GL_INLINE_HEADER_BEGIN
45 #ifndef C_TYPE_INLINE
46 # define C_TYPE_INLINE _GL_INLINE
47 #endif /* C_TYPE_INLINE */
48 
49 /// @endcond
50 
51 /**
52  * @defgroup c-types-group C/C++ Types
53  * Constants, types, and functions for C/C++ types.
54  * @{
55  */
56 
57 ////////// types //////////////////////////////////////////////////////////////
58 
59 /**
60  * The C/C++ type of an identifier (variable, function, etc.). A type is split
61  * into parts because the number of distinct bits needed in total exceeds 64.
62  */
63 struct c_type {
64   /**
65    * The base types (`int`, `double`, etc.) including user-defined types
66    * (`enum`, `struct`, etc.), modifiers (`short`, `unsigned`, etc.), and also
67    * `namespace` and the generic `scope` since it makes sense to store those
68    * with other scope-types (like `struct`).
69    *
70    * Constants for base types begin with `TB_`.
71    */
72   c_tid_t btids;
73 
74   /**
75    * The storage classes (`extern`, `static`, etc., including `typedef`),
76    * storage-class-like things (`default`, `friend`, `inline`, etc.), and also
77    * qualifiers (`_Atomic`, `const`, etc.) and ref-qualifiers (`&`, `&&`).
78    *
79    * Constants for storage-class-like things begin with `TS_`.
80    */
81   c_tid_t stids;
82 
83   /**
84    * Attributes.
85    *
86    * Constants for attributes begin with `TA_`.
87    */
88   c_tid_t atids;
89 };
90 
91 /**
92  * Convenience macro for specifying a complete \ref c_type literal.
93  *
94  * @param BTID The base \ref c_tid_t.
95  * @param STID The storage \ref c_tid_t.
96  * @param ATID The attribute(s) \ref c_tid_t.
97  * @return Returns a reference to said literal.
98  *
99  * @sa #C_TYPE_LIT_A()
100  * @sa #C_TYPE_LIT_A_ANY()
101  * @sa #C_TYPE_LIT_B()
102  * @sa #C_TYPE_LIT_B_ANY()
103  * @sa #C_TYPE_LIT_S()
104  * @sa #C_TYPE_LIT_S_ANY()
105  */
106 #define C_TYPE_LIT(BTID,STID,ATID) \
107   (c_type_t const){ (BTID), (STID), (ATID) }
108 
109 /**
110  * Convenience macro for specifying a \ref c_type literal from \a ATID.
111  *
112  * @param ATID The attribute(s) \ref c_tid_t.
113  * @return Returns a reference to said literal.
114  *
115  * @sa #C_TYPE_LIT()
116  * @sa #C_TYPE_LIT_A_ANY()
117  * @sa #C_TYPE_LIT_B()
118  * @sa #C_TYPE_LIT_B_ANY()
119  * @sa #C_TYPE_LIT_S()
120  * @sa #C_TYPE_LIT_S_ANY()
121  */
122 #define C_TYPE_LIT_A(ATID) \
123   C_TYPE_LIT( TB_NONE, TS_NONE, (ATID) )
124 
125 /**
126  * Convenience macro for specifying a \ref c_type literal from #TB_ANY,
127  * #TS_ANY, and \a ATID.
128  *
129  * @param ATID The attribute(s) \ref c_tid_t.
130  * @return Returns a reference to said literal.
131  *
132  * @sa #C_TYPE_LIT()
133  * @sa #C_TYPE_LIT_A()
134  * @sa #C_TYPE_LIT_B()
135  * @sa #C_TYPE_LIT_B_ANY()
136  * @sa #C_TYPE_LIT_S()
137  * @sa #C_TYPE_LIT_S_ANY()
138  */
139 #define C_TYPE_LIT_A_ANY(ATID) \
140   C_TYPE_LIT( TB_ANY, TS_ANY, (ATID) )
141 
142 /**
143  * Convenience macro for specifying a \ref c_type literal from \a BTID.
144  *
145  * @param BTID The base \ref c_tid_t.
146  * @return Returns a reference to said literal.
147  *
148  * @sa #C_TYPE_LIT()
149  * @sa #C_TYPE_LIT_A()
150  * @sa #C_TYPE_LIT_S()
151  */
152 #define C_TYPE_LIT_B(BTID) \
153   C_TYPE_LIT( (BTID), TS_NONE, TA_NONE )
154 
155 /**
156  * Convenience macro for specifying a \ref c_type literal from \a BTID,
157  * #TS_ANY, and #TA_ANY.
158  *
159  * @param BTID The base \ref c_tid_t.
160  * @return Returns a reference to said literal.
161  *
162  * @sa #C_TYPE_LIT()
163  * @sa #C_TYPE_LIT_A()
164  * @sa #C_TYPE_LIT_A_ANY()
165  * @sa #C_TYPE_LIT_B()
166  * @sa #C_TYPE_LIT_S()
167  * @sa #C_TYPE_LIT_S_ANY()
168  */
169 #define C_TYPE_LIT_B_ANY(BTID) \
170   C_TYPE_LIT( (BTID), TS_ANY, TA_ANY )
171 
172 /**
173  * Convenience macro for specifying a \ref c_type literal from \a STID.
174  *
175  * @param STID The storage \ref c_tid_t.
176  * @return Returns a reference to said literal.
177  *
178  * @sa #C_TYPE_LIT()
179  * @sa #C_TYPE_LIT_A()
180  * @sa #C_TYPE_LIT_A_ANY()
181  * @sa #C_TYPE_LIT_B()
182  * @sa #C_TYPE_LIT_B_ANY()
183  * @sa #C_TYPE_LIT_S_ANY()
184  */
185 #define C_TYPE_LIT_S(STID) \
186   C_TYPE_LIT( TB_NONE, (STID), TA_NONE )
187 
188 /**
189  * Convenience macro for specifying a \ref c_type literal from #TB_ANY, \a
190  * STID, and #TA_ANY.
191  *
192  * @param STID The storage \ref c_tid_t.
193  * @return Returns a reference to said literal.
194  *
195  * @sa #C_TYPE_LIT()
196  * @sa #C_TYPE_LIT_A()
197  * @sa #C_TYPE_LIT_A_ANY()
198  * @sa #C_TYPE_LIT_B()
199  * @sa #C_TYPE_LIT_B_ANY()
200  * @sa #C_TYPE_LIT_S()
201  */
202 #define C_TYPE_LIT_S_ANY(STID) \
203   C_TYPE_LIT( TB_ANY, (STID), TA_ANY )
204 
205 /**
206  * For \ref c_tid_t values, the low-order 4 bits specify the \ref c_tpid and
207  * thus how the value should be interpreted.
208  */
209 enum c_tpid {
210   //
211   // Type part IDs start at 1 so we know a c_tid_t value has been initialized
212   // properly as opposed to it being 0 by default.
213   //
214   C_TPID_NONE   = 0u,                   ///< No types.
215   C_TPID_BASE   = (1u << 0),            ///< Base types, e.g., `int`.
216   C_TPID_STORE  = (1u << 1),            ///< Storage types, e.g., `static`.
217   C_TPID_ATTR   = (1u << 2)             ///< Attributes.
218 };
219 
220 //
221 // The difference between TB_TYPEDEF and TS_TYPEDEF is that:
222 //
223 //  * TS_TYPEDEF is the "storage class" for a declaration as a whole while it's
224 //    being declared during parsing.
225 //
226 //  * TB_TYPEDEF is the "type" for a particular typedef'd type, e.g., size_t,
227 //    after parsing a declaration and the new type has been defined.  Hence,
228 //    TB_TYPEDEF is the somewhat unnecessary when the kind of an AST is
229 //    K_TYPEDEF, but it has to have some type.
230 //
231 
232 #define TX_NONE               0x0000000000000000ull /**< No type at all.      */
233 
234 // base types & modifiers
235 #define TB_NONE               0x0000000000000001ull /**< No base type.        */
236 #define TB_ANY                0xFFFFFFFFFFFFFFF1ull /**< Any base type.       */
237 #define TB_VOID               0x0000000000000011ull /**< `void`               */
238 #define TB_AUTO               0x0000000000000021ull /**< C++11's `auto`.      */
239 #define TB_BOOL               0x0000000000000041ull /**< `_Bool` or `bool`    */
240 #define TB_CHAR               0x0000000000000081ull /**< `char`               */
241 #define TB_CHAR8_T            0x0000000000000101ull /**< `char8_t`            */
242 #define TB_CHAR16_T           0x0000000000000201ull /**< `char16_t`           */
243 #define TB_CHAR32_T           0x0000000000000401ull /**< `char32_t`           */
244 #define TB_WCHAR_T            0x0000000000000801ull /**< `wchar_t`            */
245 #define TB_SHORT              0x0000000000001001ull /**< `short`              */
246 #define TB_INT                0x0000000000002001ull /**< `int`                */
247 #define TB_LONG               0x0000000000004001ull /**< `long`               */
248 #define TB_LONG_LONG          0x0000000000008001ull /**< `long long`          */
249 #define TB_SIGNED             0x0000000000010001ull /**< `signed`             */
250 #define TB_UNSIGNED           0x0000000000020001ull /**< `unsigned`           */
251 #define TB_FLOAT              0x0000000000040001ull /**< `float`              */
252 #define TB_DOUBLE             0x0000000000080001ull /**< `double`             */
253 #define TB_COMPLEX            0x0000000000100001ull /**< `_Complex`           */
254 #define TB_IMAGINARY          0x0000000000200001ull /**< `_Imaginary`         */
255 #define TB_ENUM               0x0000000000400001ull /**< `enum`               */
256 #define TB_STRUCT             0x0000000000800001ull /**< `struct`             */
257 #define TB_UNION              0x0000000001000001ull /**< `union`              */
258 #define TB_CLASS              0x0000000002000001ull /**< `class`              */
259 #define TB_NAMESPACE          0x0000000004000001ull /**< `namespace`          */
260 #define TB_SCOPE              0x0000000008000001ull /**< Generic scope.       */
261 #define TB_TYPEDEF            0x0000000010000001ull /**< E.g., `size_t`       */
262 
263 // Embedded C types & modifiers
264 #define TB_EMC_ACCUM          0x0000000020000001ull /**< `_Accum`             */
265 #define TB_EMC_FRACT          0x0000000040000001ull /**< `_Fract`             */
266 #define TB_EMC_SAT            0x0000000080000001ull /**< `_Sat`               */
267 
268 // storage classes
269 #define TS_NONE               0x0000000000000002ull /**< No storage type.     */
270 #define TS_ANY                0xFFFFFFFFFFFFFFF2ull /**< Any storage type.    */
271 #define TS_AUTO               0x0000000000000012ull /**< C's `auto`.          */
272 #define TS_APPLE_BLOCK        0x0000000000000022ull /**< Block.               */
273 #define TS_EXTERN             0x0000000000000042ull /**< `extern`             */
274 #define TS_EXTERN_C           0x0000000000000082ull /**< `extern "C"`         */
275 #define TS_MUTABLE            0x0000000000000102ull /**< `mutable`            */
276 #define TS_REGISTER           0x0000000000000202ull /**< `register`           */
277 #define TS_STATIC             0x0000000000000402ull /**< `static`             */
278 #define TS_THREAD_LOCAL       0x0000000000000802ull /**< `thread_local`       */
279 #define TS_TYPEDEF            0x0000000000001002ull /**< `typedef` or `using` */
280 
281 // storage-class-like
282 #define TS_CONSTEVAL          0x0000000000002002ull /**< `consteval`          */
283 #define TS_CONSTEXPR          0x0000000000004002ull /**< `constexpr`          */
284 #define TS_CONSTINIT          0x0000000000008002ull /**< `constinit`          */
285 #define TS_DEFAULT            0x0000000000010002ull /**< `= default`          */
286 #define TS_DELETE             0x0000000000020002ull /**< `= delete`           */
287 #define TS_EXPLICIT           0x0000000000040002ull /**< `explicit`           */
288 #define TS_EXPORT             0x0000000000080002ull /**< `export`             */
289 #define TS_FINAL              0x0000000000100002ull /**< `final`              */
290 #define TS_FRIEND             0x0000000000200002ull /**< `friend`             */
291 #define TS_INLINE             0x0000000000400002ull /**< `inline`             */
292 #define TS_NOEXCEPT           0x0000000000800002ull /**< `noexcept`           */
293 #define TS_OVERRIDE           0x0000000001000002ull /**< `override`           */
294 #define TS_PURE_VIRTUAL       0x0000000002000002ull /**< `= 0`                */
295 #define TS_THROW              0x0000000004000002ull /**< `throw()`            */
296 #define TS_VIRTUAL            0x0000000008000002ull /**< `virtual`            */
297 
298 // qualifiers
299 #define TS_ATOMIC             0x0000000010000002ull /**< `_Atomic`            */
300 #define TS_CONST              0x0000000020000002ull /**< `const`              */
301 #define TS_RESTRICT           0x0000000040000002ull /**< `restrict`           */
302 #define TS_VOLATILE           0x0000000080000002ull /**< `volatile`           */
303 
304 // Unified Parallel C qualifiers
305 #define TS_UPC_RELAXED        0x0000000100000002ull /**< `relaxed`            */
306 #define TS_UPC_SHARED         0x0000000200000002ull /**< `shared`             */
307 #define TS_UPC_STRICT         0x0000000400000002ull /**< `strict`             */
308 
309 // ref-qualifiers
310 #define TS_REFERENCE          0x0000000800000002ull /**< `void f() &`         */
311 #define TS_RVALUE_REFERENCE   0x0000001000000002ull /**< `void f() &&`        */
312 
313 // attributes
314 #define TA_NONE               0x0000000000000004ull /**< No attribute.        */
315 #define TA_ANY                0xFFFFFFFFFFFFFFF4ull /**< Any attribute.       */
316 #define TA_CARRIES_DEPENDENCY 0x0000000000000014ull /**< `carries_dependency` */
317 #define TA_DEPRECATED         0x0000000000000024ull /**< `deprecated`         */
318 #define TA_MAYBE_UNUSED       0x0000000000000044ull /**< `maybe_unused`       */
319 #define TA_NODISCARD          0x0000000000000084ull /**< `nodiscard`          */
320 #define TA_NORETURN           0x0000000000000104ull /**< `noreturn`           */
321 #define TA_NO_UNIQUE_ADDRESS  0x0000000000000204ull /**< `no_unique_address`  */
322 
323 // Microsoft calling conventions
324 #define TA_MSC_CDECL          0x0000000000001004ull /**< `__cdecl`            */
325 #define TA_MSC_CLRCALL        0x0000000000002004ull /**< `__clrcall`          */
326 #define TA_MSC_FASTCALL       0x0000000000004004ull /**< `__fastcall`         */
327 #define TA_MSC_STDCALL        0x0000000000008004ull /**< `__stdcall`          */
328 #define TA_MSC_THISCALL       0x0000000000010004ull /**< `__thiscall`         */
329 #define TA_MSC_VECTORCALL     0x0000000000020004ull /**< `__vectorcall`       */
330 
331 // bit masks
332 #define TX_MASK_TPID          0x000000000000000Full /**< Type part ID bitmask.*/
333 #define TS_MASK_STORAGE       0x000000000FFFFFF2ull /**< Storage bitmask.     */
334 #define TS_MASK_QUALIFIER     0x00000007F0000002ull /**< Qualifier bitmask.   */
335 #define TS_MASK_REF_QUALIFIER 0x0000001800000002ull /**< Ref-qual bitmask.    */
336 
337 extern c_type_t const T_NONE;           ///< No type.
338 extern c_type_t const T_ANY;            ///< All types.
339 extern c_type_t const T_ANY_CONST_CLASS;///< Any `const` `class`-like type.
340 extern c_type_t const T_TS_TYPEDEF;     ///< Type containing only #TS_TYPEDEF.
341 
342 // shorthands
343 
344 /// Shorthand for any character type.
345 #define TB_ANY_CHAR           ( TB_CHAR | TB_WCHAR_T \
346                               | TB_CHAR8_T | TB_CHAR16_T | TB_CHAR32_T )
347 
348 /// Shorthand for `class`, `struct`, or `union`.
349 #define TB_ANY_CLASS          ( TB_CLASS | TB_STRUCT | TB_UNION )
350 
351 /// Shorthand for any Embedded C type.
352 #define TB_ANY_EMC            ( TB_EMC_ACCUM | TB_EMC_FRACT )
353 
354 /// Shorthand for any floating-point type.
355 #define TB_ANY_FLOAT          ( TB_FLOAT | TB_DOUBLE )
356 
357 /// Shorthand for any integral type.
358 #define TB_ANY_INTEGRAL       ( TB_BOOL | TB_ANY_CHAR | TB_INT \
359                               | TB_ANY_MODIFIER )
360 
361 /// Shorthand for an any modifier.
362 #define TB_ANY_MODIFIER       ( TB_SHORT | TB_LONG | TB_LONG_LONG | TB_SIGNED \
363                               | TB_UNSIGNED )
364 
365 /// Shorthand for any Microsoft C/C++ calling convention.
366 #define TA_ANY_MSC_CALL       ( TA_MSC_CDECL | TA_MSC_CLRCALL \
367                               | TA_MSC_FASTCALL | TA_MSC_STDCALL \
368                               | TA_MSC_THISCALL | TA_MSC_VECTORCALL )
369 
370 /// Shorthand for `class`, `struct`, `union`, or `namespace`.
371 #define TB_ANY_SCOPE          ( TB_ANY_CLASS | TB_NAMESPACE )
372 
373 /// Shorthand for any reference qualifier.
374 #define TS_ANY_REFERENCE      ( TS_REFERENCE | TS_RVALUE_REFERENCE )
375 
376 /// Shorthand for `const` or `volatile`.
377 #define TS_CV                 ( TS_CONST | TS_VOLATILE )
378 
379 /// Shorthand for `const`, `volatile`, or `restrict`.
380 #define TS_CVR                ( TS_CV | TS_RESTRICT )
381 
382 /**
383  * The only types that can apply to in-class constructor declarations.
384  *
385  * @sa #TS_CONSTRUCTOR_DEF
386  * @sa #TS_CONSTRUCTOR_ONLY
387  * @sa #TS_FUNC_LIKE_CPP
388  */
389 #define TS_CONSTRUCTOR_DECL   ( TS_CONSTEXPR | TS_DEFAULT | TS_DELETE \
390                               | TS_EXPLICIT | TS_FRIEND | TS_INLINE \
391                               | TS_NOEXCEPT | TS_THROW )
392 
393 /**
394  * A subset of #TS_CONSTRUCTOR_DECL that can apply to file-scope constructor
395  * definitions.
396  *
397  * @sa #TS_CONSTRUCTOR_DECL
398  */
399 #define TS_CONSTRUCTOR_DEF    ( TS_CONSTEXPR | TS_INLINE | TS_NOEXCEPT \
400                               | TS_THROW )
401 
402 /**
403  * The types that can apply only to constructors.
404  *
405  * @sa #TS_CONSTRUCTOR_DECL
406  * @sa #TS_CONSTRUCTOR_DEF
407  */
408 #define TS_CONSTRUCTOR_ONLY   TS_EXPLICIT
409 
410 /**
411  * The only types that can apply to in-class destructor declarations.
412  *
413  * @sa #TS_CONSTRUCTOR_DECL
414  * @sa #TS_DESTRUCTOR_DEF
415  */
416 #define TS_DESTRUCTOR_DECL    ( TS_DEFAULT | TS_DELETE | TS_FINAL | TS_FRIEND \
417                               | TS_INLINE | TS_NOEXCEPT | TS_OVERRIDE \
418                               | TS_PURE_VIRTUAL | TS_THROW | TS_VIRTUAL )
419 
420 /**
421  * A subset of #TS_DESTRUCTOR_DECL that can apply to file-scope destructor
422  * definitions.
423  *
424  * @sa #TS_DESTRUCTOR_DECL
425  */
426 #define TS_DESTRUCTOR_DEF     ( TS_INLINE | TS_NOEXCEPT | TS_THROW )
427 
428 /**
429  * The only storage-types that can apply to C functions.
430  *
431  * @sa #TS_FUNC_LIKE_CPP
432  * @sa #TS_MAIN_FUNC_C
433  */
434 #define TS_FUNC_C             ( TS_EXTERN | TS_INLINE | TS_STATIC | TS_TYPEDEF )
435 
436 /**
437  * The only storage-types that can apply to C++ function-like things
438  * (functions, blocks, constructors, destructors, operators, and user-defined
439  * conversion operators and literals).
440  *
441  * @sa #TS_CONSTRUCTOR_DECL
442  * @sa #TS_CONSTRUCTOR_DEF
443  * @sa #TS_MAIN_FUNC_CPP
444  * @sa #TS_NEW_DELETE_OPER
445  * @sa #TS_USER_DEF_CONV
446  */
447 #define TS_FUNC_LIKE_CPP      ( TS_CV | TS_CONSTEVAL | TS_CONSTEXPR \
448                               | TS_DEFAULT | TS_DELETE | TS_EXPLICIT \
449                               | TS_EXPORT | TS_EXTERN_C | TS_FINAL \
450                               | TS_FRIEND | TS_FUNC_C | TS_NOEXCEPT \
451                               | TS_OVERRIDE | TS_PURE_VIRTUAL \
452                               | TS_ANY_REFERENCE | TS_RESTRICT | TS_THROW \
453                               | TS_TYPEDEF | TS_VIRTUAL )
454 
455 /**
456  * The only storage types that can apply to a C program's `main()` function.
457  *
458  * @sa #TS_FUNC_C
459  * @sa #TS_MAIN_FUNC_CPP
460  */
461 #define TS_MAIN_FUNC_C        TS_EXTERN
462 
463 /**
464  * The only types that can apply to a C++ program's `main()` function.
465  *
466  * @sa #TS_FUNC_LIKE_CPP
467  * @sa #TS_MAIN_FUNC_C
468  */
469 #define TS_MAIN_FUNC_CPP      ( TS_EXTERN | TS_FRIEND | TS_NOEXCEPT | TS_THROW )
470 
471 /**
472  * The types that can apply only to member functions, operators, or user-
473  * defined conversions operators.
474  *
475  * @sa #TS_FUNC_LIKE_CPP
476  * @sa #TS_NONMEMBER_FUNC_ONLY
477  */
478 #define TS_MEMBER_FUNC_ONLY   ( TS_CV \
479                               | (opt_lang < LANG_CPP_20 ? TS_DEFAULT : TS_NONE)\
480                               | TS_DELETE | TS_FINAL | TS_OVERRIDE \
481                               | TS_ANY_REFERENCE | TS_RESTRICT | TS_VIRTUAL )
482 
483 /**
484  * The only types that can apply to operators `new`, `new[]`, `delete`, or
485  * `delete[]`.
486  *
487  * @sa #TS_FUNC_LIKE_CPP
488  */
489 #define TS_NEW_DELETE_OPER    ( TS_EXTERN | TS_FRIEND | TS_NOEXCEPT \
490                               | TS_STATIC | TS_THROW )
491 
492 /**
493  * The types that can apply only to non-member functions or operators.
494  *
495  * @sa #TS_MEMBER_FUNC_ONLY
496  */
497 #define TS_NONMEMBER_FUNC_ONLY TS_FRIEND
498 
499 /**
500  * The types that can apply only to function-like things except constructors.
501  *
502  * @sa #TS_CONSTRUCTOR_DECL
503  * @sa #TS_CONSTRUCTOR_DEF
504  * @sa #TS_CONSTRUCTOR_ONLY
505  * @sa #TS_FUNC_LIKE_CPP
506  */
507 #define TS_NOT_CONSTRUCTOR    ( TS_CV | TS_EXTERN | TS_EXTERN_C | TS_FINAL \
508                               | TS_OVERRIDE | TS_ANY_REFERENCE | TS_RESTRICT \
509                               | TS_STATIC | TS_VIRTUAL )
510 
511 /**
512  * The only types that can apply to user-defined conversion operators.
513  *
514  * @sa #TS_FUNC_LIKE_CPP
515  */
516 #define TS_USER_DEF_CONV      ( TS_CONST | TS_CONSTEXPR | TS_EXPLICIT \
517                               | TS_FINAL | TS_FRIEND | TS_INLINE \
518                               | TS_NOEXCEPT | TS_OVERRIDE | TS_PURE_VIRTUAL \
519                               | TS_THROW | TS_VIRTUAL )
520 
521 /**
522  * Hexadecimal print conversion specifier for \ref c_tid_t.
523  */
524 #define PRIX_C_TID_T          PRIX64
525 
526 ////////// extern functions ///////////////////////////////////////////////////
527 
528 /**
529  * Adds a type to an existing type, e.g., `short` to `int`, ensuring that a
530  * particular type is never added more than once, e.g., `short` to `short int`.
531  *
532  * A special case has to be made for `long` to allow for `long long` yet not
533  * allow for `long long long`.
534  *
535  * @param dst_tids The \ref c_tid_t to add to.
536  * @param new_tids The \ref c_tid_t to add.
537  * @param new_loc The source location of \a new_id.
538  * @return Returns `true` only if the type added successfully.
539  *
540  * @sa c_type_add(()
541  */
542 PJL_WARN_UNUSED_RESULT
543 bool c_tid_add( c_tid_t *dst_tids, c_tid_t new_tids, c_loc_t const *new_loc );
544 
545 /**
546  * Gets the C/C++ name of \a tids.
547  *
548  * @param tids The \ref c_tid_t to get the name of.
549  * @return Returns said name.
550  *
551  * @warning The pointer returned is to a small number of static buffers, so you
552  * can't do something like call this more than twice in the same `printf()`
553  * statement.
554  *
555  * @sa c_tid_name_english()
556  * @sa c_tid_name_error()
557  * @sa c_type_name_c()
558  */
559 PJL_WARN_UNUSED_RESULT
560 char const* c_tid_name_c( c_tid_t tids );
561 
562 /**
563  * Gets the pseudo-English name of \a tids, if available; the C/C++ name if
564  * not.
565  *
566  * @param tids The \ref c_tid_t to get the name of.
567  * @return Returns said name.
568  *
569  * @warning The pointer returned is to a small number of static buffers, so you
570  * can't do something like call this more than twice in the same `printf()`
571  * statement.
572  *
573  * @sa c_tid_name_c()
574  * @sa c_tid_name_error()
575  * @sa c_type_name_english()
576  */
577 PJL_WARN_UNUSED_RESULT
578 char const* c_tid_name_english( c_tid_t tids );
579 
580 /**
581  * Gets the name of \a tids for part of an error message.  If translating from
582  * pseudo-English to gibberish and the type has an pseudo-English alias, return
583  * the alias, e.g., `non-returning` rather than `noreturn`.
584  *
585  * @param tids The \ref c_tid_t to get the name of.
586  * @return Returns said name.
587  *
588  * @warning The pointer returned is to a small number of static buffers, so you
589  * can't do something like call this more than twice in the same `printf()`
590  * statement.
591  *
592  * @sa c_tid_name_c()
593  * @sa c_tid_name_english()
594  * @sa c_type_name_error()
595  */
596 PJL_WARN_UNUSED_RESULT
597 char const* c_tid_name_error( c_tid_t tids );
598 
599 /**
600  * "Normalize" \a tids:
601  *
602  *  1. If it's #TB_SIGNED and not #TB_CHAR, remove #TB_SIGNED.  If it becomes
603  *     #TB_NONE, make it #TB_INT.
604  *  2. If it's only implicitly #TB_INT (e.g., `unsigned`), make it explicitly
605  *     #TB_INT (e.g., `unsigned int`).
606  *
607  * @param tids The \ref c_tid_t to normalize.
608  * @return Returns the normalized \ref c_tid_t.
609  */
610 PJL_WARN_UNUSED_RESULT
611 c_tid_t c_tid_normalize( c_tid_t tids );
612 
613 /**
614  * Gets the "order" value of a \ref c_tid_t so it can be compared by its order.
615  * The order is:
616  *
617  * + { _none_ | `scope` }  &lt; [`inline`] `namespace` &lt;
618  *   { `struct` | `union` | `class` } &lt;
619  *   `enum` [`class`]
620  *
621  * I.e., the order of T1 &le; T2 only if T1 can appear to the left (&lt;) of T2
622  * in a declaration.  For example, given:
623  * ```
624  *  namespace N { class C { // ...
625  * ```
626  * order(`N`) &le; order(`C`) because `N` can appear to the left of `C` in a
627  * declaration.  However, given:
628  * ```
629  *  class D { namespace M { // ...
630  * ```
631  * order(`D`) &gt; order(`M`) and so `D` can not appear to the left of `M`.
632  *
633  * @param btids The scope-type ID to get the order of.
634  * @return Returns said order.
635  *
636  * @note The return value by itself is meaningless.  All that matters is the
637  * result of comparing two orders.
638  */
639 PJL_WARN_UNUSED_RESULT
640 unsigned c_tid_scope_order( c_tid_t btids );
641 
642 /**
643  * Gets the \ref c_tpid_t from \a tids.
644  *
645  * @param tids The type ID.
646  * @return Returns said \ref c_tpid_t.
647  *
648  * @sa c_tid_no_tpid()
649  */
650 PJL_WARN_UNUSED_RESULT
651 c_tpid_t c_tid_tpid( c_tid_t tids );
652 
653 /**
654  * Adds a type to an existing type, e.g., `short` to `int`, ensuring that a
655  * particular type is never added more than once, e.g., `short` to `short int`.
656  *
657  * A special case has to be made for `long` to allow for `long long` yet not
658  * allow for `long long long`.
659  *
660  * @param dst_type The \ref c_type to add to.
661  * @param new_type The \ref c_type to add.
662  * @param new_loc The source location of \a new_type.
663  * @return Returns `true` only if \a new_type added successfully.
664  *
665  * @sa c_tid_add(()
666  * @sa c_type_add_tid()
667  * @sa c_type_or_eq()
668  */
669 PJL_WARN_UNUSED_RESULT
670 bool c_type_add( c_type_t *dst_type, c_type_t const *new_type,
671                  c_loc_t const *new_loc );
672 
673 /**
674  * Adds \a new_tids to \a dst_type.
675  *
676  * @param dst_type The \ref c_type to add to.
677  * @param new_tids The \ref c_tid_t to add.
678  * @param new_loc The source location of \a new_tids.
679  * @return Returns `true` only if \a new_tids added successfully.
680  *
681  * @sa c_type_add()
682  */
683 PJL_WARN_UNUSED_RESULT
684 bool c_type_add_tid( c_type_t *dst_type, c_tid_t new_tids,
685                      c_loc_t const *new_loc );
686 
687 /**
688  * Performs the bitwise-and of all the parts of \a i_type and \a j_type.
689  *
690  * @param i_type The first \ref c_type.
691  * @param j_type The second \ref c_type.
692  * @return Returns the resultant \ref c_type.
693  *
694  * @sa c_type_and_eq_compl()
695  * @sa c_type_or()
696  */
697 PJL_WARN_UNUSED_RESULT
698 c_type_t c_type_and( c_type_t const *i_type, c_type_t const *j_type );
699 
700 /**
701  * Performs the bitwise-and of all the parts of \a dst_type with the complement
702  * of \a rm_type and stores the result in \a dst_type.
703  *
704  * @param dst_type The type to modify.
705  * @param rm_type The type to remove from \a dst_type.
706  *
707  * @sa c_type_or_eq()
708  */
709 void c_type_and_eq_compl( c_type_t *dst_type, c_type_t const *rm_type );
710 
711 /**
712  * Checks that \a type is valid.
713  *
714  * @param type The \ref c_type to check.
715  * @return Returns the bitwise-or of the language(s) \a type is legal in.
716  */
717 PJL_WARN_UNUSED_RESULT
718 c_lang_id_t c_type_check( c_type_t const *type );
719 
720 /**
721  * Checks whether \a i_type and \a j_type are equal.
722  *
723  * @param i_type The first \ref c_type.
724  * @param j_type The second \ref c_type.
725  * @return Returns `true` only if \a i_type equals \a j_type.
726  *
727  * @sa c_type_is_none()
728  */
729 PJL_WARN_UNUSED_RESULT
730 bool c_type_equal( c_type_t const *i_type, c_type_t const *j_type );
731 
732 /**
733  * Creates a \ref c_type based on the type part ID of \a tids.
734  *
735  * @param tids The \ref c_tid_t to create the \ref c_type from.
736  * @return Returns said \ref c_type.
737  */
738 PJL_WARN_UNUSED_RESULT
739 c_type_t c_type_from_tid( c_tid_t tids );
740 
741 /**
742  * Gets the \ref c_tid_t of \a type that corresponds to the type part ID of \a
743  * tids.
744  *
745  * @param type The \ref c_type to get the relevant \ref c_tid_t of.
746  * @param tids The \ref c_tid_t that specifies the part of \a type to get the
747  * pointer to.
748  * @return Returns the corresponding \ref c_tid_t of \a type for the part of \a
749  * tids.
750  *
751  * @sa c_type_get_tid_ptr()
752  */
753 PJL_WARN_UNUSED_RESULT
754 c_tid_t c_type_get_tid( c_type_t const *type, c_tid_t tids );
755 
756 /**
757  * Gets a pointer to the \ref c_tid_t of \a type that corresponds to the type
758  * part ID of \a tids.
759  *
760  * @param type The \ref c_type to get a pointer to the relevant \ref c_tid_t
761  * of.
762  * @param tids The \ref c_tid_t that specifies the part of \a type to get the
763  * pointer to.
764  * @return Returns a pointer to the corresponding \ref c_tid_t of \a type for
765  * the part of \a tids.
766  *
767  * @sa c_type_get_tid()
768  */
769 PJL_WARN_UNUSED_RESULT
770 c_tid_t* c_type_get_tid_ptr( c_type_t *type, c_tid_t tids );
771 
772 /**
773  * For all type part IDs of \a j_type that are not none, gets whether the
774  * corresponding type part ID of \a i_type is any of them.
775  *
776  * @param i_type The first \ref c_type.
777  * @param j_type The second \ref c_type.
778  * @return Returns `true` only if \a i_type contains any \a j_type.
779  *
780  * @sa c_tid_is_any()
781  */
782 PJL_WARN_UNUSED_RESULT
783 bool c_type_is_any( c_type_t const *i_type, c_type_t const *j_type );
784 
785 /**
786  * Gets the C/C++ name of \a type.
787  *
788  * @param type The type to get the name for.
789  * @return Returns said name.
790  *
791  * @warning The pointer returned is to a small number of static buffers, so you
792  * can't do something like call this more than twice in the same `printf()`
793  * statement.
794  *
795  * @sa c_tid_name_c()
796  * @sa c_type_name_ecsu()
797  * @sa c_type_name_english()
798  * @sa c_type_name_error()
799  */
800 PJL_WARN_UNUSED_RESULT
801 char const* c_type_name_c( c_type_t const *type );
802 
803 /**
804  * Gets the the C/C++ name for an `enum`, `struct`, `class`, or `union`.
805  *
806  * @param type The type to get the name for.
807  * @return Returns said name.
808  *
809  * @warning The pointer returned is to a small number of static buffers, so you
810  * can't do something like call this more than twice in the same `printf()`
811  * statement.
812  *
813  * @sa c_type_name_c()
814  * @sa c_type_name_english()
815  * @sa c_type_name_error()
816  */
817 PJL_WARN_UNUSED_RESULT
818 char const* c_type_name_ecsu( c_type_t const *type );
819 
820 /**
821  * Gets the pseudo-English name of \a type, if available; the C/C++ name if
822  * not.
823  *
824  * @param type The type to get the name for.
825  * @return Returns said name.
826  *
827  * @warning The pointer returned is to a small number of static buffers, so you
828  * can't do something like call this more than twice in the same `printf()`
829  * statement.
830  *
831  * @sa c_tid_name_error()
832  * @sa c_type_name_c()
833  * @sa c_type_name_ecsu()
834  * @sa c_type_name_error()
835  */
836 PJL_WARN_UNUSED_RESULT
837 char const* c_type_name_english( c_type_t const *type );
838 
839 /**
840  * Gets the name of \a type for part of an error message.  If translating
841  * from pseudo-English to gibberish and the type has a pseudo-English alias,
842  * return the alias, e.g., `non-returning` rather than `noreturn`.
843  *
844  * @param type The type to get the name for.
845  * @return Returns said name.
846  *
847  * @warning The pointer returned is to a small number of static buffers, so you
848  * can't do something like call this more than twice in the same `printf()`
849  * statement.
850  *
851  * @sa c_type_name_c()
852  * @sa c_type_name_ecsu()
853  * @sa c_type_name_english()
854  */
855 PJL_WARN_UNUSED_RESULT
856 char const* c_type_name_error( c_type_t const *type );
857 
858 /**
859  * Performs the bitwise-or of \a i_type and \a j_type.
860  *
861  * @param i_type The first type.
862  * @param j_type The second type.
863  * @return Returns the bitwise-or of \a i_type and \a j_type.
864  *
865  * @sa c_type_and()
866  * @sa c_type_and_eq_compl()
867  * @sa c_type_or_eq()
868  */
869 PJL_WARN_UNUSED_RESULT
870 c_type_t c_type_or( c_type_t const *i_type, c_type_t const *j_type );
871 
872 /**
873  * Performs the bitwise-or of \a dst_type with \a add_type and stores the
874  * result in \a dst_type.
875  * @note Unlike c_type_add(), no checks are made.
876  *
877  * @param dst_type The type to modify.
878  * @param add_type The source type.
879  *
880  * @sa c_type_add()
881  * @sa c_type_and_eq_compl()
882  * @sa c_type_or()
883  */
884 void c_type_or_eq( c_type_t *dst_type, c_type_t const *add_type );
885 
886 ////////// inline functions ///////////////////////////////////////////////////
887 
888 /**
889  * Checks that the type part ID of \a tids is \a tpid.
890  *
891  * @param tids The \ref c_tid_t to check.
892  * @param tpid The \ref c_tpid_t to check against.
893  * @return Returns \a tids.
894  */
895 C_TYPE_INLINE PJL_NOWARN_UNUSED_RESULT
c_tid_check(c_tid_t tids,c_tpid_t tpid)896 c_tid_t c_tid_check( c_tid_t tids, c_tpid_t tpid ) {
897   assert( (tids & TX_MASK_TPID) == tpid );
898   return tids;
899 }
900 
901 /**
902  * Checks whether \a tids has been complemented via `~`.
903  *
904  * @param tids The \ref c_tid_t to check.
905  * @return Returns `true` only if \a tids has been complemented.
906  *
907  * @sa c_tid_compl()
908  */
909 C_TYPE_INLINE PJL_WARN_UNUSED_RESULT
c_tid_is_compl(c_tid_t tids)910 bool c_tid_is_compl( c_tid_t tids ) {
911   //
912   // The low-order 4 bits specify the c_tpid.  Currently, type part IDs are 1
913   // (0b0001), 2 (0b0010), and 4 (0b0100).  If tids is 0b1xxx, it means that it
914   // was complemented.
915   //
916   return (tids & 0x8) != 0;
917 }
918 
919 /**
920  * Bitwise-complements \a tids.  The `~` operator can't be used alone because
921  * the part ID of \a tids would be complemented also.  This function
922  * complements \a tids while preserving the original part ID.
923  *
924  * @param tids The \ref c_tid_t to complement.
925  * @return Returns \a tids complemented.
926  *
927  * @sa c_tid_is_compl()
928  */
929 C_TYPE_INLINE PJL_WARN_UNUSED_RESULT
c_tid_compl(c_tid_t tids)930 c_tid_t c_tid_compl( c_tid_t tids ) {
931   assert( !c_tid_is_compl( tids ) );
932   return ~tids ^ TX_MASK_TPID;
933 }
934 
935 /**
936  * Checks whether \a tids is all of \a is_tids but not also any one of \a
937  * except_tids.
938  *
939  * @param tids The \ref c_tid_t to check.
940  * @param is_tids The bitwise-or of \ref c_tid_t to check for.
941  * @param except_tids The bitwise-or of \ref c_tid_t to exclude.
942  * @return Returns `true` only if \a tids contains any of \a is_tids, but not
943  * any of \a except_tids.
944  */
945 C_TYPE_INLINE PJL_WARN_UNUSED_RESULT
c_tid_is_except(c_tid_t tids,c_tid_t is_tids,c_tid_t except_tids)946 bool c_tid_is_except( c_tid_t tids, c_tid_t is_tids, c_tid_t except_tids ) {
947   return (tids & (is_tids | except_tids)) == is_tids;
948 }
949 
950 /**
951  * Gets the type ID value without the part ID.
952  *
953  * @param tids The \ref c_tid_t to get the value of.
954  * @return Returns the type ID value without the part ID.
955  *
956  * @sa c_tid_tpid()
957  */
958 C_TYPE_INLINE PJL_WARN_UNUSED_RESULT
c_tid_no_tpid(c_tid_t tids)959 c_tid_t c_tid_no_tpid( c_tid_t tids ) {
960   return tids & ~TX_MASK_TPID;
961 }
962 
963 /**
964  * Gets whether \a i_tids contains any of \a j_tids.
965  *
966  * @param i_tids The first \ref c_tid_t.
967  * @param j_tids The second \ref c_tid_t.
968  * @return Returns `true` only if \a i_tids contains any \a j_tids.
969  *
970  * @sa c_type_is_any()
971  */
972 C_TYPE_INLINE PJL_WARN_UNUSED_RESULT
c_tid_is_any(c_tid_t i_tids,c_tid_t j_tids)973 bool c_tid_is_any( c_tid_t i_tids, c_tid_t j_tids ) {
974   assert( c_tid_tpid( i_tids ) == c_tid_tpid( j_tids ) );
975   return c_tid_no_tpid( i_tids & j_tids ) != TX_NONE;
976 }
977 
978 /**
979  * Checks whether \a tids is "none."
980  *
981  * @note This function is useful only when the part ID of \a tids can be any
982  * part ID.
983  * @param tids The \ref c_tid_t to check.
984  * @return Returns `true` only if \a tids is `Tx_NONE`.
985  *
986  * @sa c_type_is_none()
987  */
988 C_TYPE_INLINE PJL_WARN_UNUSED_RESULT
c_tid_is_none(c_tid_t tids)989 bool c_tid_is_none( c_tid_t tids ) {
990   return c_tid_no_tpid( tids ) == TX_NONE;
991 }
992 
993 /**
994  * Checks if \a tids is equivalent to `size_t`.
995  *
996  * @note
997  * In cdecl, `size_t` is `typedef`d to be `unsigned long` in `c_typedef.c`.
998  *
999  * @param tids The \ref c_tid_t to check.
1000  * @return Returns `true` only if \a tids is `size_t`.
1001  *
1002  * @sa c_ast_is_size_t()
1003  */
1004 C_TYPE_INLINE PJL_WARN_UNUSED_RESULT
c_tid_is_size_t(c_tid_t tids)1005 bool c_tid_is_size_t( c_tid_t tids ) {
1006   assert( (tids & TX_MASK_TPID) == C_TPID_BASE );
1007   return (tids & c_tid_compl( TB_INT )) == (TB_UNSIGNED | TB_LONG);
1008 }
1009 
1010 /**
1011  * Checks whether \a type is T_NONE.
1012  *
1013  * @param type The \ref c_type to check.
1014  * @return Returns `true` only if \a type is none.
1015  *
1016  * @sa c_type_equal()
1017  */
1018 C_TYPE_INLINE PJL_WARN_UNUSED_RESULT
c_type_is_none(c_type_t const * type)1019 bool c_type_is_none( c_type_t const *type ) {
1020   return c_type_equal( type, &T_NONE );
1021 }
1022 
1023 /**
1024  * Checks whether the relevant \ref c_tid_t of \a type is any of \a tids.
1025  *
1026  * @param type The \ref c_type to check.
1027  * @param tids The \ref c_tid_t to check against.
1028  * @return Returns `true` only if the relevant \ref c_tid_t of \a type contains
1029  * any of \a tids.
1030  */
1031 C_TYPE_INLINE PJL_WARN_UNUSED_RESULT
c_type_is_tid_any(c_type_t const * type,c_tid_t tids)1032 bool c_type_is_tid_any( c_type_t const *type, c_tid_t tids ) {
1033   return c_tid_is_any( c_type_get_tid( type, tids ), tids );
1034 }
1035 
1036 ///////////////////////////////////////////////////////////////////////////////
1037 
1038 /** @} */
1039 
1040 _GL_INLINE_HEADER_END
1041 
1042 #endif /* cdecl_c_type_H */
1043 /* vim:set et sw=2 ts=2: */
1044