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