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
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <malloc.h>
28 #include <string.h>
29 #include <inttypes.h>
30 #include <stdint.h>
31
32 #include "m_token.h"
33 #include "m_ms.h"
34
35 static uMToken *m_combine (sMSCtx *c, uMToken *l, uMToken *r);
36 static uMToken *m_type (sMSCtx *c, const char *typname);
37 static uMToken *m_cv (sMSCtx *c, const char *cv);
38 static uMToken *m_coloncolon (sMSCtx *c, uMToken *l, uMToken *r);
39 static uMToken *m_element (sMSCtx *c, uMToken *el);
40 static uMToken *m_array (sMSCtx *c, uMToken *dim);
41 static uMToken *m_scope (sMSCtx *c, uMToken *n);
42 static uMToken *m_oper (sMSCtx *c, uMToken *n);
43 static uMToken *m_name (sMSCtx *c, const char *str);
44 static uMToken *m_colon (sMSCtx *c, const char *str);
45 static uMToken *m_opname (sMSCtx *c, const char *str);
46 static uMToken *m_rtti (sMSCtx *c, const char *str);
47 static uMToken *m_frame (sMSCtx *c, uMToken *u);
48 static uMToken *m_rframe (sMSCtx *c, uMToken *u);
49 static uMToken *m_ltgt (sMSCtx *c, uMToken *u);
50 static uMToken *m_throw (sMSCtx *c, uMToken *u);
51 static uMToken *m_lexical_frame (sMSCtx *c, uMToken *u);
52
53 static uMToken *get_decorated_name (sMSCtx *c);
54 static uMToken *get_string_literal_type (sMSCtx *c);
55 static uMToken *get_symbol_name (sMSCtx *c);
56 static uMToken *get_zbuf_name (sMSCtx *c, int updateCache);
57 static uMToken *get_dimension_signed (sMSCtx *c);
58 static uMToken *get_dimension (sMSCtx *c,int fSigned, int fNegate);
59 static uMToken *extract_name (sMSCtx *c, char term);
60 static uMToken *get_scope (sMSCtx *c);
61 static uMToken *get_template_name (sMSCtx *c, int fReadTerminator);
62 static uMToken *get_operator_name (sMSCtx *c, int fIsTemplate, int *pfReadTemplateArguments);
63 static uMToken *get_template_argument_list (sMSCtx *c);
64 static uMToken *get_lexical_frame(sMSCtx *c);
65 static uMToken *get_string_encoding (sMSCtx *c, int wantBody);
66 static uMToken *get_template_constant (sMSCtx *c);
67 static uMToken *get_data_type (sMSCtx *c);
68 static uMToken *get_indirect_data_type(sMSCtx *c, uMToken *superType, char prType, uMToken *cvType, int thisFlag);
69 static uMToken *get_primary_data_type (sMSCtx *c, uMToken *superType);
70 static uMToken *get_based_type (sMSCtx *c);
71 static uMToken *get_scoped_name (sMSCtx *c);
72 static uMToken *get_basic_data_type (sMSCtx *c, uMToken *superName);
73 static uMToken *get_pointer_reference_type (sMSCtx *c, uMToken *cvType, uMToken *superType, char ptrChar);
74 static uMToken *get_indirect_function_type (sMSCtx *c, uMToken *superType);
75 static uMToken *get_pointer_reference_data_type (sMSCtx *c, uMToken *superType,int isPtr);
76 static uMToken *get_ECSU_data_type (sMSCtx *c);
77 static uMToken *get_enum_size_type (sMSCtx *c);
78 static uMToken *get_this_type (sMSCtx *c);
79 static uMToken *get_calling_convention (sMSCtx *c);
80 static uMToken *get_throw_types (sMSCtx *c);
81 static uMToken *get_argument_types (sMSCtx *c);
82 static uMToken *get_return_type (sMSCtx *c);
83 static uMToken *get_array_type (sMSCtx *c, uMToken *superType);
84 static uMToken *get_argument_list (sMSCtx *c);
85 static uMToken *compose_decl (sMSCtx *c, uMToken *symbol);
86 static uMToken *get_vftable_type (sMSCtx *c, uMToken *superType);
87 static int get_number_of_dimensions (sMSCtx *c);
88 static int get_encoded_type (sMSCtx *);
89 static uMToken *get_vdisp_map_type (sMSCtx *c, uMToken *superType);
90 static uMToken *get_ext_data_type (sMSCtx *c, uMToken *superType);
91
92 uMToken *
libmangle_decode_ms_name(libmangle_gc_context_t * gc,const char * name)93 libmangle_decode_ms_name (libmangle_gc_context_t *gc, const char *name)
94 {
95 sMSCtx ctx;
96 sCached ZNameList, ArgList, TempArgList;
97 uMToken *ret = NULL;
98 if (!name || *name == 0)
99 return NULL;
100
101 memset (&ctx, 0, sizeof (ctx));
102 ctx.gc = gc;
103 memset (&ZNameList, 0, sizeof (ZNameList));
104 memset (&ArgList, 0, sizeof (ArgList));
105 memset (&TempArgList, 0, sizeof (TempArgList));
106 ctx.name = name;
107 ctx.end = name + strlen (name);
108 ctx.pos = ctx.name;
109
110 ctx.pZNameList = &ZNameList;
111 ctx.pArgList = &ArgList;
112 ctx.pTemplateArgList = &TempArgList;
113
114 #if 0
115 fprintf(stderr,"decode_ms_name: %s\n", name);
116 #endif
117
118 if (name[0] == '?')
119 {
120 if (name[1] == '@')
121 {
122 SKIP_CHAR(&ctx,2);
123 ret = get_decorated_name (&ctx);
124 /* CV: ??? */
125 }
126 else if (name[1] == '$')
127 {
128 if (!(ret = get_template_name (&ctx, 0)))
129 ret = get_decorated_name (&ctx);
130 }
131 else
132 ret = get_decorated_name (&ctx);
133 }
134 else
135 ret = get_decorated_name (&ctx);
136
137 if (!ret)
138 {
139 ret = gen_name (ctx.gc, eMST_unmangled, name);
140 }
141
142 return ret;
143 }
144
145 char *
libmangle_encode_ms_name(libmangle_gc_context_t * gc,uMToken * tok)146 libmangle_encode_ms_name (libmangle_gc_context_t *gc, uMToken *tok)
147 {
148 return NULL;
149 }
150
151 static uMToken *
get_decorated_name(sMSCtx * c)152 get_decorated_name (sMSCtx *c)
153 {
154 uMToken *n = NULL;
155 uMToken *d = NULL;
156 int isudc;
157 if (GET_CHAR (c) != '?')
158 {
159 if (GET_CHAR (c) == 0)
160 c->err = 1;
161 fprintf (stderr,"*** get_decorated_name %s empty\n", c->name);
162 return NULL;
163 }
164 INC_CHAR (c);
165
166 n = get_symbol_name (c);
167 isudc = (n && (MTOKEN_FLAGS (n) & MTOKEN_FLAGS_UDC)) ? 1 : 0;
168 if (c->err)
169 return n;
170 if (GET_CHAR (c) != 0 && GET_CHAR (c) != '@')
171 {
172 d = get_scope (c);
173 if (d)
174 {
175 if (c->fExplicitTemplateParams == 0)
176 n = m_coloncolon (c, d, n);
177 else
178 {
179 c->fExplicitTemplateParams = 0;
180 n = m_combine (c, n, d);
181 if (GET_CHAR (c) != '@')
182 {
183 d = get_scope (c);
184 n = m_coloncolon (c, d, n);
185 }
186 }
187 }
188 }
189 if (!n)
190 return n;
191 if (isudc)
192 MTOKEN_FLAGS (n) |= MTOKEN_FLAGS_UDC;
193 if (MTOKEN_FLAGS (n) & MTOKEN_FLAGS_NOTE)
194 return n;
195 if (GET_CHAR (c) != 0)
196 {
197 if (GET_CHAR (c) != '@')
198 return NULL;
199 INC_CHAR (c);
200 }
201 return compose_decl (c, n);
202 }
203
204
205 static uMToken *
get_symbol_name(sMSCtx * c)206 get_symbol_name (sMSCtx *c)
207 {
208 if (GET_CHAR (c) != '?')
209 return get_zbuf_name (c, 1);
210 if (c->pos[1] == '$')
211 return get_template_name (c, 1);
212 INC_CHAR (c);
213 return get_operator_name (c, 0, NULL);
214 }
215
216 static uMToken *
get_zbuf_name(sMSCtx * c,int updateCache)217 get_zbuf_name (sMSCtx *c, int updateCache)
218 {
219 const char *ntmp;
220 uMToken *dim, *ret = NULL, *n = NULL;
221
222 if (GET_CHAR(c) >= '0' && GET_CHAR (c) <= '9')
223 {
224 ret = c->pZNameList->arr[GET_CHAR (c) - '0'];
225 INC_CHAR (c);
226 return ret;
227 }
228 if (GET_CHAR (c) == '?')
229 {
230 n = get_template_name (c, 0);
231 if (GET_CHAR (c) == '@')
232 INC_CHAR (c);
233 if (updateCache && c->pZNameList->count < 10)
234 {
235 c->pZNameList->arr[c->pZNameList->count] = n;
236 c->pZNameList->count += 1;
237 }
238 return n;
239 }
240 ntmp="template-parameter-";
241 if (!strncmp(c->pos,"template-parameter-",19))
242 SKIP_CHAR (c,19);
243 else
244 {
245 ntmp="generic-type-";
246 if (!strncmp(c->pos, "generic-type-", 13))
247 SKIP_CHAR (c,13);
248 else
249 {
250 n = extract_name (c, '@');
251 if (updateCache && c->pZNameList->count < 10)
252 {
253 c->pZNameList->arr[c->pZNameList->count] = n;
254 c->pZNameList->count += 1;
255 }
256 return n;
257 }
258 }
259 dim=get_dimension_signed (c);
260 n=chain_tok (gen_name (c->gc, eMST_templargname, ntmp), dim);
261 if (updateCache && c->pZNameList->count < 10)
262 {
263 c->pZNameList->arr[c->pZNameList->count] = n;
264 c->pZNameList->count += 1;
265 }
266 return n;
267 }
268
269 static uMToken *
get_dimension_signed(sMSCtx * c)270 get_dimension_signed (sMSCtx *c)
271 {
272 if (GET_CHAR (c) == 0)
273 {
274 c->err=1;
275 return NULL;
276 }
277 if (GET_CHAR (c) != '?')
278 return get_dimension (c, 0, 0);
279 INC_CHAR (c);
280 return get_dimension (c, 0, 1/* be negative*/);
281 }
282
283 static uMToken *
get_dimension(sMSCtx * c,int fSigned,int fNegate)284 get_dimension (sMSCtx *c, int fSigned, int fNegate)
285 {
286 const char *non_tt_param=NULL;
287 uint64_t v_r = 0ULL, v1;
288
289 if (GET_CHAR (c) == 'Q')
290 {
291 INC_CHAR (c);
292 non_tt_param="'non-type-template-parameter";
293 }
294 if (GET_CHAR (c) == 0)
295 {
296 c->err = 2;
297 return NULL;
298 }
299 if (GET_CHAR (c) >= '0' && GET_CHAR (c) <= '9')
300 {
301 uint64_t v = (uint64_t) ((GET_CHAR (c)-'0') + 1);
302 INC_CHAR (c);
303 return gen_dim (c->gc, eMST_dim,v, non_tt_param, fSigned, fNegate);
304 }
305
306 while (GET_CHAR (c) != '@')
307 {
308 if (GET_CHAR (c) == 0)
309 {
310 c->err = 2;
311 return NULL;
312 }
313 if (GET_CHAR (c) < 'A' || GET_CHAR (c) > 'P')
314 {
315 c->err = 1;
316 return NULL;
317 }
318 v1=(uint64_t) (GET_CHAR (c) - 'A');
319 v_r = v_r*10ULL + v1;
320 INC_CHAR (c);
321 }
322 if (GET_CHAR (c) !='@')
323 {
324 c->err = 1;
325 return NULL;
326 }
327 INC_CHAR (c);
328 return gen_dim (c->gc, eMST_dim,v_r, non_tt_param, fSigned, fNegate);
329 }
330
331 static uMToken *
extract_name(sMSCtx * c,char term)332 extract_name (sMSCtx *c, char term)
333 {
334 uMToken *ret;
335 char *txt;
336 size_t len;
337 const char *sv = c->pos;
338 while (GET_CHAR (c) != 0 && GET_CHAR (c) != term)
339 {
340 INC_CHAR (c);
341 }
342 if (GET_CHAR (c) != '@')
343 {
344 c->err = 1;
345 return NULL;
346 }
347 len = (size_t) (c->pos - sv);
348 txt = (char *) malloc (len + 1);
349 memcpy (txt, sv, len);
350 txt[len] = 0;
351 INC_CHAR (c);
352 ret = m_name (c, txt);
353 free (txt);
354 return ret;
355 }
356
357 static uMToken *
get_scope(sMSCtx * c)358 get_scope (sMSCtx *c)
359 {
360 uMToken *n = NULL;
361
362 while (1)
363 {
364 if (GET_CHAR (c) == 0 || GET_CHAR (c) == '@')
365 break;
366 if (c->fExplicitTemplateParams != 0 && !c->fGetTemplateArgumentList)
367 return n;
368 if (GET_CHAR (c) == '?')
369 {
370 INC_CHAR (c);
371 if (GET_CHAR (c) == '$')
372 {
373 DEC_CHAR (c);
374 n = m_coloncolon (c, get_zbuf_name (c, 1), n);
375 }
376 else if (GET_CHAR (c) == '%' || GET_CHAR (c) == 'A')
377 {
378 while (GET_CHAR (c) != '@')
379 INC_CHAR (c);
380 INC_CHAR (c);
381 n = m_coloncolon (c, m_name (c, "anonymous_namespace"), n);
382 }
383 else if (GET_CHAR (c) == '?')
384 {
385 if (c->pos[1] == '_' && c->pos[2] == '?')
386 {
387 INC_CHAR (c);
388 n = m_coloncolon (c, get_operator_name (c, 0,NULL), n);
389 if (GET_CHAR (c) == '@')
390 INC_CHAR (c);
391 }
392 else
393 {
394 n = m_coloncolon (c, gen_unary (c->gc, eMST_slashed, get_decorated_name (c)), n);
395 }
396 }
397 else if (GET_CHAR (c) == 'I')
398 {
399 INC_CHAR (c);
400 n = m_coloncolon (c, m_array (c, get_zbuf_name (c, 1)), n);
401 }
402 else
403 n = m_coloncolon (c, get_lexical_frame (c), n);
404 }
405 else
406 n = m_coloncolon (c, get_zbuf_name (c, 1), n);
407 }
408 if (n)
409 n = m_scope (c, n);
410 if (GET_CHAR (c))
411 {
412 if (GET_CHAR (c) == '@')
413 return n;
414 }
415 else
416 {
417 c->err = 2;
418 return n;
419 }
420 return n;
421 }
422
423 static uMToken *
get_template_name(sMSCtx * c,int fReadTerminator)424 get_template_name (sMSCtx *c, int fReadTerminator)
425 {
426 sCached rep1;
427 sCached rep2;
428 sCached rep3;
429 sCached *svZName,*svArgList,*svTempArgList;
430 uMToken *n = NULL;
431 int fFlag = 0;
432
433 if (GET_CHAR (c) !='?' || c->pos[1] != '$')
434 return NULL;
435 memset (&rep1, 0, sizeof (rep1));
436 memset (&rep2, 0, sizeof (rep2));
437 memset (&rep3, 0, sizeof (rep3));
438
439 svTempArgList = c->pTemplateArgList;
440 svArgList = c->pArgList;
441 svZName = c->pZNameList;
442
443 SKIP_CHAR(c,2);
444
445 c->pArgList=&rep1;
446 c->pZNameList=&rep2;
447 c->pTemplateArgList=&rep3;
448
449 if (GET_CHAR (c) == '?')
450 {
451 INC_CHAR (c);
452 n = get_operator_name (c, 1, &fFlag);
453 }
454 else
455 n = get_zbuf_name (c, 1);
456 if (!n)
457 c->fExplicitTemplateParams = 1;
458 if (!fFlag)
459 {
460 n = get_template_argument_list (c);
461 n = m_ltgt (c, n);
462 if (fReadTerminator)
463 INC_CHAR (c);
464 }
465 c->pArgList = svArgList;
466 c->pZNameList = svZName;
467 c->pTemplateArgList = svTempArgList;
468 return n;
469 }
470
471 static uMToken *
get_operator_name(sMSCtx * c,int fIsTemplate,int * pfReadTemplateArguments)472 get_operator_name (sMSCtx *c, int fIsTemplate, int *pfReadTemplateArguments)
473 {
474 const char *svName;
475 char ch = GET_CHAR (c);
476 uMToken *n = NULL,*h = NULL;
477
478 if (!ch)
479 {
480 c->err = 2;
481 return NULL;
482 }
483 INC_CHAR (c);
484 switch(ch)
485 {
486 case '0': case '1':
487 if (fIsTemplate)
488 {
489 h = m_ltgt (c, get_template_argument_list (c));
490 if (pfReadTemplateArguments)
491 *pfReadTemplateArguments = 1;
492 ch = GET_CHAR (c);
493 if (ch == 0)
494 return m_oper (c, h);
495 INC_CHAR (c);
496 }
497 svName = c->pos;
498 n = get_zbuf_name (c, 0);
499 c->pos = svName;
500 if (n && ch == '1')
501 n=gen_unary (c->gc, eMST_destructor, n);
502 n = chain_tok (n, h);
503 return m_oper (c, n);
504 case '2':
505 return m_oper (c, m_opname (c, "operator new"));
506 case '3':
507 return m_oper (c, m_opname (c, "operator delete"));
508 case '4':
509 return m_oper (c, m_opname (c, "operator ="));
510 case '5':
511 return m_oper (c, m_opname (c, "operator >>"));
512 case '6':
513 return m_oper (c, m_opname (c, "operator <<"));
514 case '7':
515 return m_oper (c, m_opname (c, "operator !"));
516 case '8':
517 return m_oper (c, m_opname (c, "operator =="));
518 case '9':
519 return m_oper (c, m_opname (c, "operator !="));
520 case 'A':
521 return m_oper (c, m_opname (c, "operator []"));
522 case 'B':
523 n = m_opname (c, "operator");
524 MTOKEN_FLAGS(n) |= MTOKEN_FLAGS_UDC;
525 n = m_oper (c, n);
526 MTOKEN_FLAGS(n) |= MTOKEN_FLAGS_UDC;
527 return n;
528 case 'C':
529 return m_oper (c, m_opname (c, "operator ->"));
530 case 'D':
531 return m_oper (c, m_opname (c, "operator *"));
532 case 'E':
533 return m_oper (c, m_opname (c, "operator ++"));
534 case 'F':
535 return m_oper (c, m_opname (c, "operator --"));
536 case 'G':
537 return m_oper (c, m_opname (c, "operator -"));
538 case 'H':
539 return m_oper (c, m_opname (c, "operator +"));
540 case 'I':
541 return m_oper (c, m_opname (c, "operator &"));
542 case 'J':
543 return m_oper (c, m_opname (c, "operator ->*"));
544 case 'K':
545 return m_oper (c, m_opname (c, "operator /"));
546 case 'L':
547 return m_oper (c, m_opname (c, "operator %"));
548 case 'M':
549 return m_oper (c, m_opname (c, "operator <"));
550 case 'N':
551 return m_oper (c, m_opname (c, "operator <="));
552 case 'O':
553 return m_oper (c, m_opname (c, "operator >"));
554 case 'P':
555 return m_oper (c, m_opname (c, "operator >="));
556 case 'Q':
557 return m_oper (c, m_opname (c, "operator ,"));
558 case 'R':
559 return m_oper (c, m_opname (c, "operator ()"));
560 case 'S':
561 return m_oper (c, m_opname (c, "operator ~"));
562 case 'T':
563 return m_oper (c, m_opname (c, "operator ^"));
564 case 'U':
565 return m_oper (c, m_opname (c, "operator |"));
566 case 'V':
567 return m_oper (c, m_opname (c, "operator &&"));
568 case 'W':
569 return m_oper (c, m_opname (c, "operator ||"));
570 case 'X':
571 return m_oper (c, m_opname (c, "operator *="));
572 case 'Y':
573 return m_oper (c, m_opname (c, "operator +="));
574 case 'Z':
575 return m_oper (c, m_opname (c, "operator -="));
576 case '_':
577 break;
578 default:
579 fprintf (stderr, " *** get_operator_name unknown '%c'\n", ch);
580 return NULL;
581 }
582 ch = GET_CHAR (c);
583 if (! ch)
584 {
585 c->err = 2;
586 return NULL;
587 }
588 INC_CHAR (c);
589 switch(ch)
590 {
591 case '_':
592 ch = GET_CHAR (c);
593 INC_CHAR (c);
594 switch (ch)
595 {
596 case 'A':
597 return m_oper (c, m_opname (c, "__man_vec_ctor"));
598 case 'B':
599 return m_oper (c, m_opname (c, "__man_vec_dtor"));
600 case 'C':
601 return m_oper (c, m_opname (c, "__ehvec_copy_ctor"));
602 case 'D':
603 return m_oper (c, m_opname (c, "__ehvec_copy_ctor_vb"));
604 }
605 fprintf (stderr, " *** get_operator_name unknown '__%c'\n", ch);
606 return NULL;
607
608 case '0':
609 return m_oper (c, m_opname (c, "operator /="));
610 case '1':
611 return m_oper (c, m_opname (c, "operator %="));
612 case '2':
613 return m_oper (c, m_opname (c, "operator >>="));
614 case '3':
615 return m_oper (c, m_opname (c, "operator <<="));
616 case '4':
617 return m_oper (c, m_opname (c, "operator &="));
618 case '5':
619 return m_oper (c, m_opname (c, "operator |="));
620 case '6':
621 return m_oper (c, m_opname (c, "operator ^="));
622 case '7':
623 return m_oper (c, gen_name (c->gc, eMST_vftable, "$vftable"));
624 case '8':
625 return m_oper (c, gen_name (c->gc, eMST_vbtable, "$vbtable"));
626 case '9':
627 return m_oper (c, gen_name (c->gc, eMST_vcall, "vcall"));
628 case 'A':
629 return m_oper (c, m_opname (c,"typeof"));
630 case 'B':
631 return m_oper (c, m_opname (c,"local_static_guard"));
632 case 'C':
633 n = get_string_encoding (c, 1);
634 MTOKEN_FLAGS(n) |= MTOKEN_FLAGS_NOTE;
635 return n;
636 case 'D':
637 return m_oper (c, m_opname (c,"vbase_destructor"));
638 case 'E':
639 return m_oper (c, m_opname (c,"__vecDelDtor"));
640 case 'F':
641 return m_oper (c, m_opname (c,"__dflt_ctor_closure"));
642 case 'G':
643 return m_oper (c, m_opname (c, "__delDtor"));
644 case 'H':
645 return m_oper (c, m_opname (c, "__vec_ctor"));
646 case 'I':
647 return m_oper (c, m_opname (c, "__vec_dtor"));
648 case 'J':
649 return m_oper (c, m_opname (c, "__vec_ctor_vb"));
650 case 'K':
651 return m_oper (c, m_opname (c, "$vdispmap"));
652 case 'L':
653 return m_oper (c, m_opname (c, "__ehvec_ctor"));
654 case 'M':
655 return m_oper (c, m_opname (c, "__ehvec_dtor"));
656 case 'N':
657 return m_oper (c, m_name (c, "__ehvec_ctor_vb"));
658 case 'O':
659 return m_oper (c, m_opname (c, "__copy_ctor_closure"));
660 case 'P':
661 return gen_unary (c->gc, eMST_udt_returning, get_operator_name (c, 0, NULL));
662 case 'Q':
663 return m_oper (c, m_opname (c, "operator 'EH'"));
664 case 'R':
665 ch = GET_CHAR (c);
666 INC_CHAR (c);
667 switch (ch)
668 {
669 case '0':
670 h = m_rtti (c, "$type_descriptor");
671 return m_oper (c, m_combine (c, get_data_type (c) , h));
672 case '1':
673 h = m_rtti (c, "base_class_descriptor");
674 n = m_element (c, get_dimension_signed (c));
675 n = chain_tok (n, m_element (c, get_dimension_signed (c)));
676 n = chain_tok (n, m_element (c, get_dimension_signed (c)));
677 n = chain_tok (n, m_element (c, get_dimension (c, 0, 0)));
678 n = m_frame (c, n);
679 return m_oper (c, gen_binary (c->gc, eMST_assign, h, n));
680 case '2':
681 return m_oper (c, m_rtti (c, "base_class_array"));
682 case '3':
683 return m_oper (c, m_rtti (c, "class_hierarchy_descriptor"));
684 case '4':
685 return m_oper (c, m_rtti (c, "complete_object_locator"));
686 }
687 DEC_CHAR (c);
688 fprintf (stderr, " *** Unkown RTTI %c\n", ch);
689 c->err = 2;
690 return NULL;
691 case 'S':
692 return m_oper (c, m_opname (c, "$locvftable"));
693 case 'T':
694 return m_oper (c, m_opname (c, "__local_vftable_ctor_closure"));
695 case 'U':
696 n = m_opname (c, "operator new[]");
697 return m_oper (c, n);
698 case 'V':
699 n = m_opname (c, "operator delete[]");
700 return m_oper (c, n);
701 case 'W': /* omni callsig ??? */
702 default:
703 fprintf (stderr, " *** get_operator_name unknown '_%c'\n", ch);
704 return NULL;
705 case 'X':
706 return m_oper (c, m_opname (c, "__placement_delete_closure"));
707 case 'Y':
708 return m_oper (c, m_opname (c, "__placement_arrayDelete_closure"));
709 case '?':
710 break;
711 }
712 ch = GET_CHAR (c);
713 if (!ch)
714 {
715 c->err = 2;
716 return NULL;
717 }
718 INC_CHAR (c);
719 switch(ch)
720 {
721 case '0':
722 m_combine (c, m_name (c, "using namespace"), get_string_encoding (c, 0));
723 MTOKEN_FLAGS (n) |= MTOKEN_FLAGS_NOTE;
724 return n;
725 }
726 fprintf (stderr, " *** get_operator_name unknown '__?%c'\n", ch);
727 return NULL;
728 }
729
730 static uMToken *
get_template_argument_list(sMSCtx * c)731 get_template_argument_list (sMSCtx *c)
732 {
733 uMToken *n = NULL;
734 uMToken *h = NULL;
735 int idx;
736 int beFirst=1;
737 c->fGetTemplateArgumentList = 1;
738 do
739 {
740 if (GET_CHAR (c) == 0 || GET_CHAR (c) == '@')
741 break;
742 idx = (int) (GET_CHAR (c) - '0');
743 if (GET_CHAR (c) >= '0' && GET_CHAR (c) <= '9')
744 {
745 h = c->pTemplateArgList->arr[idx];
746 INC_CHAR (c);
747 }
748 else
749 {
750 const char *svPos = c->pos;
751 if (GET_CHAR (c) =='X')
752 {
753 INC_CHAR (c);
754 h = m_type (c, "void");
755 }
756 else if (GET_CHAR (c) == '$' && c->pos[1] != '$')
757 {
758 INC_CHAR (c);
759 h = get_template_constant (c);
760 }
761 else if (GET_CHAR (c) == '?')
762 {
763 uMToken *sdim = get_dimension_signed (c);
764 h = gen_binary (c->gc, eMST_templateparam, m_name (c, "template-parameter"), sdim);
765 }
766 else
767 h = get_primary_data_type (c, NULL);
768 if ((int)(c->pos-svPos)>1 &&
769 c->pTemplateArgList->count < 10)
770 {
771 c->pTemplateArgList->arr[c->pTemplateArgList->count] = h;
772 c->pTemplateArgList->count += 1;
773 }
774 }
775 h = m_element (c, h);
776 if (beFirst)
777 {
778 n = h;
779 beFirst = 0;
780 }
781 else
782 {
783 n = chain_tok (n, h);
784 }
785 }
786 while (c->err == 0);
787 c->fGetTemplateArgumentList = 0;
788 if (n)
789 n = gen_unary (c->gc, eMST_template_argument_list, n);
790 return n;
791 }
792
793 static uMToken *
get_lexical_frame(sMSCtx * c)794 get_lexical_frame (sMSCtx *c)
795 {
796 return m_lexical_frame (c, get_dimension (c, 0, 0));
797 }
798
799 static uMToken *
get_string_encoding(sMSCtx * c,int wantBody)800 get_string_encoding (sMSCtx *c, int wantBody)
801 {
802 uMToken *length = NULL;
803 uMToken *crc = NULL, *h = NULL;
804 uMToken *typ = NULL;
805 const char *svName;
806 size_t len;
807 char *hp;
808
809 if (GET_CHAR (c) != '@') return NULL;
810 INC_CHAR (c);
811 typ = get_string_literal_type (c);
812 length = get_dimension (c, 0, 0);
813 crc = get_dimension (c, 0, 0);
814 if (GET_CHAR (c) == 0)
815 {
816 c->err = 2;
817 return NULL;
818 }
819 svName = c->pos;
820 while (GET_CHAR (c) != 0)
821 {
822 if (GET_CHAR (c) == '@')
823 break;
824 INC_CHAR (c);
825 }
826 if (GET_CHAR (c) == 0)
827 {
828 c->err = 2;
829 return NULL;
830 }
831 len = (size_t) (c->pos - svName);
832 hp = (char *) malloc (len + 1);
833 memcpy (hp, svName, len);
834 hp[len] = 0;
835 INC_CHAR (c);
836 h = m_name (c, hp);
837 free (hp);
838 if (wantBody)
839 h = m_combine (c, typ, m_combine (c, h, m_array (c, length)));
840 return h;
841 }
842
843 static uMToken *
get_template_constant(sMSCtx * c)844 get_template_constant (sMSCtx *c)
845 {
846 char ch;
847 uMToken *n = NULL;
848 uMToken *exp;
849
850 ch = GET_CHAR(c);
851 if (!ch)
852 {
853 c->err = 2;
854 return NULL;
855 }
856 INC_CHAR (c);
857 if (ch =='E')
858 return get_decorated_name (c);
859 if (ch > 'E' && ch <= 'J')
860 {
861 if (ch >= 'H' && ch <= 'J')
862 {
863 exp = m_element (c, get_decorated_name (c));
864 if (!n) n = exp;
865 else chain_tok (n, exp);
866 }
867 switch(ch)
868 {
869 case 'G': case 'J':
870 exp = m_element (c, get_dimension_signed (c));
871 if (!n) n = exp;
872 else chain_tok (n, exp);
873 case 'F': case 'I':
874 exp = m_element (c, get_dimension_signed (c));
875 if (!n) n = exp;
876 else chain_tok (n, exp);
877 case 'H':
878 exp = m_element (c, get_dimension_signed (c));
879 if (!n) n = exp;
880 else chain_tok (n, exp);
881 break;
882 }
883 return m_frame (c, n);
884 }
885 if (ch == 'Q' || ch == 'D')
886 {
887 n = get_dimension_signed (c);
888 if (ch == 'D')
889 return gen_binary (c->gc, eMST_templateparam, m_name (c, "template-parameter"), n);
890 return gen_binary (c->gc, eMST_nonetypetemplateparam, m_name (c, "none-type-template-parameter"), n);
891 }
892 if (ch == '0')
893 return get_dimension_signed (c);
894 if (ch == '1')
895 {
896 if (GET_CHAR (c) != '@')
897 return m_combine (c, m_cv (c, "&"), get_decorated_name (c));
898 INC_CHAR (c);
899 return m_name (c, "NULL");
900 }
901 if (ch != '2')
902 {
903 fprintf (stderr, " *** get_template_constant unknown '%c'\n", ch);
904 return NULL;
905 }
906 n = get_dimension_signed (c);
907 exp = get_dimension_signed (c);
908 return gen_binary (c->gc, eMST_exp, n, exp);
909 }
910
911 static uMToken *
get_data_type(sMSCtx * c)912 get_data_type (sMSCtx *c)
913 {
914 uMToken *n = NULL;
915 if (GET_CHAR (c) == 0)
916 {
917 c->err = 2;
918 return n;
919 }
920 if (GET_CHAR (c) == '?')
921 {
922 INC_CHAR (c);
923 n = get_indirect_data_type (c, n, (char)0, NULL, 0);
924 return get_primary_data_type (c, n);
925 }
926 if (GET_CHAR (c) != 'X')
927 return get_primary_data_type (c, n);
928 INC_CHAR (c);
929 return m_combine (c, m_type (c, "void"), n);
930 }
931
932 static uMToken *
get_indirect_data_type(sMSCtx * c,uMToken * superType,char prType,uMToken * cvType,int thisFlag)933 get_indirect_data_type (sMSCtx *c, uMToken *superType, char prType, uMToken *cvType, int thisFlag)
934 {
935 uMToken *n = NULL, *n1 = NULL, *n2 = NULL;
936 int state;
937
938 if (GET_CHAR (c) == 0)
939 {
940 c->err = 2;
941 if (thisFlag != 0)
942 return NULL;
943 if (!superType)
944 {
945 if (!cvType)
946 return NULL;
947 return cvType;
948 }
949 if (MTOKEN_FLAGS (superType) & MTOKEN_FLAGS_PTRREF)
950 return superType;
951 if (!cvType)
952 return superType;
953 return m_combine (c, cvType, superType);
954 }
955 if (GET_CHAR (c) == '$')
956 {
957 INC_CHAR (c);
958 if (GET_CHAR (c) == 'A')
959 {
960 n = m_cv (c, "__gc");
961 INC_CHAR (c);
962 }
963 else if (GET_CHAR (c) == 'B')
964 {
965 n = m_cv (c, "__pin");
966 INC_CHAR (c);
967 }
968 else
969 {
970 state = (int)(GET_CHAR (c) - '3')*16;
971 INC_CHAR (c);
972 state += (int)GET_CHAR (c);
973 INC_CHAR (c);
974 n = gen_value (c->gc, eMST_gcarray, (uint64_t) state, 0, 4);
975 if (superType)
976 {
977 if (!(MTOKEN_FLAGS (superType) & MTOKEN_FLAGS_ARRAY))
978 superType = m_rframe (c, superType);
979 n=m_combine (c, superType, n);
980 }
981 INC_CHAR (c);
982 return n;
983 }
984 }
985 state = (GET_CHAR (c) - (GET_CHAR (c) < 'A' ? 0x16 : 0x41));
986 while (1)
987 {
988 if (state == 4)
989 n1 = m_combine (c, n1, m_cv (c, "__ptr64"));
990 else if (state == 5)
991 n2 = m_combine (c, n2, m_cv (c, "__unaligned"));
992 else if (state != 8)
993 {
994 uMToken *ret = NULL;
995 INC_CHAR (c);
996 if (state > 31)
997 return NULL;
998 if (prType == '*')
999 ret = m_cv (c, "*");
1000 else if (prType == '&')
1001 ret = m_cv (c, "&");
1002
1003 ret = m_combine (c, n ,ret);
1004 ret = m_combine (c, ret, n1);
1005 ret = m_combine (c, n2, ret);
1006 if ((state & 0x10) != 0)
1007 {
1008 if (thisFlag != 0)
1009 return NULL;
1010 if (prType)
1011 {
1012 if (GET_CHAR (c) == 0)
1013 {
1014 c->err = 2;
1015 return ret;
1016 }
1017 else
1018 {
1019 if (ret)
1020 ret = gen_binary (c->gc, eMST_coloncolon , get_scope (c), ret);
1021 else
1022 ret = get_scope (c);
1023 }
1024 if (GET_CHAR (c) == 0) c->err = 2;
1025 else
1026 {
1027 char ch = GET_CHAR (c);
1028 INC_CHAR (c);
1029 if (ch != '@')
1030 return NULL;
1031 }
1032 }
1033 else if (GET_CHAR (c) == 0)
1034 c->err = 2;
1035 else
1036 {
1037 ret = get_scope (c);
1038 if (GET_CHAR (c) != 0)
1039 {
1040 char ch = GET_CHAR (c);
1041 INC_CHAR (c);
1042 if (ch != '@')
1043 return NULL;
1044 }
1045 else
1046 c->err = 2;
1047 }
1048 }
1049 if ((state&0xc)==0xc)
1050 {
1051 if (thisFlag != 0)
1052 return NULL;
1053 ret = m_combine (c, get_based_type (c), ret);
1054 }
1055 if ((state & 2) != 0)
1056 ret = m_combine (c, m_cv (c, "volatile"), ret);
1057 if ((state & 1) != 0)
1058 ret = m_combine (c, m_cv (c, "const"), ret);
1059 if (thisFlag != 0)
1060 {
1061 if (!ret)
1062 ret = m_name (c, "");
1063 MTOKEN_FLAGS(ret) |= MTOKEN_FLAGS_PTRREF;
1064 return ret;
1065 }
1066 if (!superType)
1067 {
1068 if (cvType)
1069 ret = m_combine (c, ret, cvType);
1070 if (!ret)
1071 ret = m_name (c, "");
1072 MTOKEN_FLAGS(ret) |= MTOKEN_FLAGS_PTRREF;
1073 return ret;
1074 }
1075 if (MTOKEN_FLAGS(superType) & MTOKEN_FLAGS_PTRREF)
1076 {
1077 if (cvType)
1078 {
1079 ret = m_combine (c, ret, cvType);
1080 ret = m_combine (c, ret, superType);
1081 MTOKEN_FLAGS(ret) |= MTOKEN_FLAGS_PTRREF;
1082 return ret;
1083 }
1084 }
1085 if (!(MTOKEN_FLAGS(superType)&MTOKEN_FLAGS_ARRAY))
1086 ret = m_combine (c, ret, superType);
1087 else
1088 ret = superType;
1089 MTOKEN_FLAGS(ret) |= MTOKEN_FLAGS_PTRREF;
1090 return ret;
1091 }
1092 else
1093 {
1094 if (!n1)
1095 n1 = m_cv (c, "__restrict");
1096 else
1097 n1 = m_combine (c, n1, m_cv (c, "__restrict"));
1098 }
1099 INC_CHAR (c);
1100 state=GET_CHAR (c)-(GET_CHAR (c) < 'A' ? 0x16 : 0x41);
1101 }
1102 }
1103
1104 static uMToken *
get_primary_data_type(sMSCtx * c,uMToken * superType)1105 get_primary_data_type (sMSCtx *c, uMToken *superType)
1106 {
1107 uMToken *superName = NULL;
1108 uMToken *cvType = NULL;
1109 switch(GET_CHAR (c))
1110 {
1111 case 0:
1112 c->err = 2;
1113 return superType;
1114 case 'B':
1115 cvType = m_cv (c, "volatile");
1116 /* fall through */
1117 case 'A':
1118 superName = superType;
1119 if (!superName)
1120 superName = m_name (c, "");
1121 MTOKEN_FLAGS (superName) |= MTOKEN_FLAGS_PTRREF;
1122 INC_CHAR (c);
1123 return get_pointer_reference_type (c, cvType, superName, '&');
1124 case '$':
1125 if (c->pos[1] == '$')
1126 {
1127 SKIP_CHAR (c, 2);
1128 break;
1129 }
1130 if (c->pos[1] == 0)
1131 {
1132 c->err = 2;
1133 return NULL;
1134 }
1135 fprintf (stderr, " *** get_primary_data_type '$%c' unknown\n", c->pos[1]);
1136 return NULL;
1137 default:
1138 return get_basic_data_type (c, superType);
1139 }
1140 switch(GET_CHAR (c))
1141 {
1142 case 0:
1143 c->err = 2;
1144 return superType;
1145 case 'A':
1146 INC_CHAR (c);
1147 return get_indirect_function_type (c, superType);
1148 case 'B':
1149 INC_CHAR (c);
1150 return get_pointer_reference_data_type (c, superType, 1);
1151 case 'C':
1152 INC_CHAR (c);
1153 return get_basic_data_type (c, get_indirect_data_type (c, superType, (char)0, superName, 0));
1154 }
1155 fprintf (stderr, " *** get_primary_data_type '$$%c' unknown\n", GET_CHAR (c));
1156 return NULL;
1157 }
1158
1159 static uMToken *
get_based_type(sMSCtx * c)1160 get_based_type (sMSCtx *c)
1161 {
1162 uMToken *n = m_cv (c, "__based");
1163 uMToken *p = NULL;
1164 char ch;
1165
1166 if (GET_CHAR (c) == 0)
1167 {
1168 c->err = 2;
1169 return gen_binary (c->gc, eMST_based, n, NULL);
1170 }
1171 ch = GET_CHAR (c);
1172 INC_CHAR (c);
1173 switch(ch)
1174 {
1175 case '0':
1176 p = m_type (c, "void");
1177 break;
1178 case '2':
1179 p = get_scoped_name (c);
1180 break;
1181 case '5':
1182 fprintf (stderr, " *** get_based_type unknown '%c'\n", ch);
1183 return NULL;
1184 default:
1185 fprintf (stderr, " *** get_based_type unknown '%c' (ignored)\n", ch);
1186 break;
1187 }
1188 return gen_binary (c->gc, eMST_based, n, p);
1189 }
1190
1191 static uMToken *
get_scoped_name(sMSCtx * c)1192 get_scoped_name (sMSCtx *c)
1193 {
1194 uMToken *n = NULL;
1195 n = get_zbuf_name (c, 1);
1196 if (n && GET_CHAR (c) != 0)
1197 {
1198 if (GET_CHAR (c) =='@')
1199 {
1200 INC_CHAR (c);
1201 return n;
1202 }
1203 n = m_coloncolon (c, get_scope (c), n);
1204 }
1205 if (GET_CHAR (c) == '@')
1206 {
1207 INC_CHAR (c);
1208 return n;
1209 }
1210 if (GET_CHAR (c) != 0)
1211 return n;
1212 c->err = 2;
1213 return n;
1214 }
1215
1216 static uMToken *
get_basic_data_type(sMSCtx * c,uMToken * superName)1217 get_basic_data_type (sMSCtx *c, uMToken *superName)
1218 {
1219 uMToken *bTyp = NULL;
1220 uMToken *cvName = NULL;
1221 uMToken *arType = NULL;
1222 uMToken *tmp = NULL;
1223 char svChar,svChar1;
1224 int flags;
1225
1226 if (GET_CHAR (c) == 0)
1227 {
1228 c->err = 2;
1229 return superName;
1230 }
1231 svChar1 = GET_CHAR (c);
1232 INC_CHAR (c);
1233 flags=~0;
1234 switch (svChar1)
1235 {
1236 case 'M':
1237 bTyp = m_type (c, "float");
1238 break;
1239 case 'C':
1240 bTyp = m_type (c, "signed char");
1241 break;
1242 case 'D':
1243 bTyp = m_type (c, "char");
1244 break;
1245 case 'E':
1246 bTyp = m_type (c, "unsigned char");
1247 break;
1248 case 'F':
1249 bTyp = m_type (c, "short");
1250 break;
1251 case 'G':
1252 bTyp = m_type (c, "unsigned short");
1253 break;
1254 case 'H':
1255 bTyp = m_type (c, "int");
1256 break;
1257 case 'I':
1258 bTyp = m_type (c, "unsigned int");
1259 break;
1260 case 'J':
1261 bTyp = m_type (c, "long");
1262 break;
1263 case 'K':
1264 bTyp = m_type (c, "unsigned long");
1265 break;
1266 case 'N':
1267 bTyp = m_type (c, "double");
1268 break;
1269 case 'O':
1270 bTyp = m_type (c, "long double");
1271 break;
1272 case 'P':
1273 return get_pointer_reference_type (c, bTyp, superName, '*');
1274 case 'Q':
1275 if (!superName)
1276 bTyp = m_cv (c, "const");
1277 return get_pointer_reference_type (c, bTyp, superName, '*');
1278 case 'R':
1279 if (!superName)
1280 bTyp = m_cv (c, "volatile");
1281 return get_pointer_reference_type (c, bTyp, superName, '*');
1282 case 'S':
1283 if (!superName)
1284 {
1285 bTyp = m_cv (c, "const");
1286 bTyp = m_combine (c, bTyp, m_cv (c, "volatile"));
1287 }
1288 return get_pointer_reference_type (c, bTyp, superName, '*');
1289 case '_':
1290 svChar = GET_CHAR (c);
1291 INC_CHAR (c);
1292 switch(svChar)
1293 {
1294 case 'N':
1295 bTyp = m_type (c, "bool");
1296 break;
1297 case 'O':
1298 if (!superName)
1299 superName = m_name (c, "");
1300 cvName=superName;
1301 MTOKEN_FLAGS (cvName) |= MTOKEN_FLAGS_ARRAY;
1302 arType = get_pointer_reference_type (c, bTyp, cvName, 0);
1303 if (!(MTOKEN_FLAGS (arType)&MTOKEN_FLAGS_ARRAY))
1304 arType = m_combine (c, arType, m_array (c, NULL));
1305 return arType;
1306 case 'W':
1307 bTyp = m_type (c, "wchar_t");
1308 break;
1309 case 'X':
1310 case 'Y':
1311 DEC_CHAR (c);
1312 if (!(bTyp = get_ECSU_data_type (c)))
1313 return NULL;
1314 break;
1315 case 'D':
1316 bTyp = m_type (c, "__int8");
1317 break;
1318 case 'E':
1319 bTyp = m_type (c, "unsigned __int8");
1320 break;
1321 case 'F':
1322 bTyp = m_type (c, "__int16");
1323 break;
1324 case 'G':
1325 bTyp = m_type (c, "unsigned __int16");
1326 break;
1327 case 'H':
1328 bTyp = m_type (c, "__int32");
1329 break;
1330 case 'I':
1331 bTyp = m_type (c, "unsigned __int32");
1332 break;
1333 case 'J':
1334 bTyp = m_type (c, "__int64");
1335 break;
1336 case 'K':
1337 bTyp = m_type (c, "unsigned __int64");
1338 break;
1339 case 'L':
1340 bTyp = m_type (c, "__int128");
1341 break;
1342 case 'M':
1343 bTyp = m_type (c, "unsigned");
1344 break;
1345 case '$':
1346 bTyp = get_basic_data_type (c, superName);
1347 return m_combine (c, m_cv (c, "__w64"), bTyp);
1348 default:
1349 fprintf (stderr, " *** get_basic_data_type unknown '_%c' (ignored).\n", svChar);
1350 bTyp = m_type (c, "UNKNOWN");
1351 break;
1352 }
1353 break;
1354 default:
1355 DEC_CHAR (c);
1356 bTyp = get_ECSU_data_type (c);
1357 if (!bTyp)
1358 return bTyp;
1359 break;
1360 }
1361 if (superName)
1362 bTyp = m_combine (c, bTyp, superName);
1363 return bTyp;
1364 }
1365
1366 static uMToken *
get_pointer_reference_type(sMSCtx * c,uMToken * cvType,uMToken * superType,char ptrChar)1367 get_pointer_reference_type (sMSCtx *c, uMToken *cvType, uMToken *superType, char ptrChar)
1368 {
1369 uMToken *n = NULL;
1370 if (ptrChar == '&')
1371 n = m_cv (c, "&");
1372 else if (ptrChar == '*')
1373 n = m_cv (c, "*");
1374 if (GET_CHAR (c) == 0)
1375 {
1376 c->err = 2;
1377 if (cvType)
1378 {
1379 if (!n)
1380 n = cvType;
1381 else
1382 n = m_combine (c, n, cvType);
1383 }
1384 if (superType)
1385 n = m_combine (c, n, superType);
1386 return n;
1387 }
1388 if (GET_CHAR (c) < '6' || GET_CHAR (c) > '9')
1389 {
1390 if (GET_CHAR (c) != '_')
1391 return get_pointer_reference_data_type (c,
1392 get_indirect_data_type (c, superType, ptrChar, cvType, 0),(ptrChar=='*' ? 1 : 0));
1393 }
1394 if (cvType)
1395 {
1396 if (!superType || !(MTOKEN_FLAGS (superType)&MTOKEN_FLAGS_PTRREF))
1397 {
1398 if (!n)
1399 n = cvType;
1400 else
1401 n = m_combine (c, n, cvType);
1402 }
1403 }
1404 if (superType)
1405 {
1406 if (!n)
1407 n = superType;
1408 else
1409 n = m_combine (c, n, superType);
1410 }
1411 return get_indirect_function_type (c, n);
1412 }
1413
1414 static uMToken *
get_indirect_function_type(sMSCtx * c,uMToken * superType)1415 get_indirect_function_type (sMSCtx *c, uMToken *superType)
1416 {
1417 uMToken *retType = NULL;
1418 uMToken *n1 = NULL, *n2 = NULL;
1419 int flag;
1420 int cidx;
1421 char ch = GET_CHAR (c);
1422 if (ch == 0)
1423 {
1424 c->err = 2;
1425 return superType;
1426 }
1427 if (ch != '_' && (ch < '6' || ch > '9'))
1428 return NULL;
1429 cidx = (int) (ch - '6');
1430 INC_CHAR (c);
1431 if (ch == '_')
1432 {
1433 ch = GET_CHAR (c);
1434 if (ch == 0)
1435 {
1436 c->err = 2;
1437 return superType;
1438 }
1439 if (ch < 'A' || ch > 'D')
1440 return NULL;
1441 cidx=(int)(ch - 'A') + 4;
1442 INC_CHAR (c);
1443 }
1444 n2 = superType;
1445 flag = cidx & 2;
1446 if (flag)
1447 {
1448 ch = GET_CHAR (c);
1449 if (ch == 0)
1450 {
1451 c->err = 2;
1452 return n2;
1453 }
1454 n2 = m_coloncolon (c, get_scope (c), n2);
1455 if (GET_CHAR (c) == 0)
1456 {
1457 c->err = 2;
1458 return n2;
1459 }
1460 if (GET_CHAR (c) != '@')
1461 return NULL;
1462 INC_CHAR (c);
1463 n1 = get_this_type (c);
1464 }
1465 if (cidx & 4)
1466 n2 = m_combine (c, get_based_type (c), n2);
1467 n2 = m_combine (c, get_calling_convention (c), n2);
1468 if (superType)
1469 n2 = m_rframe (c, n2);
1470 retType = get_return_type (c);
1471 n2 = m_combine (c, n2, m_rframe (c, get_argument_types (c)));
1472 if (flag)
1473 n2 = m_combine (c, n2, n1);
1474 n2 = m_combine (c, n2, get_throw_types (c));
1475 return m_combine (c, retType, n2);
1476 }
1477
1478 static uMToken *
get_pointer_reference_data_type(sMSCtx * c,uMToken * superType,int isPtr)1479 get_pointer_reference_data_type (sMSCtx *c, uMToken *superType,int isPtr)
1480 {
1481 uMToken *n = NULL;
1482 if (GET_CHAR (c) == 0)
1483 {
1484 c->err = 2;
1485 return superType;
1486 }
1487
1488 if (isPtr && GET_CHAR (c) == 'X')
1489 {
1490 INC_CHAR (c);
1491 n = m_type (c, "void");
1492 if (superType)
1493 n = m_combine (c, n, superType);
1494 return n;
1495 }
1496 if (GET_CHAR (c) == 'Y')
1497 {
1498 INC_CHAR (c);
1499 return get_array_type (c, superType);
1500 }
1501 if (GET_CHAR (c) != '_')
1502 return get_basic_data_type (c, superType);
1503 if (c->pos[1] != 'Z')
1504 return get_basic_data_type (c, superType);
1505 SKIP_CHAR (c, 2);
1506 n = m_cv (c, "__box");
1507 return m_combine (c, n, get_basic_data_type (c, superType));
1508 }
1509
1510 static uMToken *
get_ECSU_data_type(sMSCtx * c)1511 get_ECSU_data_type (sMSCtx *c)
1512 {
1513 char ch = GET_CHAR (c);
1514 uMToken *n = NULL;
1515
1516 if (!ch)
1517 {
1518 c->err = 2;
1519 return m_type (c, "no-ecsu");
1520 }
1521 INC_CHAR (c);
1522 switch (ch)
1523 {
1524 default:
1525 fprintf (stderr, " *** get_ECSU_data_type unknown %c\n", ch);
1526 n = m_type (c, "unknown ecsu");
1527 break;
1528 case 'T':
1529 n = m_type (c, "union");
1530 break;
1531 case 'U':
1532 n = m_type (c, "struct");
1533 break;
1534 case 'V':
1535 n = m_type (c, "class");
1536 break;
1537 case 'W':
1538 n = m_type (c, "enum");
1539 get_enum_size_type (c);
1540 break;
1541 case 'X':
1542 n = m_type (c, "coclass");
1543 break;
1544 case 'Y':
1545 n = m_type (c, "cointerface");
1546 break;
1547 }
1548 return gen_binary (c->gc, eMST_ecsu, n, get_scoped_name (c));
1549 }
1550
1551 static uMToken *
get_string_literal_type(sMSCtx * c)1552 get_string_literal_type (sMSCtx *c)
1553 {
1554 uMToken *n = NULL;
1555 char ch = GET_CHAR (c);
1556 if (ch == 0)
1557 {
1558 c->err = 2;
1559 return NULL;
1560 }
1561 if (ch == '_')
1562 {
1563 INC_CHAR (c);
1564 n = m_cv (c, "const");
1565 }
1566 ch = GET_CHAR (c);
1567 if (GET_CHAR (c) == 0)
1568 {
1569 c->err = 2;
1570 return NULL;
1571 }
1572 INC_CHAR (c);
1573 switch (ch)
1574 {
1575 case '0':
1576 return m_combine (c, n, m_type (c, "char"));
1577 case '1':
1578 return m_combine (c, n, m_type (c, "wchar_t"));
1579 }
1580 fprintf (stderr, " *** get_string_literal_type unknown '_%c'\n", ch);
1581 return NULL;
1582 }
1583
1584 static uMToken *
get_enum_size_type(sMSCtx * c)1585 get_enum_size_type (sMSCtx *c)
1586 {
1587 uMToken *n = NULL;
1588 switch (GET_CHAR (c))
1589 {
1590 case 0:
1591 c->err = 2;
1592 return NULL;
1593 case '0':
1594 n = m_type (c, "char");
1595 break;
1596 case '1':
1597 n = m_type (c, "unsigned char");
1598 break;
1599 case '2':
1600 n = m_type (c, "short");
1601 break;
1602 case '3':
1603 n = m_type (c, "unsigned short");
1604 break;
1605 case '4':
1606 n = m_type (c, "int");
1607 break;
1608 case '5':
1609 n = m_type (c, "unsigned int");
1610 break;
1611 case '6':
1612 n = m_type (c, "long");
1613 break;
1614 case '7':
1615 n = m_type (c, "unsigned long");
1616 break;
1617 default:
1618 fprintf (stderr, " *** get_enum_size_type unknown ,%c'\n", GET_CHAR (c));
1619 return NULL;
1620 }
1621 INC_CHAR (c);
1622 return n;
1623 }
1624
1625 static uMToken *
get_this_type(sMSCtx * c)1626 get_this_type (sMSCtx *c)
1627 {
1628 return get_indirect_data_type (c, NULL, (char)0, NULL, 1);
1629 }
1630
1631 static uMToken *
get_calling_convention(sMSCtx * c)1632 get_calling_convention (sMSCtx *c)
1633 {
1634 char ch = GET_CHAR (c);
1635
1636 if (ch == 0)
1637 {
1638 c->err = 2;
1639 return NULL;
1640 }
1641 INC_CHAR (c);
1642 switch(ch)
1643 {
1644 case 'A': case 'B':
1645 return m_cv (c, "__cdecl");
1646 case 'C': case 'D':
1647 return m_cv (c, "__pascal");
1648 case 'E': case 'F':
1649 return m_cv (c, "__thiscall");
1650 case 'G': case 'H':
1651 return m_cv (c, "__stdcall");
1652 case 'I': case 'J':
1653 return m_cv (c, "__fastcall");
1654 case 'K': case 'L':
1655 return m_cv (c, "");
1656 case 'M':
1657 return m_cv (c, "__clrcall");
1658 }
1659 fprintf (stderr, " *** get_calling_convention ,%c' unknown.\n", ch);
1660 return NULL;
1661 }
1662
1663 static uMToken *
get_throw_types(sMSCtx * c)1664 get_throw_types (sMSCtx *c)
1665 {
1666 if (GET_CHAR (c) == 0)
1667 {
1668 c->err = 2;
1669 return m_throw (c, m_rframe (c, NULL));
1670 }
1671 if (GET_CHAR (c) == 'Z')
1672 {
1673 INC_CHAR (c);
1674 return m_name (c, "");
1675 }
1676 return m_throw (c, m_rframe (c, get_argument_types (c)));
1677 }
1678
1679 static uMToken *
get_argument_types(sMSCtx * c)1680 get_argument_types (sMSCtx *c)
1681 {
1682 char ch = GET_CHAR (c);
1683 uMToken *n = NULL;
1684
1685 if (ch == 'X')
1686 {
1687 INC_CHAR (c);
1688 return m_element (c, m_type (c, "void"));
1689 }
1690 if (ch == 'Z')
1691 {
1692 INC_CHAR (c);
1693 return m_element (c, m_type (c, "..."));
1694 }
1695 n = get_argument_list (c);
1696 if (!n || c->err)
1697 return n;
1698 if (GET_CHAR (c) == 0)
1699 {
1700 c->err = 2;
1701 return n;
1702 }
1703 if (GET_CHAR (c) == '@')
1704 {
1705 INC_CHAR (c);
1706 return n;
1707 }
1708 if (GET_CHAR (c) == 'Z')
1709 {
1710 INC_CHAR (c);
1711 return chain_tok (n, m_element (c, m_type (c, "...")));
1712 }
1713 fprintf (stderr, " *** get_argument_types unknown ,%c'\n", GET_CHAR (c));
1714 return NULL;
1715 }
1716
1717 static uMToken *
get_return_type(sMSCtx * c)1718 get_return_type (sMSCtx *c)
1719 {
1720 if (GET_CHAR (c) == '@')
1721 {
1722 INC_CHAR (c);
1723 return m_name (c, "");
1724 }
1725 return get_data_type (c);
1726 }
1727
1728 static int
get_number_of_dimensions(sMSCtx * c)1729 get_number_of_dimensions (sMSCtx *c)
1730 {
1731 int ret = 0;
1732 if (GET_CHAR (c))
1733 return 0;
1734 if (GET_CHAR (c) >= '0' && GET_CHAR (c) <= '9')
1735 {
1736 ret = (int) (GET_CHAR (c) - '0') + 1;
1737 INC_CHAR (c);
1738 return ret;
1739 }
1740 while (GET_CHAR (c) != '@')
1741 {
1742 if (GET_CHAR (c) == 0)
1743 return 0;
1744 if (GET_CHAR (c) < 'A' || GET_CHAR (c) > 'P')
1745 return -1;
1746 ret <<= 4;
1747 ret += (int) (GET_CHAR (c) - 'A');
1748 INC_CHAR (c);
1749 }
1750 if (GET_CHAR (c) == '@')
1751 {
1752 INC_CHAR (c);
1753 return ret;
1754 }
1755 return -1;
1756 }
1757
1758 static uMToken *
get_array_type(sMSCtx * c,uMToken * superType)1759 get_array_type (sMSCtx *c, uMToken *superType)
1760 {
1761 uMToken *n = NULL, *h = NULL;
1762 int dims;
1763
1764 if (GET_CHAR (c) == 0)
1765 {
1766 c->err = 2;
1767 if (superType)
1768 return m_combine (c, m_rframe (c, superType), m_array (c, NULL));
1769 return m_array (c, NULL);
1770 }
1771 dims = get_number_of_dimensions (c);
1772 if ( dims < 0)
1773 dims=0;
1774 if (!dims)
1775 {
1776 c->err = 2;
1777 return get_basic_data_type (c, m_array (c, NULL));
1778 }
1779 if (superType && (MTOKEN_FLAGS(superType)&MTOKEN_FLAGS_ARRAY))
1780 h = m_array (c, NULL);
1781 do {
1782 n = m_array (c, get_dimension (c, 0, 0));
1783 if (!h)
1784 h = n;
1785 else
1786 h = m_combine (c, h, n);
1787 } while (--dims != 0);
1788 if (superType)
1789 {
1790 if (!(MTOKEN_FLAGS(superType)&MTOKEN_FLAGS_ARRAY))
1791 superType = m_rframe (c, superType);
1792 h = m_combine (c, superType, h);
1793 }
1794 n = get_primary_data_type (c, h);
1795 MTOKEN_FLAGS (n) |= MTOKEN_FLAGS_ARRAY;
1796 return n;
1797 }
1798
1799 static uMToken *
get_argument_list(sMSCtx * c)1800 get_argument_list (sMSCtx *c)
1801 {
1802 uMToken *n = NULL, *h = NULL;
1803 int idx;
1804
1805 if (c->err)
1806 return NULL;
1807 do {
1808 h = NULL;
1809 if (GET_CHAR (c) == '@' || GET_CHAR (c) == 'Z')
1810 return n;
1811 if (GET_CHAR (c) == 0)
1812 {
1813 c->err = 2;
1814 return n;
1815 }
1816 idx= (int) (GET_CHAR (c) - '0');
1817 if (idx < 0 || idx > 9)
1818 {
1819 const char *svName = c->pos;
1820 h = get_primary_data_type (c, NULL);
1821 if ((size_t) (c->pos - svName)>1 && c->pArgList->count < 10)
1822 {
1823 c->pArgList->arr[c->pArgList->count]=h;
1824 c->pArgList->count += 1;
1825 }
1826 }
1827 else
1828 {
1829 INC_CHAR (c);
1830 h = c->pArgList->arr[idx];
1831 }
1832 h = m_element (c, h);
1833 n = chain_tok (n, h);
1834 } while (c->err != 2);
1835 return n;
1836 }
1837
1838 static uMToken *
get_vdisp_map_type(sMSCtx * c,uMToken * superType)1839 get_vdisp_map_type (sMSCtx *c, uMToken *superType)
1840 {
1841 uMToken *n = superType;
1842 uMToken *h = get_scope (c);
1843 h = m_combine (c, m_name (c, "for"), h);
1844 h = m_frame (c, h);
1845 n = m_combine (c, n, h);
1846 if (GET_CHAR (c) =='@')
1847 INC_CHAR (c);
1848 return n;
1849 }
1850
1851 static uMToken *
get_ext_data_type(sMSCtx * c,uMToken * superType)1852 get_ext_data_type (sMSCtx *c, uMToken *superType)
1853 {
1854 uMToken *dt = NULL,*n = NULL;
1855 dt = get_data_type (c);
1856 n = get_indirect_data_type (c, NULL, (char)0, NULL, 0);
1857 if (superType)
1858 n = m_combine (c, n, superType);
1859
1860 return m_combine (c, dt, n);
1861 }
1862
getVCallThunkType(sMSCtx * c)1863 static uMToken *getVCallThunkType(sMSCtx *c)
1864 {
1865 if (GET_CHAR (c) == 0)
1866 {
1867 c->err = 2;
1868 return NULL;
1869 }
1870 if (GET_CHAR (c) != 'A')
1871 {
1872 fprintf (stderr, " *** getVCallThunkType unknown '%c'\n", GET_CHAR (c));
1873 return NULL;
1874 }
1875 INC_CHAR (c);
1876 return m_cv (c, "{flat}");
1877 }
1878
1879 static uMToken *
get_vftable_type(sMSCtx * c,uMToken * superType)1880 get_vftable_type (sMSCtx *c, uMToken *superType)
1881 {
1882 uMToken *n = superType;
1883 if (c->err || GET_CHAR (c) == 0)
1884 {
1885 c->err = 2;
1886 return n;
1887 }
1888 n = m_combine (c, get_indirect_data_type (c, NULL, (char)0, NULL, 0), n);
1889 if (c->err == 2 || !n)
1890 return n;
1891 if (GET_CHAR (c) != '@')
1892 {
1893 n = m_combine (c, n, m_name (c, "{for "));
1894 while (c->err == 0)
1895 {
1896 if (GET_CHAR (c) ==0 || GET_CHAR (c) =='@')
1897 break;
1898 n = m_combine (c, n, m_lexical_frame (c, get_scope (c)));
1899 if (GET_CHAR (c) == '@')
1900 INC_CHAR (c);
1901 if (c->err == 0 && GET_CHAR (c) != '@')
1902 n = m_combine (c, n, m_name (c, "s "));
1903 }
1904 if (c->err == 0)
1905 {
1906 if (GET_CHAR (c) == 0)
1907 c->err = 2;
1908 n = m_combine (c, n, m_name (c, "}"));
1909 }
1910 if (GET_CHAR (c) != '@')
1911 return n;
1912 }
1913 INC_CHAR (c);
1914 return n;
1915 }
1916
1917 static uMToken *
compose_decl(sMSCtx * c,uMToken * symbol)1918 compose_decl (sMSCtx *c, uMToken *symbol)
1919 {
1920 uMToken *n = NULL;
1921 int et = get_encoded_type (c);
1922 int nIsUDC = (symbol && (MTOKEN_FLAGS (symbol) & MTOKEN_FLAGS_UDC)) ? 1 : 0;
1923 if (et==0xffff)
1924 return NULL;
1925 if (et==0xfffe)
1926 {
1927 c->err = 2;
1928 return symbol;
1929 }
1930 if (et==0xfffd)
1931 return symbol;
1932 if ((et&0x8000)==0)
1933 {
1934 n = symbol;
1935 if ((et&0x7c00)==0x6800)
1936 return get_vftable_type (c, n);
1937 if ((et&0x7c00)==0x7000)
1938 return get_vftable_type (c, n);
1939 if ((et&0x7c00)==0x6000)
1940 {
1941 uMToken *ll = m_element (c, get_dimension (c, 0, 0));
1942 ll = m_frame (c, ll);
1943 return m_combine (c, n, ll);
1944 }
1945 if ((et&0x7c00)==0x7c00)
1946 return get_vdisp_map_type (c, n);
1947 if ((et&0x7c00)==0x7800)
1948 return n;
1949 n = get_ext_data_type (c, n);
1950 if ((et&0x6000)!=0)
1951 {
1952 if ((et&0x1000))
1953 n = m_combine (c, m_colon (c, "[thunk]"), n);
1954 return n;
1955 }
1956 n = m_combine (c, m_cv (c, "static"), n);
1957 if ((et&0x700) == 0x400 || (et&0x700) == 0x500)
1958 n = m_combine (c, m_cv (c, "virtual"), n);
1959 switch ((et&0x1800))
1960 {
1961 case 0x800:
1962 n = m_combine (c, m_colon (c, "private"), n);
1963 break;
1964 case 0x1000:
1965 n = m_combine (c, m_colon (c, "protected"), n);
1966 break;
1967 case 0x0:
1968 n = m_combine (c, m_colon (c, "public"), n);
1969 break;
1970 }
1971 if ((et&0x400))
1972 n = m_combine (c, m_colon (c, "[thunk]"), n);
1973 return n;
1974 }
1975 if ((et&0x1f00)==0x1000 || (et&0x1f00)==0x1400)
1976 {
1977 n = symbol;
1978 if ((et&0x6000)!=0 || (et&0x7f00)==0x1400)
1979 n = m_combine (c, n, m_name (c, "local_static_destructor_helper"));
1980 n = get_ext_data_type (c, n);
1981 symbol = NULL;
1982 }
1983 else if ((et&0x1f00)==0x1500 || (et&0x1f00)==0x1600)
1984 {
1985 n = symbol;
1986 symbol = NULL;
1987 if ((et&0x1f00)==0x1500)
1988 n = m_combine (c, n, m_name (c, "template_static_data_member_constructor_helper"));
1989 else if ((et&0x1f00)==0x1600)
1990 n = m_combine (c, n, m_name (c, "template_static_data_member_destructor_helper"));
1991 }
1992 else
1993 {
1994 if ((et&0x4000)!=0)
1995 n = get_based_type (c);
1996 if ((et&0x1800)==0x1800)
1997 {
1998 uMToken *hh = NULL;
1999 hh = m_element (c, get_dimension (c, 0, 0));
2000 hh = chain_tok (hh, m_element (c, getVCallThunkType (c)));
2001 n = m_combine (c, symbol,
2002 m_frame (c, hh));
2003 n = m_combine (c, get_calling_convention (c), n);
2004 }
2005 else
2006 {
2007 uMToken *h = NULL;
2008 uMToken *n1 = NULL;
2009 uMToken *n2 = NULL;
2010 uMToken *n3 = NULL;
2011 if ((et&0x1000)!=0 || (et&0x1c00)==0xc00)
2012 {
2013 if ((et&0x1f00)==0xd00)
2014 n1 = get_dimension (c, 1, 0);
2015 n2 = get_dimension (c, 1, 0);
2016 }
2017 if (((et&0x1800)==0x800) && (et&0x700)!=0x200)
2018 n3 = get_this_type (c);
2019 n = m_combine (c, get_calling_convention (c), n);
2020 if (symbol)
2021 n = m_combine (c, n, symbol);
2022
2023 if (nIsUDC)
2024 n = m_combine (c, n, get_return_type (c));
2025 h = get_return_type (c);
2026 if (((et&0x1800)!=0x800 ? (et&0x1000)!=0 : (et&0x400)!=0))
2027 {
2028 if (((et&0x1800)==0x800) && (et&0x700)==0x500)
2029 {
2030 n2 = chain_tok (
2031 m_element (c, n1),
2032 m_element (c, n2));
2033 n2 = m_frame (c, n2);
2034 n = m_combine (c, n, m_combine (c, m_name (c, "vtordisp"), n2));
2035 }
2036 else
2037 {
2038 n2 = m_frame (c, m_element (c, n2));
2039 n = m_combine (c, n, m_combine (c, m_name (c, "adjustor"), n2));
2040 }
2041 }
2042 n = m_combine (c, n, m_rframe (c, get_argument_types (c)));
2043 if (((et&0x1800)==0x800) && (et&0x700)!=0x200)
2044 n = m_combine (c, n, n3);
2045 n = m_combine (c, n, get_throw_types (c));
2046 if (h)
2047 n = m_combine (c, h, n);
2048 }
2049 }
2050 if ((et&0x1800)!=0x800) {
2051 if ((et&0x1000))
2052 n = m_combine (c, m_colon (c, "[thunk]"), n);
2053 return n;
2054 }
2055 switch ((et&0x700))
2056 {
2057 case 0x200:
2058 n = m_combine (c, m_cv (c, "static"), n);
2059 break;
2060 case 0x100:
2061 case 0x400:
2062 case 0x500:
2063 n = m_combine (c, m_cv (c, "virtual"), n);
2064 break;
2065 }
2066 switch ((et&0xc0))
2067 {
2068 case 0x40:
2069 n = m_combine (c, m_colon (c, "private"), n);
2070 break;
2071 case 0x80:
2072 n = m_combine (c, m_colon (c, "protected"), n);
2073 break;
2074 case 0x0:
2075 n = m_combine (c, m_colon (c, "public"), n);
2076 break;
2077 }
2078 if ((et&0x400))
2079 n = m_combine (c, m_colon (c, "[thunk]"), n);
2080 return n;
2081 }
2082
2083 static int
get_encoded_type(sMSCtx * c)2084 get_encoded_type (sMSCtx *c)
2085 {
2086 int ret;
2087
2088 for(;;)
2089 {
2090 ret = 0;
2091 if (GET_CHAR (c) == '_')
2092 {
2093 INC_CHAR (c);
2094 ret = 0x4000;
2095 }
2096 if (GET_CHAR (c) >= 'A' && GET_CHAR (c) <= 'Z')
2097 {
2098 int chc = (int) (GET_CHAR (c) - 'A');
2099 INC_CHAR (c);
2100 if ((chc & 1) == 0)
2101 ret |= 0x8000;
2102 else
2103 ret |= 0xa000;
2104 if (chc >= 0x18)
2105 return ret;
2106 ret |= 0x800;
2107 switch((chc&0x18))
2108 {
2109 case 0:
2110 ret |= 0x40;
2111 break;
2112 case 8:
2113 ret |= 0x80;
2114 break;
2115 case 0x10:
2116 break;
2117 }
2118 switch((chc&6))
2119 {
2120 case 0:
2121 return ret;
2122 case 2:
2123 return ret|0x200;
2124 case 4:
2125 return ret|0x100;
2126 case 6:
2127 return ret|0x400;
2128 }
2129 return 0xffff;
2130 }
2131 if (GET_CHAR (c) != '$')
2132 {
2133 INC_CHAR (c);
2134 switch(c->pos[-1])
2135 {
2136 case '0':
2137 return 0x800;
2138 case '1':
2139 return 0x1000;
2140 case '2':
2141 return 0;
2142 case '3':
2143 return 0x4000;
2144 case '4':
2145 return 0x2000;
2146 case '5':
2147 return 0x6000;
2148 case '6':
2149 return 0x6800;
2150 case '7':
2151 return 0x7000;
2152 case '8':
2153 return 0x7800;
2154 case '9':
2155 return 0xfffd;
2156 case 0:
2157 DEC_CHAR (c);
2158 return 0xfffe;
2159 }
2160 DEC_CHAR (c);
2161 return 0xffff;
2162 }
2163 INC_CHAR (c);
2164 switch(GET_CHAR (c))
2165 {
2166 case 'A':
2167 INC_CHAR (c);
2168 return ret|0x9000;
2169 case 'B':
2170 INC_CHAR (c);
2171 return ret|0x9800;
2172 case 'C':
2173 INC_CHAR (c);
2174 return ret|0x7c00;
2175 case 'D':
2176 INC_CHAR (c);
2177 return ret|0x9100;
2178 case 'E':
2179 INC_CHAR (c);
2180 return ret|0x9200;
2181 case 0:
2182 INC_CHAR (c);
2183 return 0xfffe;
2184 case '0':
2185 INC_CHAR (c);
2186 return ret|0x8d40;
2187 case '1':
2188 INC_CHAR (c);
2189 return ret|0xad40;
2190 case '2':
2191 INC_CHAR (c);
2192 return ret|0x8d80;
2193 case '3':
2194 INC_CHAR (c);
2195 return ret|0xad80;
2196 case '4':
2197 INC_CHAR (c);
2198 return ret|0x8d00;
2199 case '5':
2200 INC_CHAR (c);
2201 return ret|0xad00;
2202 case '$':
2203 if (c->pos[1] == 'P')
2204 INC_CHAR (c);
2205 break;
2206 default:
2207 return 0xffff;
2208 }
2209 INC_CHAR (c);
2210 switch(GET_CHAR (c))
2211 {
2212 case 'F': case 'G': case 'H': case 'I': case 'L': case 'M':
2213 INC_CHAR (c);
2214 break;
2215 case 'J': case 'K': case 'N': case 'O':
2216 INC_CHAR (c);
2217 if (GET_CHAR (c) < '0' || GET_CHAR (c) > '9')
2218 {
2219 INC_CHAR (c);
2220 return 0xffff;
2221 }
2222 {
2223 int skip = (GET_CHAR (c) - '0') + 1;
2224 SKIP_CHAR (c, skip);
2225 }
2226 break;
2227 default:
2228 INC_CHAR (c);
2229 return ret;
2230 }
2231 }
2232 }
2233
2234 static uMToken *
m_combine(sMSCtx * c,uMToken * l,uMToken * r)2235 m_combine (sMSCtx *c, uMToken *l, uMToken *r)
2236 {
2237 if (!l && !r)
2238 return NULL;
2239 if (!l)
2240 return r;
2241 if (!r)
2242 return l;
2243 return gen_binary (c->gc, eMST_combine, l, r);
2244 }
2245
2246 static uMToken *
m_type(sMSCtx * c,const char * typname)2247 m_type (sMSCtx *c, const char *typname)
2248 {
2249 return gen_name (c->gc, eMST_type, typname);
2250 }
2251
2252 static uMToken *
m_cv(sMSCtx * c,const char * cv)2253 m_cv (sMSCtx *c, const char *cv)
2254 {
2255 return gen_name (c->gc, eMST_cv, cv);
2256 }
2257
2258 static uMToken *
m_coloncolon(sMSCtx * c,uMToken * l,uMToken * r)2259 m_coloncolon (sMSCtx *c, uMToken *l, uMToken *r)
2260 {
2261 if (!l)
2262 return r;
2263 if (!r)
2264 return l;
2265 return gen_binary (c->gc, eMST_coloncolon, l, r);
2266 }
2267
2268 static uMToken *
m_element(sMSCtx * c,uMToken * el)2269 m_element (sMSCtx *c, uMToken *el)
2270 {
2271 return gen_unary (c->gc, eMST_element, el);
2272 }
2273
2274 static uMToken *
m_array(sMSCtx * c,uMToken * dim)2275 m_array (sMSCtx *c, uMToken *dim)
2276 {
2277 return gen_unary (c->gc, eMST_array, dim);
2278 }
2279
2280 static uMToken *
m_scope(sMSCtx * c,uMToken * n)2281 m_scope (sMSCtx *c, uMToken *n)
2282 {
2283 return gen_unary (c->gc, eMST_scope, n);
2284 }
2285
2286 static uMToken *
m_oper(sMSCtx * c,uMToken * n)2287 m_oper (sMSCtx *c, uMToken *n)
2288 {
2289 return gen_unary (c->gc, eMST_oper, n);
2290 }
2291
2292 static uMToken *
m_name(sMSCtx * c,const char * str)2293 m_name (sMSCtx *c, const char *str)
2294 {
2295 return gen_name (c->gc, eMST_name, str);
2296 }
2297
2298 static uMToken *
m_colon(sMSCtx * c,const char * str)2299 m_colon (sMSCtx *c, const char *str)
2300 {
2301 return gen_name (c->gc, eMST_colon, str);
2302 }
2303
2304 static uMToken *
m_opname(sMSCtx * c,const char * str)2305 m_opname (sMSCtx *c, const char *str)
2306 {
2307 return gen_name (c->gc, eMST_opname, str);
2308 }
2309
2310 static uMToken *
m_rtti(sMSCtx * c,const char * str)2311 m_rtti (sMSCtx *c, const char *str)
2312 {
2313 return gen_name (c->gc, eMST_rtti, str);
2314 }
2315
2316 static uMToken *
m_frame(sMSCtx * c,uMToken * u)2317 m_frame (sMSCtx *c, uMToken *u)
2318 {
2319 return gen_unary (c->gc, eMST_frame, u);
2320 }
2321
2322 static uMToken *
m_rframe(sMSCtx * c,uMToken * u)2323 m_rframe (sMSCtx *c, uMToken *u)
2324 {
2325 return gen_unary (c->gc, eMST_rframe, u);
2326 }
2327
2328 static uMToken *
m_ltgt(sMSCtx * c,uMToken * u)2329 m_ltgt (sMSCtx *c, uMToken *u)
2330 {
2331 return gen_unary (c->gc, eMST_ltgt, u);
2332 }
2333
2334 static uMToken *
m_throw(sMSCtx * c,uMToken * u)2335 m_throw (sMSCtx *c, uMToken *u)
2336 {
2337 return gen_unary (c->gc, eMST_throw, u);
2338 }
2339
2340 static uMToken *
m_lexical_frame(sMSCtx * c,uMToken * u)2341 m_lexical_frame (sMSCtx *c, uMToken *u)
2342 {
2343 return gen_unary (c->gc, eMST_lexical_frame, u);
2344 }
2345