1 /*
2 **      cdecl -- C gibberish translator
3 **      src/c_operator.h
4 **
5 **      Copyright (C) 2018-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_operator_H
22 #define cdecl_c_operator_H
23 
24 /**
25  * @file
26  * Declares constants, macros, types, and functions for C++ operators.
27  */
28 
29 // local
30 #include "pjl_config.h"                 /* must go first */
31 #include "types.h"
32 
33 /// @cond DOXYGEN_IGNORE
34 
35 // standard
36 #include <stdbool.h>
37 
38 _GL_INLINE_HEADER_BEGIN
39 #ifndef C_OPERATOR_INLINE
40 # define C_OPERATOR_INLINE _GL_INLINE
41 #endif /* C_OPERATOR_INLINE */
42 
43 /// @endcond
44 
45 /**
46  * @defgroup cpp-operators-group C++ Operators
47  * Macros, types, and functions for C++ operators.
48  * @{
49  */
50 
51 // overloadability
52 
53 /**
54  * For c_operator.flags, denotes that the operator is not overloadable.
55  *
56  * @sa #C_OP_MEMBER
57  * @sa #C_OP_NON_MEMBER
58  * @sa #C_OP_OVERLOADABLE
59  * @sa #C_OP_UNSPECIFIED
60  */
61 #define C_OP_NOT_OVERLOADABLE     (1u << 2)
62 
63 /**
64  * For c_operator.params_max of `operator()()`, denotes an unlimited number of
65  * parameters.
66  */
67 #define C_OP_PARAMS_UNLIMITED     (~0u)
68 
69 /**
70  * For c_operator.flags, denotes that the operator overloadability (member or
71  * non-member) is unspecified.
72  *
73  * @sa #C_OP_MEMBER
74  * @sa #C_OP_NON_MEMBER
75  * @sa #C_OP_NOT_OVERLOADABLE
76  * @sa #C_OP_OVERLOADABLE
77  */
78 #define C_OP_UNSPECIFIED          C_FN_UNSPECIFIED
79 
80 /**
81  * For c_operator.flags, denotes that the operator is overload{able|ed} as a
82  * member only.
83  *
84  * @sa #C_OP_NON_MEMBER
85  * @sa #C_OP_NOT_OVERLOADABLE
86  * @sa #C_OP_OVERLOADABLE
87  * @sa #C_OP_UNSPECIFIED
88  */
89 #define C_OP_MEMBER               C_FN_MEMBER
90 
91 /**
92  * For c_operator.flags, denotes that the operator is overload{able|ed} as a
93  * non-member only.
94  *
95  * @sa #C_OP_MEMBER
96  * @sa #C_OP_NOT_OVERLOADABLE
97  * @sa #C_OP_OVERLOADABLE
98  * @sa #C_OP_UNSPECIFIED
99  */
100 #define C_OP_NON_MEMBER           C_FN_NON_MEMBER
101 
102 /**
103  * For c_operator.flags, denotes that the operator is overloadable as either a
104  * member or non-member.
105  *
106  * @sa #C_OP_MEMBER
107  * @sa #C_OP_NON_MEMBER
108  * @sa #C_OP_NOT_OVERLOADABLE
109  * @sa #C_OP_UNSPECIFIED
110  */
111 #define C_OP_OVERLOADABLE         (C_OP_MEMBER | C_OP_NON_MEMBER)
112 
113 /**
114  * For c_operator.flags, overloadability bitmask.
115  */
116 #define C_OP_MASK_OVERLOAD        0x7u
117 
118 ///////////////////////////////////////////////////////////////////////////////
119 
120 /**
121  * C++ operators.
122  *
123  * @note Operators are named based on the characters comprising them rather
124  * than their semantics because many operators have more than one meaning
125  * depending upon context, e.g. `*` is both the "times" and the "dereference"
126  * operator.
127  */
128 enum c_oper_id {
129   C_OP_NONE,            ///< No operator.
130   C_OP_NEW,             ///< The `new` operator.
131   C_OP_NEW_ARRAY,       ///< The `new[]` operator.
132   C_OP_DELETE,          ///< The `delete` operator.
133   C_OP_DELETE_ARRAY,    ///< The `delete[]` operator.
134   C_OP_EXCLAM,          ///< The `!` operator.
135   C_OP_EXCLAM_EQ,       ///< The `!=` operator.
136   C_OP_PERCENT,         ///< The `%` operator.
137   C_OP_PERCENT_EQ,      ///< The `%=` operator.
138   C_OP_AMPER,           ///< The `&` operator.
139   C_OP_AMPER2,          ///< The `&&` operator.
140   C_OP_AMPER_EQ,        ///< The `&=` operator.
141   C_OP_PARENS,          ///< The `()` operator.
142   C_OP_STAR,            ///< The `*` operator.
143   C_OP_STAR_EQ,         ///< The `*=` operator.
144   C_OP_PLUS,            ///< The `+` operator.
145   C_OP_PLUS2,           ///< The `++` operator.
146   C_OP_PLUS_EQ,         ///< The `+=` operator.
147   C_OP_COMMA,           ///< The `,` operator.
148   C_OP_MINUS,           ///< The `-` operator.
149   C_OP_MINUS2,          ///< The `--` operator.
150   C_OP_MINUS_EQ,        ///< The `-=` operator.
151   C_OP_ARROW,           ///< The `->` operator.
152   C_OP_ARROW_STAR,      ///< The `->*` operator.
153   C_OP_DOT,             ///< The `.` operator.
154   C_OP_DOT_STAR,        ///< The `.*` operator.
155   C_OP_SLASH,           ///< The `/` operator.
156   C_OP_SLASH_EQ,        ///< The `/=` operator.
157   C_OP_COLON2,          ///< The `::` operator.
158   C_OP_LESS,            ///< The `<` operator.
159   C_OP_LESS2,           ///< The `<<` operator.
160   C_OP_LESS2_EQ,        ///< The `<<=` operator.
161   C_OP_LESS_EQ,         ///< The `<=` operator.
162   C_OP_LESS_EQ_GREATER, ///< The `<=>` operator.
163   C_OP_EQ,              ///< The `=` operator.
164   C_OP_EQ2,             ///< The `==` operator.
165   C_OP_GREATER,         ///< The `>` operator.
166   C_OP_GREATER_EQ,      ///< The `>=` operator.
167   C_OP_GREATER2,        ///< The `>>` operator.
168   C_OP_GREATER2_EQ,     ///< The `>>=` operator.
169   C_OP_QMARK_COLON,     ///< The `?:` operator.
170   C_OP_BRACKETS,        ///< The `[]` operator.
171   C_OP_CIRC,            ///< The `^` operator.
172   C_OP_CIRC_EQ,         ///< The `^=` operator.
173   C_OP_PIPE,            ///< The `|` operator.
174   C_OP_PIPE_EQ,         ///< The `|=` operator.
175   C_OP_PIPE2,           ///< The `||` operator.
176   C_OP_TILDE,           ///< The `~` operator.
177 };
178 
179 /**
180  * C++ operator information.
181  *
182  * @note `params_min` and `params_max` comprise the inclusive range for the
183  * union of member and non-member versions.  If you know you're dealing with a
184  * member operator, use only `params_min`; if you know you're dealing with a
185  * non-member operator, use only `params_max`; if you don't know which, use
186  * both.
187  */
188 struct c_operator {
189   c_oper_id_t oper_id;                  ///< ID.
190   char const *name;                     ///< Name.
191 
192   /**
193    * Bitwise-or of flags specifying whether the operator is a member, non-
194    * member, both, or not overloadable.
195    *
196    * @sa #C_OP_MEMBER
197    * @sa #C_OP_NON_MEMBER
198    * @sa #C_OP_OVERLOADABLE
199    * @sa #C_OP_NOT_OVERLOADABLE
200    * @sa #C_OP_MASK_OVERLOAD
201    */
202   unsigned    flags;
203 
204   unsigned    params_min;               ///< Minimum number of parameters.
205   unsigned    params_max;               ///< Maximum number of parameters.
206   c_lang_id_t lang_ids;                 ///< Language(s) OK in.
207 };
208 
209 ////////// extern functions ///////////////////////////////////////////////////
210 
211 /**
212  * Gets the c_operator for \a oper_id.
213  *
214  * @param oper_id The ID of the c_operator to get.
215  * @return Returns a pointer to said c_operator.
216  */
217 PJL_WARN_UNUSED_RESULT
218 c_operator_t const* c_oper_get( c_oper_id_t oper_id );
219 
220 /**
221  * Checks whether the C++ operator is ambiguous.
222  *
223  * The operators `&`, `*`, `+`, `++`, `-`, and `--`, when declared as:
224  *
225  *      T operator OP(U);
226  *
227  * i.e., having one parameter, are ambiguous (to cdecl) between being a member
228  * or non-member operator since cdecl doesn't have the context in which the
229  * operator is declared.  If it were declared in-class, e.g.:
230  *
231  *      class T {
232  *      public:
233  *        // ...
234  *        T& operator OP(U);
235  *      };
236  *
237  * then clearly it's a member operator; if it were declared at file scope, then
238  * clearly it's a non-member operator; but cdecl doesn't have this context.
239  *
240  * We can tell if an operator is ambiguous if it can take 1 parameter when the
241  * minimum is 0 and the maximum is 2.
242  *
243  * @param op The C++ operator to check.
244  * @return Returns `true` only if the operator is ambiguous.
245  */
246 C_OPERATOR_INLINE PJL_WARN_UNUSED_RESULT
c_oper_is_ambiguous(c_operator_t const * op)247 bool c_oper_is_ambiguous( c_operator_t const *op ) {
248   return op->params_min == 0 && op->params_max == 2;
249 }
250 
251 /**
252  * Gets the C++ token for the operator having \a oper_id.
253  *
254  * @param oper_id The ID of the c_operator to get the token for.
255  * @return Returns said token (including alternative or graph tokens, if either
256  * is enabled); otherwise, returns the unaltered token.
257  */
258 PJL_WARN_UNUSED_RESULT
259 char const* c_oper_token_c( c_oper_id_t oper_id );
260 
261 ///////////////////////////////////////////////////////////////////////////////
262 
263 /** @} */
264 
265 _GL_INLINE_HEADER_END
266 
267 #endif /* cdecl_c_operator_H */
268 /* vim:set et sw=2 ts=2: */
269