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, ¶msToDecoBufferDg, (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