• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2    Copyright (c) 2009-2016  mingw-w64 project
3 
4    Contributing authors: Kai Tietz, Jonathan Yong
5 
6    Permission is hereby granted, free of charge, to any person obtaining a
7    copy of this software and associated documentation files (the "Software"),
8    to deal in the Software without restriction, including without limitation
9    the rights to use, copy, modify, merge, publish, distribute, sublicense,
10    and/or sell copies of the Software, and to permit persons to whom the
11    Software is furnished to do so, subject to the following conditions:
12 
13    The above copyright notice and this permission notice shall be included in
14    all copies or substantial portions of the Software.
15 
16    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22    DEALINGS IN THE SOFTWARE.
23 */
24 #ifndef _M_TOKEN_HXX
25 #define _M_TOKEN_HXX
26 
27 /**
28  * Garbage collector elements.
29  * Tracks allocated memory and points to the next element from the same context.
30  * @see libmangle_gc_context_t
31  */
32 typedef struct sGcElem {
33   struct sGcElem *chain;        /**< Next element in chain. */
34   size_t length;                /**< Size of allocated memory (excluding sGcElem and sGcCtx). */
35   char dta[1];                  /**< Starting adress marker of requested memory. */
36 } sGcElem;
37 
38 /**
39  * Garbage collector context.
40  * Tracks first and last of elements in gc context.
41  * @see libmangle_generate_gc()
42  * @see libmangle_release_gc()
43  */
44 typedef struct libmangle_gc_context_t {
45   sGcElem *head;                /**< Pointer to first gc element in context.*/
46   sGcElem *tail;                /**< Pointer to last gc element in context. */
47 } libmangle_gc_context_t;
48 
49 /**
50  * Token "Kind" enumeration list.
51  * @see gen_tok()
52  * @see eMSToken
53  * @see sMToken_base
54  */
55 typedef enum eMToken {
56   eMToken_none = 0,                /**< Token type: None.  */
57   eMToken_value = 1,               /**< Token type: Value. */
58   eMToken_name = 2,                /**< Token type: Name.  */
59   eMToken_dim = 3,                 /**< Token type: Dim.   */
60   eMToken_unary = 4,               /**< Token type: Unary  */
61   eMToken_binary = 5,              /**< Token type: Binary */
62   eMToken_MAX                      /**< Unused sentinel.   */
63 } eMToken;
64 
65 /**
66  * Token "Subkind" enumeration list.
67  * Also used by internal function sprint_decl1() for printing.
68  * @see gen_tok()
69  * @see eMToken
70  * @see sMToken_base
71  */
72 typedef enum eMSToken {
73   eMST_unmangled = 0,               /**< Name is unmagled. */
74   eMST_nttp = 1,                    /**< Template name. */
75   eMST_name = 2,                    /**< Decoded function name. */
76   eMST_colon = 3,                   /**< Class member accessibility. */
77   eMST_rtti = 4,                    /**< Runtime Type information name. */
78   eMST_cv = 5,                      /**< Function call convention / data qualifiers / pointer. */
79   eMST_vftable = 6,                 /**< Virtual Function Table. */
80   eMST_vbtable = 7,                 /**< Virtual Base Table. */
81   eMST_vcall = 8,                   /**< Virtual Function Call. */
82   eMST_opname = 9,                  /**< Overloaded operator. */
83   eMST_templargname = 10,           /**< Explicit template arg name. */
84   eMST_type = 11,                   /**< Function return type. */
85   eMST_dim,                         /**< Print array-like expression. @see eMToken_dim */
86   eMST_val,                         /**< Print value expression. @see sMToken_val */
87   eMST_gcarray, /* __gc[,,,,] */    /**< MSVC extenstion: "__gc" Managed C++ reference. */
88   eMST_slashed,                     /**< MTOKEN_UNARY appended and prepended with "/". */
89   eMST_array,                       /**< MTOKEN_UNARY enclosed by square brackets. */
90   eMST_element,                     /**< MTOKEN_UNARY in an argument list. */
91   eMST_template_argument_list,      /**< MTOKEN_UNARY in an argument list. */
92   eMST_ltgt,                        /**< MTOKEN_UNARY enclosed by angular brackets. */
93   eMST_frame,                       /**< MTOKEN_UNARY enclosed by curly brackets. */
94   eMST_throw,                       /**< MTOKEN_UNARY prepended by "throw ". */
95   eMST_rframe,                      /**< MTOKEN_UNARY enclosed by parentheses. */
96   eMST_destructor,                  /**< MTOKEN_UNARY prepended with "~". */
97   eMST_oper,                        /**< indicates that token an operand, prints from MTOKEN_UNARY. */
98   eMST_colonarray, /* ::[] */       /**< Unused, to be removed. */
99   eMST_lexical_frame,               /**< MTOKEN_UNARY enclosed by single quotes "'". */
100   eMST_scope,                       /**< MTOKEN_UNARY, unenclosed. */
101   eMST_udt_returning,               /**< User defined types (RTTI). */
102   eMST_coloncolon,                  /**< "::" between MTOKEN_BINARY_LEFT and MTOKEN_BINARY_RIGHT. */
103   eMST_assign,                      /**< "=" between MTOKEN_BINARY_LEFT and MTOKEN_BINARY_RIGHT and appended with "}". */
104   eMST_templateparam,               /**< Explicit template. */
105   eMST_nonetypetemplateparam,       /**< Non-explicit template. */
106   eMST_exp,                         /**< dim 'e' (exponent) dim */
107   eMST_combine,                     /**< Unary grouping. */
108   eMST_ecsu,                        /**< Is an Enum/Class/Struct/Union */
109   eMST_based                       /**< MSVC extension: "__based" Based addressing */
110 } eMSToken;
111 
112 /**
113  * Token base descriptor header.
114  * Descibes the type of token being processed.
115  */
116 typedef struct sMToken_base {
117   enum eMToken kind;            /**< Token kind. */
118   enum eMSToken subkind;        /**< Token Subkind. */
119   union uMToken *chain;         /**< Pointer to next token. NULL terminated. */
120   int flags;                    /**< Token flags. */
121 } sMToken_base;
122 
123 /**Sets the token kind, @a PT pointer to a base uMToken. */
124 #define MTOKEN_KIND(PT)		((PT)->base.kind)
125 
126 /**Sets the token subkind, @a PT pointer to a base uMToken. */
127 #define MTOKEN_SUBKIND(PT)	((PT)->base.subkind)
128 
129 /**Sets the pointer to the next token in the chain. */
130 #define MTOKEN_CHAIN(PT)	((PT)->base.chain)
131 
132 /**Sets flags in base descriptor. */
133 #define MTOKEN_FLAGS(PT)	((PT)->base.flags)
134 
135 #define MTOKEN_FLAGS_UDC    0x1 /**< Indicates a following "name" token for named struct/union/class. */
136 #define MTOKEN_FLAGS_NOTE   0x2 /**< Contains "note" name token.*/
137 #define MTOKEN_FLAGS_PTRREF 0x4 /**< Decoded fragment is a referrence. */
138 #define MTOKEN_FLAGS_ARRAY  0x8 /**< Decoded fragment has an array-like expression.*/
139 
140 /**
141  * "value" token.
142  * Contains numerical expressions for decoded names.
143  * @see sMToken_dim
144  */
145 typedef struct sMToken_value {
146   sMToken_base base;            /**< Base descriptor header. */
147   uint64_t value;               /**< Integer value. */
148   uint64_t size : 5;            /**< Byte width of value. */
149   uint64_t is_signed : 1;       /**< Value signed bit */
150 } sMToken_value;
151 
152 /**Sets the token value. @a PT pointer to a value uMToken.*/
153 #define MTOKEN_VALUE(PT)	((PT)->value.value)
154 
155 /**Sets the signed bit on value token. @a PT pointer to a value uMToken.*/
156 #define MTOKEN_VALUE_SIGNED(PT)	((PT)->value.is_signed)
157 
158 /**Sets the byte width of value in value token. @a PT pointer to a value uMToken.*/
159 #define MTOKEN_VALUE_SIZE(PT)	((PT)->value.size)
160 
161 /**
162  * "name" token.
163  * Contains text string expressions of the decoded fragment.
164  */
165 typedef struct sMToken_name {
166   sMToken_base base;            /**< Base descriptor header. */
167   char name[1];                 /**< Pointer to text string.*/
168 } sMToken_name;
169 
170 /** Retrieve or set the name string, @a PT pointer to a name uMToken */
171 #define MTOKEN_NAME(PT)		((PT)->name.name)
172 
173 /**
174  * "dim" token.
175  * Contains array-like expressions in decoded names.
176  */
177 typedef struct sMToken_dim {
178   sMToken_base base;            /**< Base descriptor header. */
179   union uMToken *value;         /**< Pointer to value token. */
180   union uMToken *non_tt_param;  /**< Pointer to C++ template name token. */
181   int beNegate;                 /**< 1 for negative "values". */
182 } sMToken_dim;
183 
184 /** Retrieve or set the value of a token, @a PT pointer to a value uMToken */
185 #define MTOKEN_DIM_VALUE(PT)	((PT)->dim.value)
186 
187 /** Retrieve or set the template of a token, @a PT pointer to a name uMToken */
188 #define MTOKEN_DIM_NTTP(PT)	((PT)->dim.non_tt_param)
189 
190 /** Retrieve or set negative bit on value token, @a PT pointer to an generic uMToken */
191 #define MTOKEN_DIM_NEGATE(PT)	((PT)->dim.beNegate)
192 
193 /**
194  * Unary node token.
195  * Contains a pointer to a single generic leaf element.
196  */
197 typedef struct sMToken_Unary
198 {
199   sMToken_base base;            /**< Base descriptor header. */
200   union uMToken *unary;         /**< Pointer to leaf element. */
201 } sMToken_Unary;
202 
203 /**Sets the leaf element on a unary token, @a PT pointer to a unary uMToken. */
204 #define MTOKEN_UNARY(PT)	((PT)->unary.unary)
205 
206 /**
207  * Binary node token.
208  * Contains pointers to any 2 generic token instances as child node elements.
209  * May act as a connector for decoded C++ names.
210  */
211 typedef struct sMToken_binary {
212   sMToken_base base;            /**< Base descriptor header. */
213   union uMToken *left;          /**< Left node element. */
214   union uMToken *right;         /**< Right node element. */
215 } sMToken_binary;
216 
217 /**Sets the left node on binary token, @a PT pointer to a binary uMToken. */
218 #define MTOKEN_BINARY_LEFT(PT)		((PT)->binary.left)
219 
220 /**Sets the right node on binary token, @a PT pointer to a binary uMToken. */
221 #define MTOKEN_BINARY_RIGHT(PT)		((PT)->binary.right)
222 
223 /**
224  * Generic token instances.
225  * Type of token determined by base descriptor in members.
226  * Base descriptor header available in all members through type punning.
227  * @see gen_tok()
228  */
229 typedef union uMToken {
230   sMToken_base base;        /**< Base descriptor header. */
231   sMToken_value value;      /**< "value" token. */
232   sMToken_name name;        /**< "name" token. */
233   sMToken_dim dim;          /**< "dim" token */
234   sMToken_Unary unary;      /**< Unary node token. */
235   sMToken_binary binary;    /**< Binary node token. */
236 } uMToken;
237 
238 /**
239  * gen_tok constructs uMToken instances
240  * Instances are destroyed with libmangle_release_gc().
241  * @param[in] gc Pointer to garbage collection context.
242  * @param[in] kind Kind of token to construct
243  * @param[in] subkind Subkind of token to construct
244  * @param[in] addend Additional byte padding at the end.
245  * @see libmangle_release_gc()
246  */
247 uMToken *libmangle_gen_tok (libmangle_gc_context_t *gc, enum eMToken kind, enum eMSToken subkind, size_t addend);
248 
249 /**
250  * Releases memory tracked by context.
251  * @param[in] gc Garbage collection context to work on.
252  * @see libmangle_generate_gc()
253  */
254 void libmangle_release_gc (libmangle_gc_context_t *gc);
255 
256 /**
257  * Constructs a garbage collection context token.
258  * @return Pointer to context.
259  * @see libmangle_release_gc()
260  */
261 libmangle_gc_context_t *libmangle_generate_gc (void);
262 
263 /**
264  * Chains uMTokens together.
265  * @param[in] l uMtoken chain to link up with.
266  * @param[in] add uMtoken to add to chain.
267  * @return @a l unchanged
268  */
269 uMToken *chain_tok (uMToken *l, uMToken *add);
270 
271 /**
272  * Dumps uMToken to a file descriptor for debugging.
273  * @param[in] fp File descriptor to print the token to.
274  * @param[in] p uMToken chain to print.
275  */
276 void libmangle_dump_tok (FILE *fp, uMToken *p);
277 
278 /**
279  * Prints C++ name to file descriptor.
280  * @param[in] fp Output file descriptor.
281  * @param[in] p Token containing information about the C++ name.
282  * @see libmangle_decode_ms_name()
283  */
284 void libmangle_print_decl (FILE *fp, uMToken *p);
285 
286 /**
287  * Get pointer to decoded C++ name string.
288  * Use free() to release returned string.
289  * @param[in] r C++ name token.
290  * @return pointer to decoded C++ name string.
291  * @see libmangle_decode_ms_name()
292  */
293 char *libmangle_sprint_decl (uMToken *r);
294 
295 /**
296  * Constructs a "value" kind token.
297  * @param[in] gc Pointer to garbage collection context.
298  * @param[in] skind Token subkind.
299  * @param[in] val Sets the value on token,
300  * @param[in] is_signed Signed bit of \a val.
301  * @param[in] size Width of \a val.
302  * @return Pointer to value token.
303  * @see sMToken_value
304  */
305 uMToken *gen_value (libmangle_gc_context_t *gc, enum eMSToken skind, uint64_t val, int is_signed, int size);
306 
307 /**
308  * Constructs a "name" kind token.
309  * @param[in] gc Pointer to garbage collection context.
310  * @param[in] skind Token subkind.
311  * @param[in] name Pointer to name string.
312  * @return Pointer to name token.
313  * @see sMToken_name
314  */
315 uMToken *gen_name (libmangle_gc_context_t *gc, enum eMSToken skind, const char *name);
316 
317 /**
318  * Constructs a "dim" kind token.
319  * @param[in] gc Pointer to garbage collection context.
320  * @param[in] skind Token subkind.
321  * @param[in] val Token numerical value.
322  * @param[in] non_tt_param pointer to decoded C++ template name.
323  * @param[in] fSigned Signedness of the numerical value.
324  * @param[in] fNegate 1 for "val" is negative digit.
325  * @return Pointer to dim token.
326  * @see sMToken_dim
327  */
328 uMToken *gen_dim (libmangle_gc_context_t *gc, enum eMSToken skind, uint64_t val, const char *non_tt_param, int fSigned, int fNegate);
329 
330 /**
331  * Constructs a "unary" kind token.
332  * @param[in] gc Pointer to garbage collection context.
333  * @param[in] skind Token subkind.
334  * @param[in] un Pointer to leaf element.
335  * @return Pointer to a unary token.
336  * @see sMToken_unary
337  */
338 uMToken *gen_unary (libmangle_gc_context_t *gc, enum eMSToken skind, uMToken *un);
339 
340 /**
341  * Generates a binary node token.
342  * @param[in] gc Pointer to garbage collection context.
343  * @param[in] skind Token subKind.
344  * @param[in] l Left node element.
345  * @param[in] r Right node element.
346  * @return Pointer to binary token.
347  * @see sMToken_binary
348  */
349 uMToken *gen_binary (libmangle_gc_context_t *gc, enum eMSToken skind, uMToken *l, uMToken *r);
350 
351 #endif
352