1 /*
2 **      cdecl -- C gibberish translator
3 **      src/c_kind.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_kind_H
22 #define cdecl_c_kind_H
23 
24 /**
25  * @file
26  * Declares types and functions for kinds of things in C/C++ declarations.
27  */
28 
29 // local
30 #include "pjl_config.h"                 /* must go first */
31 #include "types.h"
32 
33 /**
34  * @defgroup c-kinds-group C/C++ Declaration Kinds
35  * Types and functions for kinds of things in C/C++ declarations.
36  * @{
37  */
38 
39 /**
40  * Shorthand for use inside a `switch` statement on an AST's kind to assert
41  * that it's not #K_PLACEHOLDER because it shouldn't occur in a completed AST.
42  * For example:
43  *
44  *      switch ( ast->kind ) {
45  *        // ...
46  *
47  *        CASE_K_PLACEHOLDER;
48  *      }
49  */
50 #define CASE_K_PLACEHOLDER  \
51   case K_PLACEHOLDER:       \
52     assert( 0 );            \
53     break
54 
55 ///////////////////////////////////////////////////////////////////////////////
56 
57 /**
58  * Kinds of things comprising a C/C++ declaration.
59  *
60  * A given thing may only have a single kind and _not_ be a bitwise-or of
61  * kinds.  However, a bitwise-or of kinds may be used to test whether a given
62  * thing is any _one_ of those kinds.
63  */
64 enum c_ast_kind {
65   /**
66    * Temporary node in AST.  This is needed in two cases:
67    *
68    * 1. Array declarations or casts.  Consider:
69    *
70    *         int a[2][3]
71    *
72    *    At the first `[`, we know it's an "array 2 [of something]* of int," but
73    *    we don't yet know whether the "something" will turn out to be nothing.
74    *    It's not until the second `[` that we know it's an "array 2 of array 3
75    *    of int."  (Had the `[3]` not been there, then it would have been just
76    *    "array 2 of int.")
77    *
78    * 2. Nested declarations or casts (inside parentheses).  Consider:
79    *
80    *         int (*a)[2]
81    *
82    *    At the `*`, we know it's a "pointer [to something]* of int," but,
83    *    similar to the array case, we don't yet know whether the "something"
84    *    will turn out to be nothing.  It's not until the `[` that we know it's
85    *    a "pointer to array 2 of int."  (Had the `[2]` not been there, then it
86    *    would have been just "pointer to int" (with unnecessary parentheses).
87    *
88    * In either case, a placeholder node is created to hold the place of the
89    * "something" in the AST.
90    */
91   K_PLACEHOLDER             = (1u << 0),
92 
93   /**
94    * Built-in type, e.g., `void`, `char`, `int`, etc.
95    */
96   K_BUILTIN                 = (1u << 1),
97 
98   /**
99    * Name only.  It's used as the initial kind for an identifier ("name") until
100    * we know its actual type (if ever).  However, it's also used for pre-
101    * prototype typeless function parameters in K&R C, e.g., `double sin(x)`.
102    */
103   K_NAME                    = (1u << 2),
104 
105   /**
106    * `typedef` type, e.g., `size_t`.
107    */
108   K_TYPEDEF                 = (1u << 3),
109 
110   /**
111    * Variadic (`...`) function parameter.
112    */
113   K_VARIADIC                = (1u << 4),
114 
115   ////////// "parent" kinds ///////////////////////////////////////////////////
116 
117   /**
118    * Array.
119    */
120   K_ARRAY                   = (1u << 5),
121 
122   /**
123    * An `enum,` `class,` `struct,` or `union`.
124    *
125    * @note This is a "parent" kind because `enum` in C++11 and later can be
126    * "of" a fixed type.
127    */
128   K_ENUM_CLASS_STRUCT_UNION = (1u << 6),
129 
130   /**
131    * C or C++ pointer.
132    */
133   K_POINTER                 = (1u << 7),
134 
135   /**
136    * C++ pointer-to-member.
137    */
138   K_POINTER_TO_MEMBER       = (1u << 8),
139 
140   /**
141    * C++ reference.
142    */
143   K_REFERENCE               = (1u << 9),
144 
145   /**
146    * C++11 rvalue reference.
147    */
148   K_RVALUE_REFERENCE        = (1u << 10),
149 
150   ////////// function-like "parent" kinds /////////////////////////////////////
151 
152   /**
153    * C++ constructor.
154    */
155   K_CONSTRUCTOR             = (1u << 11),
156 
157   /**
158    * C++ destructor.
159    */
160   K_DESTRUCTOR              = (1u << 12),
161 
162   ////////// function-like "parent" kinds that have return values /////////////
163 
164   /**
165    * Block (Apple extension).
166    *
167    * @sa [Apple's Extensions to C](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1370.pdf)
168    * @sa [Blocks Programming Topics](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Blocks)
169    */
170   K_APPLE_BLOCK             = (1u << 13),
171 
172   /**
173    * Function.
174    */
175   K_FUNCTION                = (1u << 14),
176 
177   /**
178    * C++ overloaded operator.
179    */
180   K_OPERATOR                = (1u << 15),
181 
182   /**
183    * C++ user-defined conversion operator.
184    */
185   K_USER_DEF_CONVERSION     = (1u << 16),
186 
187   /**
188    * C++11 user-defined literal.
189    */
190   K_USER_DEF_LITERAL        = (1u << 17),
191 };
192 
193 /**
194  * Shorthand for any kind of function-like AST: #K_APPLE_BLOCK, #K_CONSTRUCTOR,
195  * #K_DESTRUCTOR, #K_FUNCTION, #K_OPERATOR, #K_USER_DEF_CONVERSION, or
196  * #K_USER_DEF_LITERAL.
197  */
198 #define K_ANY_FUNCTION_LIKE   ( K_APPLE_BLOCK | K_CONSTRUCTOR | K_DESTRUCTOR \
199                               | K_FUNCTION | K_OPERATOR \
200                               | K_USER_DEF_CONVERSION | K_USER_DEF_LITERAL )
201 
202 /**
203  * Shorthand for any kind of "object" that can be the type of a variable or
204  * constant, i.e., something to which `sizeof` can be applied: #K_ARRAY,
205  * #K_BUILTIN, #K_ENUM_CLASS_STRUCT_UNION, #K_POINTER, #K_POINTER_TO_MEMBER,
206  * #K_REFERENCE, #K_RVALUE_REFERENCE, or #K_TYPEDEF.
207  */
208 #define K_ANY_OBJECT          ( K_ANY_POINTER | K_ANY_REFERENCE | K_ARRAY \
209                               | K_BUILTIN | K_ENUM_CLASS_STRUCT_UNION \
210                               | K_TYPEDEF )
211 
212 /**
213  * Shorthand for any kind of parent: #K_APPLE_BLOCK, #K_ARRAY, #K_CONSTRUCTOR,
214  * #K_DESTRUCTOR, #K_ENUM_CLASS_STRUCT_UNION, #K_FUNCTION, #K_OPERATOR,
215  * #K_POINTER, #K_POINTER_TO_MEMBER, #K_REFERENCE, #K_RVALUE_REFERENCE,
216  * #K_USER_DEF_CONVERSION, or #K_USER_DEF_LITERAL.
217  *
218  * @sa #K_ANY_REFERRER
219  */
220 #define K_ANY_PARENT          ( K_ANY_FUNCTION_LIKE | K_ANY_POINTER \
221                               | K_ANY_REFERENCE | K_ARRAY \
222                               | K_ENUM_CLASS_STRUCT_UNION )
223 
224 /**
225  * Shorthand for any kind of pointer: #K_POINTER or #K_POINTER_TO_MEMBER.
226  */
227 #define K_ANY_POINTER         ( K_POINTER | K_POINTER_TO_MEMBER )
228 
229 /**
230  * Shorthand for any kind of reference: #K_REFERENCE or #K_RVALUE_REFERENCE.
231  */
232 #define K_ANY_REFERENCE       ( K_REFERENCE | K_RVALUE_REFERENCE )
233 
234 /**
235  * Shorthand for any kind that has a pointer to another AST: #K_ANY_PARENT or
236  * #K_TYPEDEF.
237  *
238  * @sa #K_ANY_PARENT
239  */
240 #define K_ANY_REFERRER        ( K_ANY_PARENT | K_TYPEDEF )
241 
242 ////////// extern functions ///////////////////////////////////////////////////
243 
244 /**
245  * Gets the name of \a kind.
246  *
247  * @param kind The \ref c_ast_kind to get the name for.
248  * @return Returns said name.
249  */
250 PJL_WARN_UNUSED_RESULT
251 char const* c_kind_name( c_ast_kind_t kind );
252 
253 ///////////////////////////////////////////////////////////////////////////////
254 
255 /** @} */
256 
257 #endif /* cdecl_c_kind_H */
258 /* vim:set et sw=2 ts=2: */
259