~steve-sk2/mingw-w64/oneiric

« back to all changes in this revision

Viewing changes to mingw-w64-libraries/libmangle/src/m_ms.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen Kitt
  • Date: 2010-11-18 00:04:46 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20101118000446-xe24b423su55onyl
Tags: 1.0+20101003-1
* New maintainer. (Closes: #594371.)
* New upstream snapshot:
  - Includes getopt.h. (Closes: #569914.)
* Build g++ for Win64. (Closes: #600451.)
* Standards-Version 3.9.1 (new packaging).
* Include patch from
  http://mingw-w64.svn.sourceforge.net/viewvc/mingw-w64?view=revision&revision=3715
  as suggested by Rafaël Carré.

Show diffs side-by-side

added added

removed removed

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