xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/d/dmd/dmangle.c (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4  * written by Walter Bright
5  * http://www.digitalmars.com
6  * Distributed under the Boost Software License, Version 1.0.
7  * http://www.boost.org/LICENSE_1_0.txt
8  * https://github.com/D-Programming-Language/dmd/blob/master/src/mangle.c
9  */
10 
11 #include "root/dsystem.h"
12 #include "root/root.h"
13 
14 #include "mangle.h"
15 #include "init.h"
16 #include "declaration.h"
17 #include "aggregate.h"
18 #include "mtype.h"
19 #include "attrib.h"
20 #include "target.h"
21 #include "template.h"
22 #include "id.h"
23 #include "module.h"
24 #include "enum.h"
25 #include "expression.h"
26 #include "utf.h"
27 
28 typedef int (*ForeachDg)(void *ctx, size_t paramidx, Parameter *param);
29 int Parameter_foreach(Parameters *parameters, ForeachDg dg, void *ctx, size_t *pn = NULL);
30 
31 static const char *mangleChar[TMAX];
32 
initTypeMangle()33 void initTypeMangle()
34 {
35     mangleChar[Tarray] = "A";
36     mangleChar[Tsarray] = "G";
37     mangleChar[Taarray] = "H";
38     mangleChar[Tpointer] = "P";
39     mangleChar[Treference] = "R";
40     mangleChar[Tfunction] = "F";
41     mangleChar[Tident] = "I";
42     mangleChar[Tclass] = "C";
43     mangleChar[Tstruct] = "S";
44     mangleChar[Tenum] = "E";
45     mangleChar[Tdelegate] = "D";
46 
47     mangleChar[Tnone] = "n";
48     mangleChar[Tvoid] = "v";
49     mangleChar[Tint8] = "g";
50     mangleChar[Tuns8] = "h";
51     mangleChar[Tint16] = "s";
52     mangleChar[Tuns16] = "t";
53     mangleChar[Tint32] = "i";
54     mangleChar[Tuns32] = "k";
55     mangleChar[Tint64] = "l";
56     mangleChar[Tuns64] = "m";
57     mangleChar[Tint128] = "zi";
58     mangleChar[Tuns128] = "zk";
59     mangleChar[Tfloat32] = "f";
60     mangleChar[Tfloat64] = "d";
61     mangleChar[Tfloat80] = "e";
62 
63     mangleChar[Timaginary32] = "o";
64     mangleChar[Timaginary64] = "p";
65     mangleChar[Timaginary80] = "j";
66     mangleChar[Tcomplex32] = "q";
67     mangleChar[Tcomplex64] = "r";
68     mangleChar[Tcomplex80] = "c";
69 
70     mangleChar[Tbool] = "b";
71     mangleChar[Tchar] = "a";
72     mangleChar[Twchar] = "u";
73     mangleChar[Tdchar] = "w";
74 
75     // '@' shouldn't appear anywhere in the deco'd names
76     mangleChar[Tinstance] = "@";
77     mangleChar[Terror] = "@";
78     mangleChar[Ttypeof] = "@";
79     mangleChar[Ttuple] = "B";
80     mangleChar[Tslice] = "@";
81     mangleChar[Treturn] = "@";
82     mangleChar[Tvector] = "@";
83     mangleChar[Ttraits] = "@";
84 
85     mangleChar[Tnull] = "n";    // same as TypeNone
86 
87     for (size_t i = 0; i < TMAX; i++)
88     {
89         if (!mangleChar[i])
90             fprintf(stderr, "ty = %llu\n", (ulonglong)i);
91         assert(mangleChar[i]);
92     }
93 }
94 
95 /*********************************
96  * Mangling for mod.
97  */
MODtoDecoBuffer(OutBuffer * buf,MOD mod)98 void MODtoDecoBuffer(OutBuffer *buf, MOD mod)
99 {
100     switch (mod)
101     {
102         case 0:
103             break;
104         case MODconst:
105             buf->writeByte('x');
106             break;
107         case MODimmutable:
108             buf->writeByte('y');
109             break;
110         case MODshared:
111             buf->writeByte('O');
112             break;
113         case MODshared | MODconst:
114             buf->writestring("Ox");
115             break;
116         case MODwild:
117             buf->writestring("Ng");
118             break;
119         case MODwildconst:
120             buf->writestring("Ngx");
121             break;
122         case MODshared | MODwild:
123             buf->writestring("ONg");
124             break;
125         case MODshared | MODwildconst:
126             buf->writestring("ONgx");
127             break;
128         default:
129             assert(0);
130     }
131 }
132 
133 class Mangler : public Visitor
134 {
135 public:
136     OutBuffer *buf;
137 
Mangler(OutBuffer * buf)138     Mangler(OutBuffer *buf)
139     {
140         this->buf = buf;
141     }
142 
143 
144     ////////////////////////////////////////////////////////////////////////////
145 
146     /**************************************************
147      * Type mangling
148      */
149 
visitWithMask(Type * t,unsigned char modMask)150     void visitWithMask(Type *t, unsigned char modMask)
151     {
152         if (modMask != t->mod)
153         {
154             MODtoDecoBuffer(buf, t->mod);
155         }
156         t->accept(this);
157     }
158 
visit(Type * t)159     void visit(Type *t)
160     {
161         buf->writestring(mangleChar[t->ty]);
162     }
163 
visit(TypeNext * t)164     void visit(TypeNext *t)
165     {
166         visit((Type *)t);
167         visitWithMask(t->next, t->mod);
168     }
169 
visit(TypeVector * t)170     void visit(TypeVector *t)
171     {
172         buf->writestring("Nh");
173         visitWithMask(t->basetype, t->mod);
174     }
175 
visit(TypeSArray * t)176     void visit(TypeSArray *t)
177     {
178         visit((Type *)t);
179         if (t->dim)
180             buf->print(t->dim->toInteger());
181         if (t->next)
182             visitWithMask(t->next, t->mod);
183     }
184 
visit(TypeDArray * t)185     void visit(TypeDArray *t)
186     {
187         visit((Type *)t);
188         if (t->next)
189             visitWithMask(t->next, t->mod);
190     }
191 
visit(TypeAArray * t)192     void visit(TypeAArray *t)
193     {
194         visit((Type *)t);
195         visitWithMask(t->index, 0);
196         visitWithMask(t->next, t->mod);
197     }
198 
visit(TypeFunction * t)199     void visit(TypeFunction *t)
200     {
201         //printf("TypeFunction::toDecoBuffer() t = %p %s\n", t, t->toChars());
202         //static int nest; if (++nest == 50) *(char*)0=0;
203 
204         mangleFuncType(t, t, t->mod, t->next);
205     }
206 
mangleFuncType(TypeFunction * t,TypeFunction * ta,unsigned char modMask,Type * tret)207     void mangleFuncType(TypeFunction *t, TypeFunction *ta, unsigned char modMask, Type *tret)
208     {
209         //printf("mangleFuncType() %s\n", t->toChars());
210         if (t->inuse)
211         {
212             t->inuse = 2;       // flag error to caller
213             return;
214         }
215         t->inuse++;
216 
217         if (modMask != t->mod)
218             MODtoDecoBuffer(buf, t->mod);
219 
220         unsigned char mc;
221         switch (t->linkage)
222         {
223             case LINKd:             mc = 'F';       break;
224             case LINKc:             mc = 'U';       break;
225             case LINKwindows:       mc = 'W';       break;
226             case LINKpascal:        mc = 'V';       break;
227             case LINKcpp:           mc = 'R';       break;
228             case LINKobjc:          mc = 'Y';       break;
229             default:
230                 assert(0);
231         }
232         buf->writeByte(mc);
233 
234         if (ta->purity || ta->isnothrow || ta->isnogc || ta->isproperty || ta->isref || ta->trust || ta->isreturn || ta->isscope)
235         {
236             if (ta->purity)
237                 buf->writestring("Na");
238             if (ta->isnothrow)
239                 buf->writestring("Nb");
240             if (ta->isref)
241                 buf->writestring("Nc");
242             if (ta->isproperty)
243                 buf->writestring("Nd");
244             if (ta->isnogc)
245                 buf->writestring("Ni");
246             if (ta->isreturn)
247                 buf->writestring("Nj");
248             if (ta->isscope && !ta->isreturn && !ta->isscopeinferred)
249                 buf->writestring("Nl");
250             switch (ta->trust)
251             {
252                 case TRUSTtrusted:
253                     buf->writestring("Ne");
254                     break;
255                 case TRUSTsafe:
256                     buf->writestring("Nf");
257                     break;
258                 default:
259                     break;
260             }
261         }
262 
263         // Write argument types
264         paramsToDecoBuffer(t->parameters);
265         //if (buf->data[buf->offset - 1] == '@') halt();
266         buf->writeByte('Z' - t->varargs);   // mark end of arg list
267         if (tret != NULL)
268             visitWithMask(tret, 0);
269 
270         t->inuse--;
271     }
272 
visit(TypeIdentifier * t)273     void visit(TypeIdentifier *t)
274     {
275         visit((Type *)t);
276         const char *name = t->ident->toChars();
277         size_t len = strlen(name);
278         buf->print(len);
279         buf->writestring(name);
280     }
281 
visit(TypeEnum * t)282     void visit(TypeEnum *t)
283     {
284         visit((Type *)t);
285         t->sym->accept(this);
286     }
287 
visit(TypeStruct * t)288     void visit(TypeStruct *t)
289     {
290         //printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", t->toChars(), name);
291         visit((Type *)t);
292         t->sym->accept(this);
293     }
294 
visit(TypeClass * t)295     void visit(TypeClass *t)
296     {
297         //printf("TypeClass::toDecoBuffer('%s' mod=%x) = '%s'\n", t->toChars(), mod, name);
298         visit((Type *)t);
299         t->sym->accept(this);
300     }
301 
visit(TypeTuple * t)302     void visit(TypeTuple *t)
303     {
304         //printf("TypeTuple::toDecoBuffer() t = %p, %s\n", t, t->toChars());
305         visit((Type *)t);
306 
307         OutBuffer buf2;
308         buf2.reserve(32);
309         Mangler v(&buf2);
310         v.paramsToDecoBuffer(t->arguments);
311         const char *s = buf2.peekString();
312         int len = (int)buf2.offset;
313         buf->printf("%d%.*s", len, len, s);
314     }
315 
visit(TypeNull * t)316     void visit(TypeNull *t)
317     {
318         visit((Type *)t);
319     }
320 
321     ////////////////////////////////////////////////////////////////////////////
322 
mangleDecl(Declaration * sthis)323     void mangleDecl(Declaration *sthis)
324     {
325         mangleParent(sthis);
326 
327         assert(sthis->ident);
328         const char *id = sthis->ident->toChars();
329         toBuffer(id, sthis);
330 
331         if (FuncDeclaration *fd = sthis->isFuncDeclaration())
332         {
333             mangleFunc(fd, false);
334         }
335         else if (sthis->type->deco)
336         {
337             buf->writestring(sthis->type->deco);
338         }
339         else
340             assert(0);
341     }
342 
mangleParent(Dsymbol * s)343     void mangleParent(Dsymbol *s)
344     {
345         Dsymbol *p;
346         if (TemplateInstance *ti = s->isTemplateInstance())
347             p = ti->isTemplateMixin() ? ti->parent : ti->tempdecl->parent;
348         else
349             p = s->parent;
350 
351         if (p)
352         {
353             mangleParent(p);
354 
355             if (p->getIdent())
356             {
357                 const char *id = p->ident->toChars();
358                 toBuffer(id, s);
359 
360                 if (FuncDeclaration *f = p->isFuncDeclaration())
361                     mangleFunc(f, true);
362             }
363             else
364                 buf->writeByte('0');
365         }
366     }
367 
mangleFunc(FuncDeclaration * fd,bool inParent)368     void mangleFunc(FuncDeclaration *fd, bool inParent)
369     {
370         //printf("deco = '%s'\n", fd->type->deco ? fd->type->deco : "null");
371         //printf("fd->type = %s\n", fd->type->toChars());
372         if (fd->needThis() || fd->isNested())
373             buf->writeByte('M');
374         if (inParent)
375         {
376             TypeFunction *tf = (TypeFunction *)fd->type;
377             TypeFunction *tfo = (TypeFunction *)fd->originalType;
378             mangleFuncType(tf, tfo, 0, NULL);
379         }
380         else if (fd->type->deco)
381         {
382             buf->writestring(fd->type->deco);
383         }
384         else
385         {
386             printf("[%s] %s %s\n", fd->loc.toChars(), fd->toChars(), fd->type->toChars());
387             assert(0);  // don't mangle function until semantic3 done.
388         }
389     }
390 
391     /************************************************************
392      * Write length prefixed string to buf.
393      */
toBuffer(const char * id,Dsymbol * s)394     void toBuffer(const char *id, Dsymbol *s)
395     {
396         size_t len = strlen(id);
397         if (len >= 8 * 1024 * 1024)         // 8 megs ought be enough for anyone
398             s->error("excessive length %llu for symbol, possible recursive expansion?", len);
399         else
400         {
401             buf->print(len);
402             buf->write(id, len);
403         }
404     }
405 
visit(Declaration * d)406     void visit(Declaration *d)
407     {
408         //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n",
409         //        d, d->toChars(), d->parent ? d->parent->toChars() : "null", d->linkage);
410         if (!d->parent || d->parent->isModule() || d->linkage == LINKcpp) // if at global scope
411         {
412             switch (d->linkage)
413             {
414                 case LINKd:
415                     break;
416 
417                 case LINKc:
418                 case LINKwindows:
419                 case LINKpascal:
420                 case LINKobjc:
421                     buf->writestring(d->ident->toChars());
422                     return;
423 
424                 case LINKcpp:
425                     buf->writestring(Target::toCppMangle(d));
426                     return;
427 
428                 case LINKdefault:
429                     d->error("forward declaration");
430                     buf->writestring(d->ident->toChars());
431                     return;
432 
433                 default:
434                     fprintf(stderr, "'%s', linkage = %d\n", d->toChars(), d->linkage);
435                     assert(0);
436                     return;
437             }
438         }
439 
440         buf->writestring("_D");
441         mangleDecl(d);
442     }
443 
444     /******************************************************************************
445      * Normally FuncDeclaration and FuncAliasDeclaration have overloads.
446      * If and only if there is no overloads, mangle() could return
447      * exact mangled name.
448      *
449      *      module test;
450      *      void foo(long) {}           // _D4test3fooFlZv
451      *      void foo(string) {}         // _D4test3fooFAyaZv
452      *
453      *      // from FuncDeclaration::mangle().
454      *      pragma(msg, foo.mangleof);  // prints unexact mangled name "4test3foo"
455      *                                  // by calling Dsymbol::mangle()
456      *
457      *      // from FuncAliasDeclaration::mangle()
458      *      pragma(msg, __traits(getOverloads, test, "foo")[0].mangleof);  // "_D4test3fooFlZv"
459      *      pragma(msg, __traits(getOverloads, test, "foo")[1].mangleof);  // "_D4test3fooFAyaZv"
460      *
461      * If a function has no overloads, .mangleof property still returns exact mangled name.
462      *
463      *      void bar() {}
464      *      pragma(msg, bar.mangleof);  // still prints "_D4test3barFZv"
465      *                                  // by calling FuncDeclaration::mangleExact().
466      */
visit(FuncDeclaration * fd)467     void visit(FuncDeclaration *fd)
468     {
469         if (fd->isUnique())
470             mangleExact(fd);
471         else
472             visit((Dsymbol *)fd);
473     }
474 
475     // ditto
visit(FuncAliasDeclaration * fd)476     void visit(FuncAliasDeclaration *fd)
477     {
478         FuncDeclaration *f = fd->toAliasFunc();
479         FuncAliasDeclaration *fa = f->isFuncAliasDeclaration();
480         if (!fd->hasOverloads && !fa)
481         {
482             mangleExact(f);
483             return;
484         }
485         if (fa)
486         {
487             fa->accept(this);
488             return;
489         }
490         visit((Dsymbol *)fd);
491     }
492 
visit(OverDeclaration * od)493     void visit(OverDeclaration *od)
494     {
495         if (od->overnext)
496         {
497             visit((Dsymbol *)od);
498             return;
499         }
500 
501         if (FuncDeclaration *fd = od->aliassym->isFuncDeclaration())
502         {
503             if (!od->hasOverloads || fd->isUnique())
504             {
505                 mangleExact(fd);
506                 return;
507             }
508         }
509         if (TemplateDeclaration *td = od->aliassym->isTemplateDeclaration())
510         {
511             if (!od->hasOverloads || td->overnext == NULL)
512             {
513                 td->accept(this);
514                 return;
515             }
516         }
517         visit((Dsymbol *)od);
518     }
519 
mangleExact(FuncDeclaration * fd)520     void mangleExact(FuncDeclaration *fd)
521     {
522         assert(!fd->isFuncAliasDeclaration());
523 
524         if (fd->mangleOverride)
525         {
526             buf->writestring(fd->mangleOverride);
527             return;
528         }
529 
530         if (fd->isMain())
531         {
532             buf->writestring("_Dmain");
533             return;
534         }
535 
536         if (fd->isWinMain() || fd->isDllMain() || fd->ident == Id::tls_get_addr)
537         {
538             buf->writestring(fd->ident->toChars());
539             return;
540         }
541 
542         visit((Declaration *)fd);
543     }
544 
visit(VarDeclaration * vd)545     void visit(VarDeclaration *vd)
546     {
547         if (vd->mangleOverride)
548         {
549             buf->writestring(vd->mangleOverride);
550             return;
551         }
552 
553         visit((Declaration *)vd);
554     }
555 
visit(AggregateDeclaration * ad)556     void visit(AggregateDeclaration *ad)
557     {
558         ClassDeclaration *cd = ad->isClassDeclaration();
559         Dsymbol *parentsave = ad->parent;
560         if (cd)
561         {
562             /* These are reserved to the compiler, so keep simple
563              * names for them.
564              */
565             if ((cd->ident == Id::Exception && cd->parent->ident == Id::object) ||
566                 cd->ident == Id::TypeInfo ||
567                 cd->ident == Id::TypeInfo_Struct ||
568                 cd->ident == Id::TypeInfo_Class ||
569                 cd->ident == Id::TypeInfo_Tuple ||
570                 cd == ClassDeclaration::object ||
571                 cd == Type::typeinfoclass ||
572                 cd == Module::moduleinfo ||
573                 strncmp(cd->ident->toChars(), "TypeInfo_", 9) == 0)
574             {
575                 // Don't mangle parent
576                 ad->parent = NULL;
577             }
578         }
579 
580         visit((Dsymbol *)ad);
581 
582         ad->parent = parentsave;
583     }
584 
visit(TemplateInstance * ti)585     void visit(TemplateInstance *ti)
586     {
587         if (!ti->tempdecl)
588             ti->error("is not defined");
589         else
590             mangleParent(ti);
591 
592         ti->getIdent();
593         const char *id = ti->ident ? ti->ident->toChars() : ti->toChars();
594         toBuffer(id, ti);
595 
596         //printf("TemplateInstance::mangle() %s = %s\n", ti->toChars(), ti->id);
597     }
598 
visit(Dsymbol * s)599     void visit(Dsymbol *s)
600     {
601         mangleParent(s);
602 
603         const char *id = s->ident ? s->ident->toChars() : s->toChars();
604         toBuffer(id, s);
605 
606         //printf("Dsymbol::mangle() %s = %s\n", s->toChars(), id);
607     }
608 
609     ////////////////////////////////////////////////////////////////////////////
610 
visit(Expression * e)611     void visit(Expression *e)
612     {
613         e->error("expression %s is not a valid template value argument", e->toChars());
614     }
615 
visit(IntegerExp * e)616     void visit(IntegerExp *e)
617     {
618         if ((sinteger_t)e->value < 0)
619         {
620             buf->writeByte('N');
621             buf->print(-e->value);
622         }
623         else
624         {
625             buf->writeByte('i');
626             buf->print(e->value);
627         }
628     }
629 
visit(RealExp * e)630     void visit(RealExp *e)
631     {
632         buf->writeByte('e');
633         realToMangleBuffer(e->value);
634     }
635 
realToMangleBuffer(real_t value)636     void realToMangleBuffer(real_t value)
637     {
638         /* Rely on %A to get portable mangling.
639          * Must munge result to get only identifier characters.
640          *
641          * Possible values from %A  => mangled result
642          * NAN                      => NAN
643          * -INF                     => NINF
644          * INF                      => INF
645          * -0X1.1BC18BA997B95P+79   => N11BC18BA997B95P79
646          * 0X1.9P+2                 => 19P2
647          */
648 
649         if (CTFloat::isNaN(value))
650             buf->writestring("NAN");        // no -NAN bugs
651         else if (CTFloat::isInfinity(value))
652             buf->writestring(value < CTFloat::zero ? "NINF" : "INF");
653         else
654         {
655             const size_t BUFFER_LEN = 36;
656             char buffer[BUFFER_LEN];
657             size_t n = CTFloat::sprint(buffer, 'A', value);
658             assert(n < BUFFER_LEN);
659             for (size_t i = 0; i < n; i++)
660             {
661                 char c = buffer[i];
662                 switch (c)
663                 {
664                     case '-':
665                         buf->writeByte('N');
666                         break;
667 
668                     case '+':
669                     case 'X':
670                     case '.':
671                         break;
672 
673                     case '0':
674                         if (i < 2)
675                             break;          // skip leading 0X
676                         /* fall through */
677                     default:
678                         buf->writeByte(c);
679                         break;
680                 }
681             }
682         }
683     }
684 
visit(ComplexExp * e)685     void visit(ComplexExp *e)
686     {
687         buf->writeByte('c');
688         realToMangleBuffer(e->toReal());
689         buf->writeByte('c');        // separate the two
690         realToMangleBuffer(e->toImaginary());
691     }
692 
visit(NullExp *)693     void visit(NullExp *)
694     {
695         buf->writeByte('n');
696     }
697 
visit(StringExp * e)698     void visit(StringExp *e)
699     {
700         char m;
701         OutBuffer tmp;
702         utf8_t *q;
703         size_t qlen;
704 
705         /* Write string in UTF-8 format
706          */
707         switch (e->sz)
708         {
709             case 1:
710                 m = 'a';
711                 q = (utf8_t *)e->string;
712                 qlen = e->len;
713                 break;
714 
715             case 2:
716                 m = 'w';
717                 for (size_t u = 0; u < e->len; )
718                 {
719                     unsigned c;
720                     const char *p = utf_decodeWchar((unsigned short *)e->string, e->len, &u, &c);
721                     if (p)
722                         e->error("%s", p);
723                     else
724                         tmp.writeUTF8(c);
725                 }
726                 q = (utf8_t *)tmp.data;
727                 qlen = tmp.offset;
728                 break;
729 
730             case 4:
731                 m = 'd';
732                 for (size_t u = 0; u < e->len; u++)
733                 {
734                     unsigned c = ((unsigned *)e->string)[u];
735                     if (!utf_isValidDchar(c))
736                         e->error("invalid UCS-32 char \\U%08x", c);
737                     else
738                         tmp.writeUTF8(c);
739                 }
740                 q = (utf8_t *)tmp.data;
741                 qlen = tmp.offset;
742                 break;
743 
744             default:
745                 assert(0);
746         }
747         buf->reserve(1 + 11 + 2 * qlen);
748         buf->writeByte(m);
749         buf->print(qlen);
750         buf->writeByte('_');    // nbytes <= 11
751 
752         for (utf8_t *p = (utf8_t *)buf->data + buf->offset, *pend = p + 2 * qlen;
753              p < pend; p += 2, ++q)
754         {
755             utf8_t hi = *q >> 4 & 0xF;
756             p[0] = (utf8_t)(hi < 10 ? hi + '0' : hi - 10 + 'a');
757             utf8_t lo = *q & 0xF;
758             p[1] = (utf8_t)(lo < 10 ? lo + '0' : lo - 10 + 'a');
759         }
760         buf->offset += 2 * qlen;
761     }
762 
visit(ArrayLiteralExp * e)763     void visit(ArrayLiteralExp *e)
764     {
765         size_t dim = e->elements ? e->elements->dim : 0;
766         buf->writeByte('A');
767         buf->print(dim);
768         for (size_t i = 0; i < dim; i++)
769         {
770             e->getElement(i)->accept(this);
771         }
772     }
773 
visit(AssocArrayLiteralExp * e)774     void visit(AssocArrayLiteralExp *e)
775     {
776         size_t dim = e->keys->dim;
777         buf->writeByte('A');
778         buf->print(dim);
779         for (size_t i = 0; i < dim; i++)
780         {
781             (*e->keys)[i]->accept(this);
782             (*e->values)[i]->accept(this);
783         }
784     }
785 
visit(StructLiteralExp * e)786     void visit(StructLiteralExp *e)
787     {
788         size_t dim = e->elements ? e->elements->dim : 0;
789         buf->writeByte('S');
790         buf->print(dim);
791         for (size_t i = 0; i < dim; i++)
792         {
793             Expression *ex = (*e->elements)[i];
794             if (ex)
795                 ex->accept(this);
796             else
797                 buf->writeByte('v');        // 'v' for void
798         }
799     }
800 
801     ////////////////////////////////////////////////////////////////////////////
802 
paramsToDecoBuffer(Parameters * parameters)803     void paramsToDecoBuffer(Parameters *parameters)
804     {
805         //printf("Parameter::paramsToDecoBuffer()\n");
806         Parameter_foreach(parameters, &paramsToDecoBufferDg, (void *)this);
807     }
808 
paramsToDecoBufferDg(void * ctx,size_t,Parameter * p)809     static int paramsToDecoBufferDg(void *ctx, size_t, Parameter *p)
810     {
811         p->accept((Visitor *)ctx);
812         return 0;
813     }
814 
visit(Parameter * p)815     void visit(Parameter *p)
816     {
817         if (p->storageClass & STCscope && !(p->storageClass & STCscopeinferred))
818             buf->writeByte('M');
819         // 'return inout ref' is the same as 'inout ref'
820         if ((p->storageClass & (STCreturn | STCwild)) == STCreturn)
821             buf->writestring("Nk");
822         switch (p->storageClass & (STCin | STCout | STCref | STClazy))
823         {
824             case 0:
825             case STCin:
826                 break;
827             case STCout:
828                 buf->writeByte('J');
829                 break;
830             case STCref:
831                 buf->writeByte('K');
832                 break;
833             case STClazy:
834                 buf->writeByte('L');
835                 break;
836             default:
837                 assert(0);
838         }
839         visitWithMask(p->type, 0);
840     }
841 };
842 
843 /******************************************************************************
844  * Returns exact mangled name of function.
845  */
mangleExact(FuncDeclaration * fd)846 const char *mangleExact(FuncDeclaration *fd)
847 {
848     if (!fd->mangleString)
849     {
850         OutBuffer buf;
851         Mangler v(&buf);
852         v.mangleExact(fd);
853         fd->mangleString = buf.extractString();
854     }
855     return fd->mangleString;
856 }
857 
mangleToBuffer(Type * t,OutBuffer * buf)858 void mangleToBuffer(Type *t, OutBuffer *buf)
859 {
860     Mangler v(buf);
861     v.visitWithMask(t, 0);
862 }
863 
mangleToBuffer(Expression * e,OutBuffer * buf)864 void mangleToBuffer(Expression *e, OutBuffer *buf)
865 {
866     Mangler v(buf);
867     e->accept(&v);
868 }
869 
mangleToBuffer(Dsymbol * s,OutBuffer * buf)870 void mangleToBuffer(Dsymbol *s, OutBuffer *buf)
871 {
872     Mangler v(buf);
873     s->accept(&v);
874 }
875