• 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 
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