1
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2021 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 #include "root/aav.h"
14
15 #include "mangle.h"
16 #include "init.h"
17 #include "declaration.h"
18 #include "aggregate.h"
19 #include "mtype.h"
20 #include "attrib.h"
21 #include "target.h"
22 #include "template.h"
23 #include "id.h"
24 #include "module.h"
25 #include "enum.h"
26 #include "expression.h"
27 #include "utf.h"
28
29 typedef int (*ForeachDg)(void *ctx, size_t paramidx, Parameter *param);
30 int Parameter_foreach(Parameters *parameters, ForeachDg dg, void *ctx, size_t *pn = NULL);
31
32 static const char *mangleChar[TMAX];
33
initTypeMangle()34 void initTypeMangle()
35 {
36 mangleChar[Tarray] = "A";
37 mangleChar[Tsarray] = "G";
38 mangleChar[Taarray] = "H";
39 mangleChar[Tpointer] = "P";
40 mangleChar[Treference] = "R";
41 mangleChar[Tfunction] = "F";
42 mangleChar[Tident] = "I";
43 mangleChar[Tclass] = "C";
44 mangleChar[Tstruct] = "S";
45 mangleChar[Tenum] = "E";
46 mangleChar[Tdelegate] = "D";
47
48 mangleChar[Tnone] = "n";
49 mangleChar[Tvoid] = "v";
50 mangleChar[Tint8] = "g";
51 mangleChar[Tuns8] = "h";
52 mangleChar[Tint16] = "s";
53 mangleChar[Tuns16] = "t";
54 mangleChar[Tint32] = "i";
55 mangleChar[Tuns32] = "k";
56 mangleChar[Tint64] = "l";
57 mangleChar[Tuns64] = "m";
58 mangleChar[Tint128] = "zi";
59 mangleChar[Tuns128] = "zk";
60 mangleChar[Tfloat32] = "f";
61 mangleChar[Tfloat64] = "d";
62 mangleChar[Tfloat80] = "e";
63
64 mangleChar[Timaginary32] = "o";
65 mangleChar[Timaginary64] = "p";
66 mangleChar[Timaginary80] = "j";
67 mangleChar[Tcomplex32] = "q";
68 mangleChar[Tcomplex64] = "r";
69 mangleChar[Tcomplex80] = "c";
70
71 mangleChar[Tbool] = "b";
72 mangleChar[Tchar] = "a";
73 mangleChar[Twchar] = "u";
74 mangleChar[Tdchar] = "w";
75
76 // '@' shouldn't appear anywhere in the deco'd names
77 mangleChar[Tinstance] = "@";
78 mangleChar[Terror] = "@";
79 mangleChar[Ttypeof] = "@";
80 mangleChar[Ttuple] = "B";
81 mangleChar[Tslice] = "@";
82 mangleChar[Treturn] = "@";
83 mangleChar[Tvector] = "@";
84 mangleChar[Ttraits] = "@";
85 mangleChar[Tmixin] = "@";
86 mangleChar[Tnoreturn] = "@"; // becomes 'Nn'
87
88 mangleChar[Tnull] = "n"; // same as TypeNone
89
90 for (size_t i = 0; i < TMAX; i++)
91 {
92 if (!mangleChar[i])
93 fprintf(stderr, "ty = %llu\n", (ulonglong)i);
94 assert(mangleChar[i]);
95 }
96 }
97
98 /*********************************
99 * Mangling for mod.
100 */
MODtoDecoBuffer(OutBuffer * buf,MOD mod)101 void MODtoDecoBuffer(OutBuffer *buf, MOD mod)
102 {
103 switch (mod)
104 {
105 case 0:
106 break;
107 case MODconst:
108 buf->writeByte('x');
109 break;
110 case MODimmutable:
111 buf->writeByte('y');
112 break;
113 case MODshared:
114 buf->writeByte('O');
115 break;
116 case MODshared | MODconst:
117 buf->writestring("Ox");
118 break;
119 case MODwild:
120 buf->writestring("Ng");
121 break;
122 case MODwildconst:
123 buf->writestring("Ngx");
124 break;
125 case MODshared | MODwild:
126 buf->writestring("ONg");
127 break;
128 case MODshared | MODwildconst:
129 buf->writestring("ONgx");
130 break;
131 default:
132 assert(0);
133 }
134 }
135
136 class Mangler : public Visitor
137 {
138 public:
139 AA *types;
140 AA *idents;
141 OutBuffer *buf;
142
Mangler(OutBuffer * buf)143 Mangler(OutBuffer *buf)
144 {
145 this->types = NULL;
146 this->idents = NULL;
147 this->buf = buf;
148 }
149
150 /**
151 * writes a back reference with the relative position encoded with base 26
152 * using upper case letters for all digits but the last digit which uses
153 * a lower case letter.
154 * The decoder has to look up the referenced position to determine
155 * whether the back reference is an identifier (starts with a digit)
156 * or a type (starts with a letter).
157 *
158 * Params:
159 * pos = relative position to encode
160 */
writeBackRef(size_t pos)161 void writeBackRef(size_t pos)
162 {
163 buf->writeByte('Q');
164 const size_t base = 26;
165 size_t mul = 1;
166 while (pos >= mul * base)
167 mul *= base;
168 while (mul >= base)
169 {
170 unsigned char dig = (unsigned char)(pos / mul);
171 buf->writeByte('A' + dig);
172 pos -= dig * mul;
173 mul /= base;
174 }
175 buf->writeByte('a' + (unsigned char)pos);
176 }
177
178 /**
179 * Back references a non-basic type
180 *
181 * The encoded mangling is
182 * 'Q' <relative position of first occurrence of type>
183 *
184 * Params:
185 * t = the type to encode via back referencing
186 *
187 * Returns:
188 * true if the type was found. A back reference has been encoded.
189 * false if the type was not found. The current position is saved for later back references.
190 */
backrefType(Type * t)191 bool backrefType(Type *t)
192 {
193 if (!t->isTypeBasic())
194 {
195 size_t *p = (size_t *)dmd_aaGet(&types, (void *)t);
196 if (*p)
197 {
198 writeBackRef(buf->length() - *p);
199 return true;
200 }
201 *p = buf->length();
202 }
203 return false;
204 }
205
206 /**
207 * Back references a single identifier
208 *
209 * The encoded mangling is
210 * 'Q' <relative position of first occurrence of type>
211 *
212 * Params:
213 * id = the identifier to encode via back referencing
214 *
215 * Returns:
216 * true if the identifier was found. A back reference has been encoded.
217 * false if the identifier was not found. The current position is saved for later back references.
218 */
backrefIdentifier(Identifier * id)219 bool backrefIdentifier(Identifier *id)
220 {
221 size_t *p = (size_t *)dmd_aaGet(&idents, (void *)id);
222 if (*p)
223 {
224 writeBackRef(buf->length() - *p);
225 return true;
226 }
227 *p = buf->length();
228 return false;
229 }
230
mangleSymbol(Dsymbol * s)231 void mangleSymbol(Dsymbol *s)
232 {
233 s->accept(this);
234 }
235
mangleType(Type * t)236 void mangleType(Type *t)
237 {
238 if (!backrefType(t))
239 t->accept(this);
240 }
241
mangleIdentifier(Identifier * id,Dsymbol * s)242 void mangleIdentifier(Identifier *id, Dsymbol *s)
243 {
244 if (!backrefIdentifier(id))
245 toBuffer(id->toChars(), s);
246 }
247
248 ////////////////////////////////////////////////////////////////////////////
249
250 /**************************************************
251 * Type mangling
252 */
253
visitWithMask(Type * t,unsigned char modMask)254 void visitWithMask(Type *t, unsigned char modMask)
255 {
256 if (modMask != t->mod)
257 {
258 MODtoDecoBuffer(buf, t->mod);
259 }
260 mangleType(t);
261 }
262
visit(Type * t)263 void visit(Type *t)
264 {
265 buf->writestring(mangleChar[t->ty]);
266 }
267
visit(TypeNext * t)268 void visit(TypeNext *t)
269 {
270 visit((Type *)t);
271 visitWithMask(t->next, t->mod);
272 }
273
visit(TypeVector * t)274 void visit(TypeVector *t)
275 {
276 buf->writestring("Nh");
277 visitWithMask(t->basetype, t->mod);
278 }
279
visit(TypeSArray * t)280 void visit(TypeSArray *t)
281 {
282 visit((Type *)t);
283 if (t->dim)
284 buf->print(t->dim->toInteger());
285 if (t->next)
286 visitWithMask(t->next, t->mod);
287 }
288
visit(TypeDArray * t)289 void visit(TypeDArray *t)
290 {
291 visit((Type *)t);
292 if (t->next)
293 visitWithMask(t->next, t->mod);
294 }
295
visit(TypeAArray * t)296 void visit(TypeAArray *t)
297 {
298 visit((Type *)t);
299 visitWithMask(t->index, 0);
300 visitWithMask(t->next, t->mod);
301 }
302
visit(TypeFunction * t)303 void visit(TypeFunction *t)
304 {
305 //printf("TypeFunction::toDecoBuffer() t = %p %s\n", t, t->toChars());
306 //static int nest; if (++nest == 50) *(char*)0=0;
307
308 mangleFuncType(t, t, t->mod, t->next);
309 }
310
mangleFuncType(TypeFunction * t,TypeFunction * ta,unsigned char modMask,Type * tret)311 void mangleFuncType(TypeFunction *t, TypeFunction *ta, unsigned char modMask, Type *tret)
312 {
313 //printf("mangleFuncType() %s\n", t->toChars());
314 if (t->inuse && tret)
315 {
316 // printf("TypeFunction.mangleFuncType() t = %s inuse\n", t->toChars());
317 t->inuse = 2; // flag error to caller
318 return;
319 }
320 t->inuse++;
321
322 if (modMask != t->mod)
323 MODtoDecoBuffer(buf, t->mod);
324
325 unsigned char mc;
326 switch (t->linkage)
327 {
328 case LINKd: mc = 'F'; break;
329 case LINKc: mc = 'U'; break;
330 case LINKwindows: mc = 'W'; break;
331 case LINKcpp: mc = 'R'; break;
332 case LINKobjc: mc = 'Y'; break;
333 default:
334 assert(0);
335 }
336 buf->writeByte(mc);
337
338 if (ta->purity || ta->isnothrow || ta->isnogc || ta->isproperty || ta->isref || ta->trust || ta->isreturn || ta->isscope)
339 {
340 if (ta->purity)
341 buf->writestring("Na");
342 if (ta->isnothrow)
343 buf->writestring("Nb");
344 if (ta->isref)
345 buf->writestring("Nc");
346 if (ta->isproperty)
347 buf->writestring("Nd");
348 if (ta->isnogc)
349 buf->writestring("Ni");
350 if (ta->isreturn)
351 buf->writestring("Nj");
352 if (ta->isscope && !ta->isreturn && !ta->isscopeinferred)
353 buf->writestring("Nl");
354 switch (ta->trust)
355 {
356 case TRUSTtrusted:
357 buf->writestring("Ne");
358 break;
359 case TRUSTsafe:
360 buf->writestring("Nf");
361 break;
362 default:
363 break;
364 }
365 }
366
367 // Write argument types
368 paramsToDecoBuffer(t->parameterList.parameters);
369 //if (buf->slice().ptr[buf->length() - 1] == '@') halt();
370 buf->writeByte('Z' - t->parameterList.varargs); // mark end of arg list
371 if (tret != NULL)
372 visitWithMask(tret, 0);
373
374 t->inuse--;
375 }
376
visit(TypeIdentifier * t)377 void visit(TypeIdentifier *t)
378 {
379 visit((Type *)t);
380 const char *name = t->ident->toChars();
381 size_t len = strlen(name);
382 buf->print(len);
383 buf->writestring(name);
384 }
385
visit(TypeEnum * t)386 void visit(TypeEnum *t)
387 {
388 visit((Type *)t);
389 mangleSymbol(t->sym);
390 }
391
visit(TypeStruct * t)392 void visit(TypeStruct *t)
393 {
394 //printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", t->toChars(), name);
395 visit((Type *)t);
396 mangleSymbol(t->sym);
397 }
398
visit(TypeClass * t)399 void visit(TypeClass *t)
400 {
401 //printf("TypeClass::toDecoBuffer('%s' mod=%x) = '%s'\n", t->toChars(), mod, name);
402 visit((Type *)t);
403 mangleSymbol(t->sym);
404 }
405
visit(TypeTuple * t)406 void visit(TypeTuple *t)
407 {
408 //printf("TypeTuple::toDecoBuffer() t = %p, %s\n", t, t->toChars());
409 visit((Type *)t);
410 paramsToDecoBuffer(t->arguments);
411 buf->writeByte('Z');
412 }
413
visit(TypeNull * t)414 void visit(TypeNull *t)
415 {
416 visit((Type *)t);
417 }
418
visit(TypeNoreturn *)419 void visit(TypeNoreturn *)
420 {
421 buf->writestring("Nn");
422 }
423
424 ////////////////////////////////////////////////////////////////////////////
425
mangleDecl(Declaration * sthis)426 void mangleDecl(Declaration *sthis)
427 {
428 mangleParent(sthis);
429
430 assert(sthis->ident);
431 mangleIdentifier(sthis->ident, sthis);
432 if (FuncDeclaration *fd = sthis->isFuncDeclaration())
433 {
434 mangleFunc(fd, false);
435 }
436 else if (sthis->type)
437 {
438 visitWithMask(sthis->type, 0);
439 }
440 else
441 assert(0);
442 }
443
mangleParent(Dsymbol * s)444 void mangleParent(Dsymbol *s)
445 {
446 Dsymbol *p;
447 if (TemplateInstance *ti = s->isTemplateInstance())
448 p = ti->isTemplateMixin() ? ti->parent : ti->tempdecl->parent;
449 else
450 p = s->parent;
451
452 if (p)
453 {
454 mangleParent(p);
455 TemplateInstance *ti = p->isTemplateInstance();
456 if (ti && !ti->isTemplateMixin())
457 {
458 mangleTemplateInstance(ti);
459 }
460 else if (p->getIdent())
461 {
462 mangleIdentifier(p->ident, s);
463 if (FuncDeclaration *f = p->isFuncDeclaration())
464 mangleFunc(f, true);
465 }
466 else
467 buf->writeByte('0');
468 }
469 }
470
mangleFunc(FuncDeclaration * fd,bool inParent)471 void mangleFunc(FuncDeclaration *fd, bool inParent)
472 {
473 //printf("deco = '%s'\n", fd->type->deco ? fd->type->deco : "null");
474 //printf("fd->type = %s\n", fd->type->toChars());
475 if (fd->needThis() || fd->isNested())
476 buf->writeByte('M');
477 if (inParent)
478 {
479 TypeFunction *tf = (TypeFunction *)fd->type;
480 TypeFunction *tfo = (TypeFunction *)fd->originalType;
481 mangleFuncType(tf, tfo, 0, NULL);
482 }
483 else if (fd->type)
484 {
485 visitWithMask(fd->type, 0);
486 }
487 else
488 {
489 printf("[%s] %s no type\n", fd->loc.toChars(), fd->toChars());
490 assert(0); // don't mangle function until semantic3 done.
491 }
492 }
493
494 /************************************************************
495 * Write length prefixed string to buf.
496 */
toBuffer(const char * id,Dsymbol * s)497 void toBuffer(const char *id, Dsymbol *s)
498 {
499 size_t len = strlen(id);
500 if (buf->length() + len >= 8 * 1024 * 1024) // 8 megs ought be enough for anyone
501 s->error("excessive length %llu for symbol, possible recursive expansion?", buf->length() + len);
502 else
503 {
504 buf->print(len);
505 buf->write(id, len);
506 }
507 }
508
externallyMangledIdentifier(Declaration * d)509 static const char *externallyMangledIdentifier(Declaration *d)
510 {
511 if (!d->parent || d->parent->isModule() || d->linkage == LINKcpp) // if at global scope
512 {
513 switch (d->linkage)
514 {
515 case LINKd:
516 break;
517 case LINKc:
518 case LINKwindows:
519 case LINKobjc:
520 return d->ident->toChars();
521 case LINKcpp:
522 return target.cpp.toMangle(d);
523 case LINKdefault:
524 d->error("forward declaration");
525 return d->ident->toChars();
526 default:
527 fprintf(stderr, "'%s', linkage = %d\n", d->toChars(), d->linkage);
528 assert(0);
529 }
530 }
531 return NULL;
532 }
533
visit(Declaration * d)534 void visit(Declaration *d)
535 {
536 //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n",
537 // d, d->toChars(), d->parent ? d->parent->toChars() : "null", d->linkage);
538 if (const char *id = externallyMangledIdentifier(d))
539 {
540 buf->writestring(id);
541 return;
542 }
543 buf->writestring("_D");
544 mangleDecl(d);
545 }
546
547 /******************************************************************************
548 * Normally FuncDeclaration and FuncAliasDeclaration have overloads.
549 * If and only if there is no overloads, mangle() could return
550 * exact mangled name.
551 *
552 * module test;
553 * void foo(long) {} // _D4test3fooFlZv
554 * void foo(string) {} // _D4test3fooFAyaZv
555 *
556 * // from FuncDeclaration::mangle().
557 * pragma(msg, foo.mangleof); // prints unexact mangled name "4test3foo"
558 * // by calling Dsymbol::mangle()
559 *
560 * // from FuncAliasDeclaration::mangle()
561 * pragma(msg, __traits(getOverloads, test, "foo")[0].mangleof); // "_D4test3fooFlZv"
562 * pragma(msg, __traits(getOverloads, test, "foo")[1].mangleof); // "_D4test3fooFAyaZv"
563 *
564 * If a function has no overloads, .mangleof property still returns exact mangled name.
565 *
566 * void bar() {}
567 * pragma(msg, bar.mangleof); // still prints "_D4test3barFZv"
568 * // by calling FuncDeclaration::mangleExact().
569 */
visit(FuncDeclaration * fd)570 void visit(FuncDeclaration *fd)
571 {
572 if (fd->isUnique())
573 mangleExact(fd);
574 else
575 visit((Dsymbol *)fd);
576 }
577
578 // ditto
visit(FuncAliasDeclaration * fd)579 void visit(FuncAliasDeclaration *fd)
580 {
581 FuncDeclaration *f = fd->toAliasFunc();
582 FuncAliasDeclaration *fa = f->isFuncAliasDeclaration();
583 if (!fd->hasOverloads && !fa)
584 {
585 mangleExact(f);
586 return;
587 }
588 if (fa)
589 {
590 mangleSymbol(fa);
591 return;
592 }
593 visit((Dsymbol *)fd);
594 }
595
visit(OverDeclaration * od)596 void visit(OverDeclaration *od)
597 {
598 if (od->overnext)
599 {
600 visit((Dsymbol *)od);
601 return;
602 }
603
604 if (FuncDeclaration *fd = od->aliassym->isFuncDeclaration())
605 {
606 if (!od->hasOverloads || fd->isUnique())
607 {
608 mangleExact(fd);
609 return;
610 }
611 }
612 if (TemplateDeclaration *td = od->aliassym->isTemplateDeclaration())
613 {
614 if (!od->hasOverloads || td->overnext == NULL)
615 {
616 mangleSymbol(td);
617 return;
618 }
619 }
620 visit((Dsymbol *)od);
621 }
622
mangleExact(FuncDeclaration * fd)623 void mangleExact(FuncDeclaration *fd)
624 {
625 assert(!fd->isFuncAliasDeclaration());
626
627 if (fd->mangleOverride.length)
628 {
629 buf->writestring(fd->mangleOverride.ptr);
630 return;
631 }
632
633 if (fd->isMain())
634 {
635 buf->writestring("_Dmain");
636 return;
637 }
638
639 if (fd->isWinMain() || fd->isDllMain() || fd->ident == Id::tls_get_addr)
640 {
641 buf->writestring(fd->ident->toChars());
642 return;
643 }
644
645 visit((Declaration *)fd);
646 }
647
visit(VarDeclaration * vd)648 void visit(VarDeclaration *vd)
649 {
650 if (vd->mangleOverride.length)
651 {
652 buf->writestring(vd->mangleOverride.ptr);
653 return;
654 }
655
656 visit((Declaration *)vd);
657 }
658
visit(AggregateDeclaration * ad)659 void visit(AggregateDeclaration *ad)
660 {
661 ClassDeclaration *cd = ad->isClassDeclaration();
662 Dsymbol *parentsave = ad->parent;
663 if (cd)
664 {
665 /* These are reserved to the compiler, so keep simple
666 * names for them.
667 */
668 if ((cd->ident == Id::Exception && cd->parent->ident == Id::object) ||
669 cd->ident == Id::TypeInfo ||
670 cd->ident == Id::TypeInfo_Struct ||
671 cd->ident == Id::TypeInfo_Class ||
672 cd->ident == Id::TypeInfo_Tuple ||
673 cd == ClassDeclaration::object ||
674 cd == Type::typeinfoclass ||
675 cd == Module::moduleinfo ||
676 strncmp(cd->ident->toChars(), "TypeInfo_", 9) == 0)
677 {
678 // Don't mangle parent
679 ad->parent = NULL;
680 }
681 }
682
683 visit((Dsymbol *)ad);
684
685 ad->parent = parentsave;
686 }
687
visit(TemplateInstance * ti)688 void visit(TemplateInstance *ti)
689 {
690 if (!ti->tempdecl)
691 ti->error("is not defined");
692 else
693 mangleParent(ti);
694
695 if (ti->isTemplateMixin() && ti->ident)
696 mangleIdentifier(ti->ident, ti);
697 else
698 mangleTemplateInstance(ti);
699 }
700
mangleTemplateInstance(TemplateInstance * ti)701 void mangleTemplateInstance(TemplateInstance *ti)
702 {
703 TemplateDeclaration *tempdecl = ti->tempdecl->isTemplateDeclaration();
704 assert(tempdecl);
705
706 // Use "__U" for the symbols declared inside template constraint.
707 const char T = ti->members ? 'T' : 'U';
708 buf->printf("__%c", T);
709 mangleIdentifier(tempdecl->ident, tempdecl);
710
711 Objects *args = ti->tiargs;
712 size_t nparams = tempdecl->parameters->length - (tempdecl->isVariadic() ? 1 : 0);
713 for (size_t i = 0; i < args->length; i++)
714 {
715 RootObject *o = (*args)[i];
716 Type *ta = isType(o);
717 Expression *ea = isExpression(o);
718 Dsymbol *sa = isDsymbol(o);
719 Tuple *va = isTuple(o);
720 //printf("\to [%d] %p ta %p ea %p sa %p va %p\n", i, o, ta, ea, sa, va);
721 if (i < nparams && (*tempdecl->parameters)[i]->specialization())
722 buf->writeByte('H'); // https://issues.dlang.org/show_bug.cgi?id=6574
723 if (ta)
724 {
725 buf->writeByte('T');
726 visitWithMask(ta, 0);
727 }
728 else if (ea)
729 {
730 // Don't interpret it yet, it might actually be an alias template parameter.
731 // Only constfold manifest constants, not const/immutable lvalues, see https://issues.dlang.org/show_bug.cgi?id=17339.
732 const bool keepLvalue = true;
733 ea = ea->optimize(WANTvalue, keepLvalue);
734 if (ea->op == TOKvar)
735 {
736 sa = ((VarExp *)ea)->var;
737 ea = NULL;
738 goto Lsa;
739 }
740 if (ea->op == TOKthis)
741 {
742 sa = ((ThisExp *)ea)->var;
743 ea = NULL;
744 goto Lsa;
745 }
746 if (ea->op == TOKfunction)
747 {
748 if (((FuncExp *)ea)->td)
749 sa = ((FuncExp *)ea)->td;
750 else
751 sa = ((FuncExp *)ea)->fd;
752 ea = NULL;
753 goto Lsa;
754 }
755 buf->writeByte('V');
756 if (ea->op == TOKtuple)
757 {
758 ea->error("tuple is not a valid template value argument");
759 continue;
760 }
761 // Now that we know it is not an alias, we MUST obtain a value
762 unsigned olderr = global.errors;
763 ea = ea->ctfeInterpret();
764 if (ea->op == TOKerror || olderr != global.errors)
765 continue;
766
767 /* Use type mangling that matches what it would be for a function parameter
768 */
769 visitWithMask(ea->type, 0);
770 ea->accept(this);
771 }
772 else if (sa)
773 {
774 Lsa:
775 sa = sa->toAlias();
776 if (Declaration *d = sa->isDeclaration())
777 {
778 if (FuncAliasDeclaration *fad = d->isFuncAliasDeclaration())
779 d = fad->toAliasFunc();
780 if (d->mangleOverride.length)
781 {
782 buf->writeByte('X');
783 toBuffer(d->mangleOverride.ptr, d);
784 continue;
785 }
786 if (const char *id = externallyMangledIdentifier(d))
787 {
788 buf->writeByte('X');
789 toBuffer(id, d);
790 continue;
791 }
792 if (!d->type || !d->type->deco)
793 {
794 ti->error("forward reference of %s %s", d->kind(), d->toChars());
795 continue;
796 }
797 }
798 buf->writeByte('S');
799 mangleSymbol(sa);
800 }
801 else if (va)
802 {
803 assert(i + 1 == args->length); // must be last one
804 args = &va->objects;
805 i = -(size_t)1;
806 }
807 else
808 assert(0);
809 }
810 buf->writeByte('Z');
811 }
812
visit(Dsymbol * s)813 void visit(Dsymbol *s)
814 {
815 mangleParent(s);
816 if (s->ident)
817 mangleIdentifier(s->ident, s);
818 else
819 toBuffer(s->toChars(), s);
820 //printf("Dsymbol::mangle() %s = %s\n", s->toChars(), id);
821 }
822
823 ////////////////////////////////////////////////////////////////////////////
824
visit(Expression * e)825 void visit(Expression *e)
826 {
827 e->error("expression %s is not a valid template value argument", e->toChars());
828 }
829
visit(IntegerExp * e)830 void visit(IntegerExp *e)
831 {
832 if ((sinteger_t)e->value < 0)
833 {
834 buf->writeByte('N');
835 buf->print(-e->value);
836 }
837 else
838 {
839 buf->writeByte('i');
840 buf->print(e->value);
841 }
842 }
843
visit(RealExp * e)844 void visit(RealExp *e)
845 {
846 buf->writeByte('e');
847 realToMangleBuffer(e->value);
848 }
849
realToMangleBuffer(real_t value)850 void realToMangleBuffer(real_t value)
851 {
852 /* Rely on %A to get portable mangling.
853 * Must munge result to get only identifier characters.
854 *
855 * Possible values from %A => mangled result
856 * NAN => NAN
857 * -INF => NINF
858 * INF => INF
859 * -0X1.1BC18BA997B95P+79 => N11BC18BA997B95P79
860 * 0X1.9P+2 => 19P2
861 */
862
863 if (CTFloat::isNaN(value))
864 buf->writestring("NAN"); // no -NAN bugs
865 else if (CTFloat::isInfinity(value))
866 buf->writestring(value < CTFloat::zero ? "NINF" : "INF");
867 else
868 {
869 const size_t BUFFER_LEN = 36;
870 char buffer[BUFFER_LEN];
871 size_t n = CTFloat::sprint(buffer, 'A', value);
872 assert(n < BUFFER_LEN);
873 for (size_t i = 0; i < n; i++)
874 {
875 char c = buffer[i];
876 switch (c)
877 {
878 case '-':
879 buf->writeByte('N');
880 break;
881
882 case '+':
883 case 'X':
884 case '.':
885 break;
886
887 case '0':
888 if (i < 2)
889 break; // skip leading 0X
890 /* fall through */
891 default:
892 buf->writeByte(c);
893 break;
894 }
895 }
896 }
897 }
898
visit(ComplexExp * e)899 void visit(ComplexExp *e)
900 {
901 buf->writeByte('c');
902 realToMangleBuffer(e->toReal());
903 buf->writeByte('c'); // separate the two
904 realToMangleBuffer(e->toImaginary());
905 }
906
visit(NullExp *)907 void visit(NullExp *)
908 {
909 buf->writeByte('n');
910 }
911
visit(StringExp * e)912 void visit(StringExp *e)
913 {
914 char m;
915 OutBuffer tmp;
916 utf8_t *q;
917 size_t qlen;
918
919 /* Write string in UTF-8 format
920 */
921 switch (e->sz)
922 {
923 case 1:
924 m = 'a';
925 q = (utf8_t *)e->string;
926 qlen = e->len;
927 break;
928
929 case 2:
930 m = 'w';
931 for (size_t u = 0; u < e->len; )
932 {
933 unsigned c;
934 const char *p = utf_decodeWchar((unsigned short *)e->string, e->len, &u, &c);
935 if (p)
936 e->error("%s", p);
937 else
938 tmp.writeUTF8(c);
939 }
940 q = (utf8_t *)tmp.slice().ptr;
941 qlen = tmp.length();
942 break;
943
944 case 4:
945 m = 'd';
946 for (size_t u = 0; u < e->len; u++)
947 {
948 unsigned c = ((unsigned *)e->string)[u];
949 if (!utf_isValidDchar(c))
950 e->error("invalid UCS-32 char \\U%08x", c);
951 else
952 tmp.writeUTF8(c);
953 }
954 q = (utf8_t *)tmp.slice().ptr;
955 qlen = tmp.length();
956 break;
957
958 default:
959 assert(0);
960 }
961 buf->reserve(1 + 11 + 2 * qlen);
962 buf->writeByte(m);
963 buf->print(qlen);
964 buf->writeByte('_'); // nbytes <= 11
965
966 for (utf8_t *p = (utf8_t *)buf->slice().ptr + buf->length(), *pend = p + 2 * qlen;
967 p < pend; p += 2, ++q)
968 {
969 utf8_t hi = *q >> 4 & 0xF;
970 p[0] = (utf8_t)(hi < 10 ? hi + '0' : hi - 10 + 'a');
971 utf8_t lo = *q & 0xF;
972 p[1] = (utf8_t)(lo < 10 ? lo + '0' : lo - 10 + 'a');
973 }
974 buf->setsize(buf->length() + 2 * qlen);
975 }
976
visit(ArrayLiteralExp * e)977 void visit(ArrayLiteralExp *e)
978 {
979 size_t dim = e->elements ? e->elements->length : 0;
980 buf->writeByte('A');
981 buf->print(dim);
982 for (size_t i = 0; i < dim; i++)
983 {
984 e->getElement(i)->accept(this);
985 }
986 }
987
visit(AssocArrayLiteralExp * e)988 void visit(AssocArrayLiteralExp *e)
989 {
990 size_t dim = e->keys->length;
991 buf->writeByte('A');
992 buf->print(dim);
993 for (size_t i = 0; i < dim; i++)
994 {
995 (*e->keys)[i]->accept(this);
996 (*e->values)[i]->accept(this);
997 }
998 }
999
visit(StructLiteralExp * e)1000 void visit(StructLiteralExp *e)
1001 {
1002 size_t dim = e->elements ? e->elements->length : 0;
1003 buf->writeByte('S');
1004 buf->print(dim);
1005 for (size_t i = 0; i < dim; i++)
1006 {
1007 Expression *ex = (*e->elements)[i];
1008 if (ex)
1009 ex->accept(this);
1010 else
1011 buf->writeByte('v'); // 'v' for void
1012 }
1013 }
1014
1015 ////////////////////////////////////////////////////////////////////////////
1016
paramsToDecoBuffer(Parameters * parameters)1017 void paramsToDecoBuffer(Parameters *parameters)
1018 {
1019 //printf("Parameter::paramsToDecoBuffer()\n");
1020 Parameter_foreach(parameters, ¶msToDecoBufferDg, (void *)this);
1021 }
1022
paramsToDecoBufferDg(void * ctx,size_t,Parameter * p)1023 static int paramsToDecoBufferDg(void *ctx, size_t, Parameter *p)
1024 {
1025 p->accept((Visitor *)ctx);
1026 return 0;
1027 }
1028
visit(Parameter * p)1029 void visit(Parameter *p)
1030 {
1031 if (p->storageClass & STCscope && !(p->storageClass & STCscopeinferred))
1032 buf->writeByte('M');
1033 // 'return inout ref' is the same as 'inout ref'
1034 if ((p->storageClass & (STCreturn | STCwild)) == STCreturn)
1035 buf->writestring("Nk");
1036 switch (p->storageClass & (STCin | STCout | STCref | STClazy))
1037 {
1038 case 0:
1039 case STCin:
1040 break;
1041 case STCout:
1042 buf->writeByte('J');
1043 break;
1044 case STCref:
1045 buf->writeByte('K');
1046 break;
1047 case STClazy:
1048 buf->writeByte('L');
1049 break;
1050 default:
1051 assert(0);
1052 }
1053 visitWithMask(p->type, 0);
1054 }
1055 };
1056
1057 /******************************************************************************
1058 * Returns exact mangled name of function.
1059 */
mangleExact(FuncDeclaration * fd)1060 const char *mangleExact(FuncDeclaration *fd)
1061 {
1062 if (!fd->mangleString)
1063 {
1064 OutBuffer buf;
1065 Mangler v(&buf);
1066 v.mangleExact(fd);
1067 fd->mangleString = buf.extractChars();
1068 }
1069 return fd->mangleString;
1070 }
1071
mangleToBuffer(Type * t,OutBuffer * buf)1072 void mangleToBuffer(Type *t, OutBuffer *buf)
1073 {
1074 Mangler v(buf);
1075 v.visitWithMask(t, 0);
1076 }
1077
mangleToBuffer(Expression * e,OutBuffer * buf)1078 void mangleToBuffer(Expression *e, OutBuffer *buf)
1079 {
1080 Mangler v(buf);
1081 e->accept(&v);
1082 }
1083
mangleToBuffer(Dsymbol * s,OutBuffer * buf)1084 void mangleToBuffer(Dsymbol *s, OutBuffer *buf)
1085 {
1086 Mangler v(buf);
1087 s->accept(&v);
1088 }
1089
mangleToBuffer(TemplateInstance * ti,OutBuffer * buf)1090 void mangleToBuffer(TemplateInstance *ti, OutBuffer *buf)
1091 {
1092 Mangler v(buf);
1093 v.mangleTemplateInstance(ti);
1094 }
1095
1096 /**********************************************
1097 * Convert a string representing a type (the deco) and
1098 * return its equivalent Type.
1099 * Params:
1100 * deco = string containing the deco
1101 * Returns:
1102 * null for failed to convert
1103 * Type for succeeded
1104 */
1105
decoToType(const char * deco)1106 Type *decoToType(const char *deco)
1107 {
1108 if (!deco)
1109 return NULL;
1110
1111 //printf("decoToType(): %s\n", deco)
1112 if (StringValue *sv = Type::stringtable.lookup(deco, strlen(deco)))
1113 {
1114 if (sv->ptrvalue)
1115 {
1116 Type *t = (Type *)sv->ptrvalue;
1117 assert(t->deco);
1118 return t;
1119 }
1120 }
1121 return NULL;
1122 }
1123