]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/dmd/dmangle.c
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2020 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
11 #include "root/dsystem.h"
12 #include "root/root.h"
16 #include "declaration.h"
17 #include "aggregate.h"
25 #include "expression.h"
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
);
31 static const char *mangleChar
[TMAX
];
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";
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";
63 mangleChar
[Timaginary32
] = "o";
64 mangleChar
[Timaginary64
] = "p";
65 mangleChar
[Timaginary80
] = "j";
66 mangleChar
[Tcomplex32
] = "q";
67 mangleChar
[Tcomplex64
] = "r";
68 mangleChar
[Tcomplex80
] = "c";
70 mangleChar
[Tbool
] = "b";
71 mangleChar
[Tchar
] = "a";
72 mangleChar
[Twchar
] = "u";
73 mangleChar
[Tdchar
] = "w";
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
] = "@";
85 mangleChar
[Tnull
] = "n"; // same as TypeNone
87 for (size_t i
= 0; i
< TMAX
; i
++)
90 fprintf(stderr
, "ty = %llu\n", (ulonglong
)i
);
91 assert(mangleChar
[i
]);
95 /*********************************
98 void MODtoDecoBuffer(OutBuffer
*buf
, MOD mod
)
113 case MODshared
| MODconst
:
114 buf
->writestring("Ox");
117 buf
->writestring("Ng");
120 buf
->writestring("Ngx");
122 case MODshared
| MODwild
:
123 buf
->writestring("ONg");
125 case MODshared
| MODwildconst
:
126 buf
->writestring("ONgx");
133 class Mangler
: public Visitor
138 Mangler(OutBuffer
*buf
)
144 ////////////////////////////////////////////////////////////////////////////
146 /**************************************************
150 void visitWithMask(Type
*t
, unsigned char modMask
)
152 if (modMask
!= t
->mod
)
154 MODtoDecoBuffer(buf
, t
->mod
);
161 buf
->writestring(mangleChar
[t
->ty
]);
164 void visit(TypeNext
*t
)
167 visitWithMask(t
->next
, t
->mod
);
170 void visit(TypeVector
*t
)
172 buf
->writestring("Nh");
173 visitWithMask(t
->basetype
, t
->mod
);
176 void visit(TypeSArray
*t
)
180 buf
->printf("%llu", t
->dim
->toInteger());
182 visitWithMask(t
->next
, t
->mod
);
185 void visit(TypeDArray
*t
)
189 visitWithMask(t
->next
, t
->mod
);
192 void visit(TypeAArray
*t
)
195 visitWithMask(t
->index
, 0);
196 visitWithMask(t
->next
, t
->mod
);
199 void visit(TypeFunction
*t
)
201 //printf("TypeFunction::toDecoBuffer() t = %p %s\n", t, t->toChars());
202 //static int nest; if (++nest == 50) *(char*)0=0;
204 mangleFuncType(t
, t
, t
->mod
, t
->next
);
207 void mangleFuncType(TypeFunction
*t
, TypeFunction
*ta
, unsigned char modMask
, Type
*tret
)
209 //printf("mangleFuncType() %s\n", t->toChars());
212 t
->inuse
= 2; // flag error to caller
217 if (modMask
!= t
->mod
)
218 MODtoDecoBuffer(buf
, t
->mod
);
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;
234 if (ta
->purity
|| ta
->isnothrow
|| ta
->isnogc
|| ta
->isproperty
|| ta
->isref
|| ta
->trust
|| ta
->isreturn
|| ta
->isscope
)
237 buf
->writestring("Na");
239 buf
->writestring("Nb");
241 buf
->writestring("Nc");
243 buf
->writestring("Nd");
245 buf
->writestring("Ni");
247 buf
->writestring("Nj");
248 if (ta
->isscope
&& !ta
->isreturn
&& !ta
->isscopeinferred
)
249 buf
->writestring("Nl");
253 buf
->writestring("Ne");
256 buf
->writestring("Nf");
263 // Write argument types
264 paramsToDecoBuffer(t
->parameterList
.parameters
);
265 //if (buf->data[buf->offset - 1] == '@') halt();
266 buf
->writeByte('Z' - t
->parameterList
.varargs
); // mark end of arg list
268 visitWithMask(tret
, 0);
273 void visit(TypeIdentifier
*t
)
276 const char *name
= t
->ident
->toChars();
277 size_t len
= strlen(name
);
278 buf
->printf("%u%s", (unsigned)len
, name
);
281 void visit(TypeEnum
*t
)
284 t
->sym
->accept(this);
287 void visit(TypeStruct
*t
)
289 //printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", t->toChars(), name);
291 t
->sym
->accept(this);
294 void visit(TypeClass
*t
)
296 //printf("TypeClass::toDecoBuffer('%s' mod=%x) = '%s'\n", t->toChars(), mod, name);
298 t
->sym
->accept(this);
301 void visit(TypeTuple
*t
)
303 //printf("TypeTuple::toDecoBuffer() t = %p, %s\n", t, t->toChars());
309 v
.paramsToDecoBuffer(t
->arguments
);
310 const char *s
= buf2
.peekChars();
311 int len
= (int)buf2
.offset
;
312 buf
->printf("%d%.*s", len
, len
, s
);
315 void visit(TypeNull
*t
)
320 ////////////////////////////////////////////////////////////////////////////
322 void mangleDecl(Declaration
*sthis
)
326 assert(sthis
->ident
);
327 const char *id
= sthis
->ident
->toChars();
330 if (FuncDeclaration
*fd
= sthis
->isFuncDeclaration())
332 mangleFunc(fd
, false);
334 else if (sthis
->type
->deco
)
336 buf
->writestring(sthis
->type
->deco
);
342 void mangleParent(Dsymbol
*s
)
345 if (TemplateInstance
*ti
= s
->isTemplateInstance())
346 p
= ti
->isTemplateMixin() ? ti
->parent
: ti
->tempdecl
->parent
;
356 const char *id
= p
->ident
->toChars();
359 if (FuncDeclaration
*f
= p
->isFuncDeclaration())
367 void mangleFunc(FuncDeclaration
*fd
, bool inParent
)
369 //printf("deco = '%s'\n", fd->type->deco ? fd->type->deco : "null");
370 //printf("fd->type = %s\n", fd->type->toChars());
371 if (fd
->needThis() || fd
->isNested())
375 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
376 TypeFunction
*tfo
= (TypeFunction
*)fd
->originalType
;
377 mangleFuncType(tf
, tfo
, 0, NULL
);
379 else if (fd
->type
->deco
)
381 buf
->writestring(fd
->type
->deco
);
385 printf("[%s] %s %s\n", fd
->loc
.toChars(), fd
->toChars(), fd
->type
->toChars());
386 assert(0); // don't mangle function until semantic3 done.
390 /************************************************************
391 * Write length prefixed string to buf.
393 void toBuffer(const char *id
, Dsymbol
*s
)
395 size_t len
= strlen(id
);
396 if (len
>= 8 * 1024 * 1024) // 8 megs ought be enough for anyone
397 s
->error("excessive length %llu for symbol, possible recursive expansion?", len
);
400 buf
->printf("%llu", (ulonglong
)len
);
405 void visit(Declaration
*d
)
407 //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n",
408 // d, d->toChars(), d->parent ? d->parent->toChars() : "null", d->linkage);
409 if (!d
->parent
|| d
->parent
->isModule() || d
->linkage
== LINKcpp
) // if at global scope
420 buf
->writestring(d
->ident
->toChars());
424 buf
->writestring(target
.cpp
.toMangle(d
));
428 d
->error("forward declaration");
429 buf
->writestring(d
->ident
->toChars());
433 fprintf(stderr
, "'%s', linkage = %d\n", d
->toChars(), d
->linkage
);
439 buf
->writestring("_D");
443 /******************************************************************************
444 * Normally FuncDeclaration and FuncAliasDeclaration have overloads.
445 * If and only if there is no overloads, mangle() could return
446 * exact mangled name.
449 * void foo(long) {} // _D4test3fooFlZv
450 * void foo(string) {} // _D4test3fooFAyaZv
452 * // from FuncDeclaration::mangle().
453 * pragma(msg, foo.mangleof); // prints unexact mangled name "4test3foo"
454 * // by calling Dsymbol::mangle()
456 * // from FuncAliasDeclaration::mangle()
457 * pragma(msg, __traits(getOverloads, test, "foo")[0].mangleof); // "_D4test3fooFlZv"
458 * pragma(msg, __traits(getOverloads, test, "foo")[1].mangleof); // "_D4test3fooFAyaZv"
460 * If a function has no overloads, .mangleof property still returns exact mangled name.
463 * pragma(msg, bar.mangleof); // still prints "_D4test3barFZv"
464 * // by calling FuncDeclaration::mangleExact().
466 void visit(FuncDeclaration
*fd
)
471 visit((Dsymbol
*)fd
);
475 void visit(FuncAliasDeclaration
*fd
)
477 FuncDeclaration
*f
= fd
->toAliasFunc();
478 FuncAliasDeclaration
*fa
= f
->isFuncAliasDeclaration();
479 if (!fd
->hasOverloads
&& !fa
)
489 visit((Dsymbol
*)fd
);
492 void visit(OverDeclaration
*od
)
496 visit((Dsymbol
*)od
);
500 if (FuncDeclaration
*fd
= od
->aliassym
->isFuncDeclaration())
502 if (!od
->hasOverloads
|| fd
->isUnique())
508 if (TemplateDeclaration
*td
= od
->aliassym
->isTemplateDeclaration())
510 if (!od
->hasOverloads
|| td
->overnext
== NULL
)
516 visit((Dsymbol
*)od
);
519 void mangleExact(FuncDeclaration
*fd
)
521 assert(!fd
->isFuncAliasDeclaration());
523 if (fd
->mangleOverride
.length
)
525 buf
->writestring(fd
->mangleOverride
.ptr
);
531 buf
->writestring("_Dmain");
535 if (fd
->isWinMain() || fd
->isDllMain() || fd
->ident
== Id::tls_get_addr
)
537 buf
->writestring(fd
->ident
->toChars());
541 visit((Declaration
*)fd
);
544 void visit(VarDeclaration
*vd
)
546 if (vd
->mangleOverride
.length
)
548 buf
->writestring(vd
->mangleOverride
.ptr
);
552 visit((Declaration
*)vd
);
555 void visit(AggregateDeclaration
*ad
)
557 ClassDeclaration
*cd
= ad
->isClassDeclaration();
558 Dsymbol
*parentsave
= ad
->parent
;
561 /* These are reserved to the compiler, so keep simple
564 if ((cd
->ident
== Id::Exception
&& cd
->parent
->ident
== Id::object
) ||
565 cd
->ident
== Id::TypeInfo
||
566 cd
->ident
== Id::TypeInfo_Struct
||
567 cd
->ident
== Id::TypeInfo_Class
||
568 cd
->ident
== Id::TypeInfo_Tuple
||
569 cd
== ClassDeclaration::object
||
570 cd
== Type::typeinfoclass
||
571 cd
== Module::moduleinfo
||
572 strncmp(cd
->ident
->toChars(), "TypeInfo_", 9) == 0)
574 // Don't mangle parent
579 visit((Dsymbol
*)ad
);
581 ad
->parent
= parentsave
;
584 void visit(TemplateInstance
*ti
)
587 ti
->error("is not defined");
592 const char *id
= ti
->ident
? ti
->ident
->toChars() : ti
->toChars();
595 //printf("TemplateInstance::mangle() %s = %s\n", ti->toChars(), ti->id);
598 void visit(Dsymbol
*s
)
602 const char *id
= s
->ident
? s
->ident
->toChars() : s
->toChars();
605 //printf("Dsymbol::mangle() %s = %s\n", s->toChars(), id);
608 ////////////////////////////////////////////////////////////////////////////
610 void visit(Expression
*e
)
612 e
->error("expression %s is not a valid template value argument", e
->toChars());
615 void visit(IntegerExp
*e
)
617 if ((sinteger_t
)e
->value
< 0)
618 buf
->printf("N%lld", -e
->value
);
620 buf
->printf("i%lld", e
->value
);
623 void visit(RealExp
*e
)
626 realToMangleBuffer(e
->value
);
629 void realToMangleBuffer(real_t value
)
631 /* Rely on %A to get portable mangling.
632 * Must munge result to get only identifier characters.
634 * Possible values from %A => mangled result
638 * -0X1.1BC18BA997B95P+79 => N11BC18BA997B95P79
642 if (CTFloat::isNaN(value
))
643 buf
->writestring("NAN"); // no -NAN bugs
644 else if (CTFloat::isInfinity(value
))
645 buf
->writestring(value
< CTFloat::zero
? "NINF" : "INF");
648 const size_t BUFFER_LEN
= 36;
649 char buffer
[BUFFER_LEN
];
650 size_t n
= CTFloat::sprint(buffer
, 'A', value
);
651 assert(n
< BUFFER_LEN
);
652 for (size_t i
= 0; i
< n
; i
++)
668 break; // skip leading 0X
678 void visit(ComplexExp
*e
)
681 realToMangleBuffer(e
->toReal());
682 buf
->writeByte('c'); // separate the two
683 realToMangleBuffer(e
->toImaginary());
686 void visit(NullExp
*)
691 void visit(StringExp
*e
)
698 /* Write string in UTF-8 format
704 q
= (utf8_t
*)e
->string
;
710 for (size_t u
= 0; u
< e
->len
; )
713 const char *p
= utf_decodeWchar((unsigned short *)e
->string
, e
->len
, &u
, &c
);
719 q
= (utf8_t
*)tmp
.data
;
725 for (size_t u
= 0; u
< e
->len
; u
++)
727 unsigned c
= ((unsigned *)e
->string
)[u
];
728 if (!utf_isValidDchar(c
))
729 e
->error("invalid UCS-32 char \\U%08x", c
);
733 q
= (utf8_t
*)tmp
.data
;
740 buf
->reserve(1 + 11 + 2 * qlen
);
742 buf
->printf("%d_", (int)qlen
); // nbytes <= 11
744 for (utf8_t
*p
= (utf8_t
*)buf
->data
+ buf
->offset
, *pend
= p
+ 2 * qlen
;
745 p
< pend
; p
+= 2, ++q
)
747 utf8_t hi
= *q
>> 4 & 0xF;
748 p
[0] = (utf8_t
)(hi
< 10 ? hi
+ '0' : hi
- 10 + 'a');
749 utf8_t lo
= *q
& 0xF;
750 p
[1] = (utf8_t
)(lo
< 10 ? lo
+ '0' : lo
- 10 + 'a');
752 buf
->offset
+= 2 * qlen
;
755 void visit(ArrayLiteralExp
*e
)
757 size_t dim
= e
->elements
? e
->elements
->length
: 0;
758 buf
->printf("A%u", dim
);
759 for (size_t i
= 0; i
< dim
; i
++)
761 e
->getElement(i
)->accept(this);
765 void visit(AssocArrayLiteralExp
*e
)
767 size_t dim
= e
->keys
->length
;
768 buf
->printf("A%u", dim
);
769 for (size_t i
= 0; i
< dim
; i
++)
771 (*e
->keys
)[i
]->accept(this);
772 (*e
->values
)[i
]->accept(this);
776 void visit(StructLiteralExp
*e
)
778 size_t dim
= e
->elements
? e
->elements
->length
: 0;
779 buf
->printf("S%u", dim
);
780 for (size_t i
= 0; i
< dim
; i
++)
782 Expression
*ex
= (*e
->elements
)[i
];
786 buf
->writeByte('v'); // 'v' for void
790 ////////////////////////////////////////////////////////////////////////////
792 void paramsToDecoBuffer(Parameters
*parameters
)
794 //printf("Parameter::paramsToDecoBuffer()\n");
795 Parameter_foreach(parameters
, ¶msToDecoBufferDg
, (void *)this);
798 static int paramsToDecoBufferDg(void *ctx
, size_t, Parameter
*p
)
800 p
->accept((Visitor
*)ctx
);
804 void visit(Parameter
*p
)
806 if (p
->storageClass
& STCscope
&& !(p
->storageClass
& STCscopeinferred
))
808 // 'return inout ref' is the same as 'inout ref'
809 if ((p
->storageClass
& (STCreturn
| STCwild
)) == STCreturn
)
810 buf
->writestring("Nk");
811 switch (p
->storageClass
& (STCin
| STCout
| STCref
| STClazy
))
828 visitWithMask(p
->type
, 0);
832 /******************************************************************************
833 * Returns exact mangled name of function.
835 const char *mangleExact(FuncDeclaration
*fd
)
837 if (!fd
->mangleString
)
842 fd
->mangleString
= buf
.extractChars();
844 return fd
->mangleString
;
847 void mangleToBuffer(Type
*t
, OutBuffer
*buf
)
850 v
.visitWithMask(t
, 0);
853 void mangleToBuffer(Expression
*e
, OutBuffer
*buf
)
859 void mangleToBuffer(Dsymbol
*s
, OutBuffer
*buf
)