]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/dmd/dmangle.c
9734624b2881d5112a81c83cd5f8017dec369139
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2018 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
16 #include "root/root.h"
20 #include "declaration.h"
21 #include "aggregate.h"
29 #include "expression.h"
32 typedef int (*ForeachDg
)(void *ctx
, size_t paramidx
, Parameter
*param
);
33 int Parameter_foreach(Parameters
*parameters
, ForeachDg dg
, void *ctx
, size_t *pn
= NULL
);
35 static const char *mangleChar
[TMAX
];
39 mangleChar
[Tarray
] = "A";
40 mangleChar
[Tsarray
] = "G";
41 mangleChar
[Taarray
] = "H";
42 mangleChar
[Tpointer
] = "P";
43 mangleChar
[Treference
] = "R";
44 mangleChar
[Tfunction
] = "F";
45 mangleChar
[Tident
] = "I";
46 mangleChar
[Tclass
] = "C";
47 mangleChar
[Tstruct
] = "S";
48 mangleChar
[Tenum
] = "E";
49 mangleChar
[Tdelegate
] = "D";
51 mangleChar
[Tnone
] = "n";
52 mangleChar
[Tvoid
] = "v";
53 mangleChar
[Tint8
] = "g";
54 mangleChar
[Tuns8
] = "h";
55 mangleChar
[Tint16
] = "s";
56 mangleChar
[Tuns16
] = "t";
57 mangleChar
[Tint32
] = "i";
58 mangleChar
[Tuns32
] = "k";
59 mangleChar
[Tint64
] = "l";
60 mangleChar
[Tuns64
] = "m";
61 mangleChar
[Tint128
] = "zi";
62 mangleChar
[Tuns128
] = "zk";
63 mangleChar
[Tfloat32
] = "f";
64 mangleChar
[Tfloat64
] = "d";
65 mangleChar
[Tfloat80
] = "e";
67 mangleChar
[Timaginary32
] = "o";
68 mangleChar
[Timaginary64
] = "p";
69 mangleChar
[Timaginary80
] = "j";
70 mangleChar
[Tcomplex32
] = "q";
71 mangleChar
[Tcomplex64
] = "r";
72 mangleChar
[Tcomplex80
] = "c";
74 mangleChar
[Tbool
] = "b";
75 mangleChar
[Tchar
] = "a";
76 mangleChar
[Twchar
] = "u";
77 mangleChar
[Tdchar
] = "w";
79 // '@' shouldn't appear anywhere in the deco'd names
80 mangleChar
[Tinstance
] = "@";
81 mangleChar
[Terror
] = "@";
82 mangleChar
[Ttypeof
] = "@";
83 mangleChar
[Ttuple
] = "B";
84 mangleChar
[Tslice
] = "@";
85 mangleChar
[Treturn
] = "@";
86 mangleChar
[Tvector
] = "@";
88 mangleChar
[Tnull
] = "n"; // same as TypeNone
90 for (size_t i
= 0; i
< TMAX
; i
++)
93 fprintf(stderr
, "ty = %llu\n", (ulonglong
)i
);
94 assert(mangleChar
[i
]);
98 /*********************************
101 void MODtoDecoBuffer(OutBuffer
*buf
, MOD mod
)
116 case MODshared
| MODconst
:
117 buf
->writestring("Ox");
120 buf
->writestring("Ng");
123 buf
->writestring("Ngx");
125 case MODshared
| MODwild
:
126 buf
->writestring("ONg");
128 case MODshared
| MODwildconst
:
129 buf
->writestring("ONgx");
136 class Mangler
: public Visitor
141 Mangler(OutBuffer
*buf
)
147 ////////////////////////////////////////////////////////////////////////////
149 /**************************************************
153 void visitWithMask(Type
*t
, unsigned char modMask
)
155 if (modMask
!= t
->mod
)
157 MODtoDecoBuffer(buf
, t
->mod
);
164 buf
->writestring(mangleChar
[t
->ty
]);
167 void visit(TypeNext
*t
)
170 visitWithMask(t
->next
, t
->mod
);
173 void visit(TypeVector
*t
)
175 buf
->writestring("Nh");
176 visitWithMask(t
->basetype
, t
->mod
);
179 void visit(TypeSArray
*t
)
183 buf
->printf("%llu", t
->dim
->toInteger());
185 visitWithMask(t
->next
, t
->mod
);
188 void visit(TypeDArray
*t
)
192 visitWithMask(t
->next
, t
->mod
);
195 void visit(TypeAArray
*t
)
198 visitWithMask(t
->index
, 0);
199 visitWithMask(t
->next
, t
->mod
);
202 void visit(TypeFunction
*t
)
204 //printf("TypeFunction::toDecoBuffer() t = %p %s\n", t, t->toChars());
205 //static int nest; if (++nest == 50) *(char*)0=0;
207 mangleFuncType(t
, t
, t
->mod
, t
->next
);
210 void mangleFuncType(TypeFunction
*t
, TypeFunction
*ta
, unsigned char modMask
, Type
*tret
)
212 //printf("mangleFuncType() %s\n", t->toChars());
215 t
->inuse
= 2; // flag error to caller
220 if (modMask
!= t
->mod
)
221 MODtoDecoBuffer(buf
, t
->mod
);
226 case LINKd
: mc
= 'F'; break;
227 case LINKc
: mc
= 'U'; break;
228 case LINKwindows
: mc
= 'W'; break;
229 case LINKpascal
: mc
= 'V'; break;
230 case LINKcpp
: mc
= 'R'; break;
231 case LINKobjc
: mc
= 'Y'; break;
237 if (ta
->purity
|| ta
->isnothrow
|| ta
->isnogc
|| ta
->isproperty
|| ta
->isref
|| ta
->trust
|| ta
->isreturn
|| ta
->isscope
)
240 buf
->writestring("Na");
242 buf
->writestring("Nb");
244 buf
->writestring("Nc");
246 buf
->writestring("Nd");
248 buf
->writestring("Ni");
250 buf
->writestring("Nj");
251 if (ta
->isscope
&& !ta
->isreturn
&& !ta
->isscopeinferred
)
252 buf
->writestring("Nl");
256 buf
->writestring("Ne");
259 buf
->writestring("Nf");
266 // Write argument types
267 paramsToDecoBuffer(t
->parameters
);
268 //if (buf->data[buf->offset - 1] == '@') halt();
269 buf
->writeByte('Z' - t
->varargs
); // mark end of arg list
271 visitWithMask(tret
, 0);
276 void visit(TypeIdentifier
*t
)
279 const char *name
= t
->ident
->toChars();
280 size_t len
= strlen(name
);
281 buf
->printf("%u%s", (unsigned)len
, name
);
284 void visit(TypeEnum
*t
)
287 t
->sym
->accept(this);
290 void visit(TypeStruct
*t
)
292 //printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", t->toChars(), name);
294 t
->sym
->accept(this);
297 void visit(TypeClass
*t
)
299 //printf("TypeClass::toDecoBuffer('%s' mod=%x) = '%s'\n", t->toChars(), mod, name);
301 t
->sym
->accept(this);
304 void visit(TypeTuple
*t
)
306 //printf("TypeTuple::toDecoBuffer() t = %p, %s\n", t, t->toChars());
312 v
.paramsToDecoBuffer(t
->arguments
);
313 int len
= (int)buf2
.offset
;
314 buf
->printf("%d%.*s", len
, len
, buf2
.extractData());
317 void visit(TypeNull
*t
)
322 ////////////////////////////////////////////////////////////////////////////
324 void mangleDecl(Declaration
*sthis
)
328 assert(sthis
->ident
);
329 const char *id
= sthis
->ident
->toChars();
332 if (FuncDeclaration
*fd
= sthis
->isFuncDeclaration())
334 mangleFunc(fd
, false);
336 else if (sthis
->type
->deco
)
338 buf
->writestring(sthis
->type
->deco
);
344 void mangleParent(Dsymbol
*s
)
347 if (TemplateInstance
*ti
= s
->isTemplateInstance())
348 p
= ti
->isTemplateMixin() ? ti
->parent
: ti
->tempdecl
->parent
;
358 const char *id
= p
->ident
->toChars();
361 if (FuncDeclaration
*f
= p
->isFuncDeclaration())
369 void mangleFunc(FuncDeclaration
*fd
, bool inParent
)
371 //printf("deco = '%s'\n", fd->type->deco ? fd->type->deco : "null");
372 //printf("fd->type = %s\n", fd->type->toChars());
373 if (fd
->needThis() || fd
->isNested())
377 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
378 TypeFunction
*tfo
= (TypeFunction
*)fd
->originalType
;
379 mangleFuncType(tf
, tfo
, 0, NULL
);
381 else if (fd
->type
->deco
)
383 buf
->writestring(fd
->type
->deco
);
387 printf("[%s] %s %s\n", fd
->loc
.toChars(), fd
->toChars(), fd
->type
->toChars());
388 assert(0); // don't mangle function until semantic3 done.
392 /************************************************************
393 * Write length prefixed string to buf.
395 void toBuffer(const char *id
, Dsymbol
*s
)
397 size_t len
= strlen(id
);
398 if (len
>= 8 * 1024 * 1024) // 8 megs ought be enough for anyone
399 s
->error("excessive length %llu for symbol, possible recursive expansion?", len
);
402 buf
->printf("%llu", (ulonglong
)len
);
407 void visit(Declaration
*d
)
409 //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n",
410 // d, d->toChars(), d->parent ? d->parent->toChars() : "null", d->linkage);
411 if (!d
->parent
|| d
->parent
->isModule() || d
->linkage
== LINKcpp
) // if at global scope
422 buf
->writestring(d
->ident
->toChars());
426 buf
->writestring(Target::toCppMangle(d
));
430 d
->error("forward declaration");
431 buf
->writestring(d
->ident
->toChars());
435 fprintf(stderr
, "'%s', linkage = %d\n", d
->toChars(), d
->linkage
);
441 buf
->writestring("_D");
445 /******************************************************************************
446 * Normally FuncDeclaration and FuncAliasDeclaration have overloads.
447 * If and only if there is no overloads, mangle() could return
448 * exact mangled name.
451 * void foo(long) {} // _D4test3fooFlZv
452 * void foo(string) {} // _D4test3fooFAyaZv
454 * // from FuncDeclaration::mangle().
455 * pragma(msg, foo.mangleof); // prints unexact mangled name "4test3foo"
456 * // by calling Dsymbol::mangle()
458 * // from FuncAliasDeclaration::mangle()
459 * pragma(msg, __traits(getOverloads, test, "foo")[0].mangleof); // "_D4test3fooFlZv"
460 * pragma(msg, __traits(getOverloads, test, "foo")[1].mangleof); // "_D4test3fooFAyaZv"
462 * If a function has no overloads, .mangleof property still returns exact mangled name.
465 * pragma(msg, bar.mangleof); // still prints "_D4test3barFZv"
466 * // by calling FuncDeclaration::mangleExact().
468 void visit(FuncDeclaration
*fd
)
473 visit((Dsymbol
*)fd
);
477 void visit(FuncAliasDeclaration
*fd
)
479 FuncDeclaration
*f
= fd
->toAliasFunc();
480 FuncAliasDeclaration
*fa
= f
->isFuncAliasDeclaration();
481 if (!fd
->hasOverloads
&& !fa
)
491 visit((Dsymbol
*)fd
);
494 void visit(OverDeclaration
*od
)
498 visit((Dsymbol
*)od
);
502 if (FuncDeclaration
*fd
= od
->aliassym
->isFuncDeclaration())
504 if (!od
->hasOverloads
|| fd
->isUnique())
510 if (TemplateDeclaration
*td
= od
->aliassym
->isTemplateDeclaration())
512 if (!od
->hasOverloads
|| td
->overnext
== NULL
)
518 visit((Dsymbol
*)od
);
521 void mangleExact(FuncDeclaration
*fd
)
523 assert(!fd
->isFuncAliasDeclaration());
525 if (fd
->mangleOverride
)
527 buf
->writestring(fd
->mangleOverride
);
533 buf
->writestring("_Dmain");
537 if (fd
->isWinMain() || fd
->isDllMain() || fd
->ident
== Id::tls_get_addr
)
539 buf
->writestring(fd
->ident
->toChars());
543 visit((Declaration
*)fd
);
546 void visit(VarDeclaration
*vd
)
548 if (vd
->mangleOverride
)
550 buf
->writestring(vd
->mangleOverride
);
554 visit((Declaration
*)vd
);
557 void visit(AggregateDeclaration
*ad
)
559 ClassDeclaration
*cd
= ad
->isClassDeclaration();
560 Dsymbol
*parentsave
= ad
->parent
;
563 /* These are reserved to the compiler, so keep simple
566 if ((cd
->ident
== Id::Exception
&& cd
->parent
->ident
== Id::object
) ||
567 cd
->ident
== Id::TypeInfo
||
568 cd
->ident
== Id::TypeInfo_Struct
||
569 cd
->ident
== Id::TypeInfo_Class
||
570 cd
->ident
== Id::TypeInfo_Tuple
||
571 cd
== ClassDeclaration::object
||
572 cd
== Type::typeinfoclass
||
573 cd
== Module::moduleinfo
||
574 strncmp(cd
->ident
->toChars(), "TypeInfo_", 9) == 0)
576 // Don't mangle parent
581 visit((Dsymbol
*)ad
);
583 ad
->parent
= parentsave
;
586 void visit(TemplateInstance
*ti
)
589 ti
->error("is not defined");
594 const char *id
= ti
->ident
? ti
->ident
->toChars() : ti
->toChars();
597 //printf("TemplateInstance::mangle() %s = %s\n", ti->toChars(), ti->id);
600 void visit(Dsymbol
*s
)
604 const char *id
= s
->ident
? s
->ident
->toChars() : s
->toChars();
607 //printf("Dsymbol::mangle() %s = %s\n", s->toChars(), id);
610 ////////////////////////////////////////////////////////////////////////////
612 void visit(Expression
*e
)
614 e
->error("expression %s is not a valid template value argument", e
->toChars());
617 void visit(IntegerExp
*e
)
619 if ((sinteger_t
)e
->value
< 0)
620 buf
->printf("N%lld", -e
->value
);
622 buf
->printf("i%lld", e
->value
);
625 void visit(RealExp
*e
)
628 realToMangleBuffer(e
->value
);
631 void realToMangleBuffer(real_t value
)
633 /* Rely on %A to get portable mangling.
634 * Must munge result to get only identifier characters.
636 * Possible values from %A => mangled result
640 * -0X1.1BC18BA997B95P+79 => N11BC18BA997B95P79
644 if (CTFloat::isNaN(value
))
645 buf
->writestring("NAN"); // no -NAN bugs
646 else if (CTFloat::isInfinity(value
))
647 buf
->writestring(value
< CTFloat::zero
? "NINF" : "INF");
650 const size_t BUFFER_LEN
= 36;
651 char buffer
[BUFFER_LEN
];
652 size_t n
= CTFloat::sprint(buffer
, 'A', value
);
653 assert(n
< BUFFER_LEN
);
654 for (size_t i
= 0; i
< n
; i
++)
670 break; // skip leading 0X
680 void visit(ComplexExp
*e
)
683 realToMangleBuffer(e
->toReal());
684 buf
->writeByte('c'); // separate the two
685 realToMangleBuffer(e
->toImaginary());
688 void visit(NullExp
*)
693 void visit(StringExp
*e
)
700 /* Write string in UTF-8 format
706 q
= (utf8_t
*)e
->string
;
712 for (size_t u
= 0; u
< e
->len
; )
715 const char *p
= utf_decodeWchar((unsigned short *)e
->string
, e
->len
, &u
, &c
);
721 q
= (utf8_t
*)tmp
.data
;
727 for (size_t u
= 0; u
< e
->len
; u
++)
729 unsigned c
= ((unsigned *)e
->string
)[u
];
730 if (!utf_isValidDchar(c
))
731 e
->error("invalid UCS-32 char \\U%08x", c
);
735 q
= (utf8_t
*)tmp
.data
;
742 buf
->reserve(1 + 11 + 2 * qlen
);
744 buf
->printf("%d_", (int)qlen
); // nbytes <= 11
746 for (utf8_t
*p
= (utf8_t
*)buf
->data
+ buf
->offset
, *pend
= p
+ 2 * qlen
;
747 p
< pend
; p
+= 2, ++q
)
749 utf8_t hi
= *q
>> 4 & 0xF;
750 p
[0] = (utf8_t
)(hi
< 10 ? hi
+ '0' : hi
- 10 + 'a');
751 utf8_t lo
= *q
& 0xF;
752 p
[1] = (utf8_t
)(lo
< 10 ? lo
+ '0' : lo
- 10 + 'a');
754 buf
->offset
+= 2 * qlen
;
757 void visit(ArrayLiteralExp
*e
)
759 size_t dim
= e
->elements
? e
->elements
->dim
: 0;
760 buf
->printf("A%u", dim
);
761 for (size_t i
= 0; i
< dim
; i
++)
763 e
->getElement(i
)->accept(this);
767 void visit(AssocArrayLiteralExp
*e
)
769 size_t dim
= e
->keys
->dim
;
770 buf
->printf("A%u", dim
);
771 for (size_t i
= 0; i
< dim
; i
++)
773 (*e
->keys
)[i
]->accept(this);
774 (*e
->values
)[i
]->accept(this);
778 void visit(StructLiteralExp
*e
)
780 size_t dim
= e
->elements
? e
->elements
->dim
: 0;
781 buf
->printf("S%u", dim
);
782 for (size_t i
= 0; i
< dim
; i
++)
784 Expression
*ex
= (*e
->elements
)[i
];
788 buf
->writeByte('v'); // 'v' for void
792 ////////////////////////////////////////////////////////////////////////////
794 void paramsToDecoBuffer(Parameters
*parameters
)
796 //printf("Parameter::paramsToDecoBuffer()\n");
797 Parameter_foreach(parameters
, ¶msToDecoBufferDg
, (void *)this);
800 static int paramsToDecoBufferDg(void *ctx
, size_t, Parameter
*p
)
802 p
->accept((Visitor
*)ctx
);
806 void visit(Parameter
*p
)
808 if (p
->storageClass
& STCscope
&& !(p
->storageClass
& STCscopeinferred
))
810 // 'return inout ref' is the same as 'inout ref'
811 if ((p
->storageClass
& (STCreturn
| STCwild
)) == STCreturn
)
812 buf
->writestring("Nk");
813 switch (p
->storageClass
& (STCin
| STCout
| STCref
| STClazy
))
830 visitWithMask(p
->type
, 0);
834 /******************************************************************************
835 * Returns exact mangled name of function.
837 const char *mangleExact(FuncDeclaration
*fd
)
839 if (!fd
->mangleString
)
844 fd
->mangleString
= buf
.extractString();
846 return fd
->mangleString
;
849 void mangleToBuffer(Type
*t
, OutBuffer
*buf
)
852 v
.visitWithMask(t
, 0);
855 void mangleToBuffer(Expression
*e
, OutBuffer
*buf
)
861 void mangleToBuffer(Dsymbol
*s
, OutBuffer
*buf
)