-45fa6cfd20827bb4252a616dc789514a1e673687
+2bd4fc3fed8b8cd9760e77c6b2a1905cd84d0e70
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
#include "root/dsystem.h"
#include "root/root.h"
+#include "root/aav.h"
#include "mangle.h"
#include "init.h"
class Mangler : public Visitor
{
public:
+ AA *types;
+ AA *idents;
OutBuffer *buf;
Mangler(OutBuffer *buf)
{
+ this->types = NULL;
+ this->idents = NULL;
this->buf = buf;
}
+ /**
+ * writes a back reference with the relative position encoded with base 26
+ * using upper case letters for all digits but the last digit which uses
+ * a lower case letter.
+ * The decoder has to look up the referenced position to determine
+ * whether the back reference is an identifer (starts with a digit)
+ * or a type (starts with a letter).
+ *
+ * Params:
+ * pos = relative position to encode
+ */
+ void writeBackRef(size_t pos)
+ {
+ buf->writeByte('Q');
+ const size_t base = 26;
+ size_t mul = 1;
+ while (pos >= mul * base)
+ mul *= base;
+ while (mul >= base)
+ {
+ unsigned char dig = (unsigned char)(pos / mul);
+ buf->writeByte('A' + dig);
+ pos -= dig * mul;
+ mul /= base;
+ }
+ buf->writeByte('a' + (unsigned char)pos);
+ }
+
+ /**
+ * Back references a non-basic type
+ *
+ * The encoded mangling is
+ * 'Q' <relative position of first occurrence of type>
+ *
+ * Params:
+ * t = the type to encode via back referencing
+ *
+ * Returns:
+ * true if the type was found. A back reference has been encoded.
+ * false if the type was not found. The current position is saved for later back references.
+ */
+ bool backrefType(Type *t)
+ {
+ if (!t->isTypeBasic())
+ {
+ size_t *p = (size_t *)dmd_aaGet(&types, (void *)t);
+ if (*p)
+ {
+ writeBackRef(buf->length() - *p);
+ return true;
+ }
+ *p = buf->length();
+ }
+ return false;
+ }
+
+ /**
+ * Back references a single identifier
+ *
+ * The encoded mangling is
+ * 'Q' <relative position of first occurrence of type>
+ *
+ * Params:
+ * id = the identifier to encode via back referencing
+ *
+ * Returns:
+ * true if the identifier was found. A back reference has been encoded.
+ * false if the identifier was not found. The current position is saved for later back references.
+ */
+ bool backrefIdentifier(Identifier *id)
+ {
+ size_t *p = (size_t *)dmd_aaGet(&idents, (void *)id);
+ if (*p)
+ {
+ writeBackRef(buf->length() - *p);
+ return true;
+ }
+ *p = buf->length();
+ return false;
+ }
+
+ void mangleSymbol(Dsymbol *s)
+ {
+ s->accept(this);
+ }
+
+ void mangleType(Type *t)
+ {
+ if (!backrefType(t))
+ t->accept(this);
+ }
+
+ void mangleIdentifier(Identifier *id, Dsymbol *s)
+ {
+ if (!backrefIdentifier(id))
+ toBuffer(id->toChars(), s);
+ }
////////////////////////////////////////////////////////////////////////////
{
MODtoDecoBuffer(buf, t->mod);
}
- t->accept(this);
+ mangleType(t);
}
void visit(Type *t)
void mangleFuncType(TypeFunction *t, TypeFunction *ta, unsigned char modMask, Type *tret)
{
//printf("mangleFuncType() %s\n", t->toChars());
- if (t->inuse)
+ if (t->inuse && tret)
{
+ // printf("TypeFunction.mangleFuncType() t = %s inuse\n", t->toChars());
t->inuse = 2; // flag error to caller
return;
}
void visit(TypeEnum *t)
{
visit((Type *)t);
- t->sym->accept(this);
+ mangleSymbol(t->sym);
}
void visit(TypeStruct *t)
{
//printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", t->toChars(), name);
visit((Type *)t);
- t->sym->accept(this);
+ mangleSymbol(t->sym);
}
void visit(TypeClass *t)
{
//printf("TypeClass::toDecoBuffer('%s' mod=%x) = '%s'\n", t->toChars(), mod, name);
visit((Type *)t);
- t->sym->accept(this);
+ mangleSymbol(t->sym);
}
void visit(TypeTuple *t)
{
//printf("TypeTuple::toDecoBuffer() t = %p, %s\n", t, t->toChars());
visit((Type *)t);
-
- OutBuffer buf2;
- buf2.reserve(32);
- Mangler v(&buf2);
- v.paramsToDecoBuffer(t->arguments);
- const char *s = buf2.peekChars();
- int len = (int)buf2.length();
- buf->printf("%d%.*s", len, len, s);
+ paramsToDecoBuffer(t->arguments);
+ buf->writeByte('Z');
}
void visit(TypeNull *t)
mangleParent(sthis);
assert(sthis->ident);
- const char *id = sthis->ident->toChars();
- toBuffer(id, sthis);
-
+ mangleIdentifier(sthis->ident, sthis);
if (FuncDeclaration *fd = sthis->isFuncDeclaration())
{
mangleFunc(fd, false);
}
- else if (sthis->type->deco)
+ else if (sthis->type)
{
- buf->writestring(sthis->type->deco);
+ visitWithMask(sthis->type, 0);
}
else
assert(0);
if (p)
{
mangleParent(p);
-
- if (p->getIdent())
+ TemplateInstance *ti = p->isTemplateInstance();
+ if (ti && !ti->isTemplateMixin())
{
- const char *id = p->ident->toChars();
- toBuffer(id, s);
-
+ mangleTemplateInstance(ti);
+ }
+ else if (p->getIdent())
+ {
+ mangleIdentifier(p->ident, s);
if (FuncDeclaration *f = p->isFuncDeclaration())
mangleFunc(f, true);
}
TypeFunction *tfo = (TypeFunction *)fd->originalType;
mangleFuncType(tf, tfo, 0, NULL);
}
- else if (fd->type->deco)
+ else if (fd->type)
{
- buf->writestring(fd->type->deco);
+ visitWithMask(fd->type, 0);
}
else
{
- printf("[%s] %s %s\n", fd->loc.toChars(), fd->toChars(), fd->type->toChars());
+ printf("[%s] %s no type\n", fd->loc.toChars(), fd->toChars());
assert(0); // don't mangle function until semantic3 done.
}
}
void toBuffer(const char *id, Dsymbol *s)
{
size_t len = strlen(id);
- if (len >= 8 * 1024 * 1024) // 8 megs ought be enough for anyone
- s->error("excessive length %llu for symbol, possible recursive expansion?", len);
+ if (buf->length() + len >= 8 * 1024 * 1024) // 8 megs ought be enough for anyone
+ s->error("excessive length %llu for symbol, possible recursive expansion?", buf->length() + len);
else
{
buf->printf("%llu", (ulonglong)len);
}
}
- void visit(Declaration *d)
+ static const char *externallyMangledIdentifier(Declaration *d)
{
- //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n",
- // d, d->toChars(), d->parent ? d->parent->toChars() : "null", d->linkage);
if (!d->parent || d->parent->isModule() || d->linkage == LINKcpp) // if at global scope
{
switch (d->linkage)
{
case LINKd:
break;
-
case LINKc:
case LINKwindows:
case LINKobjc:
- buf->writestring(d->ident->toChars());
- return;
-
+ return d->ident->toChars();
case LINKcpp:
- buf->writestring(target.cpp.toMangle(d));
- return;
-
+ return target.cpp.toMangle(d);
case LINKdefault:
d->error("forward declaration");
- buf->writestring(d->ident->toChars());
- return;
-
+ return d->ident->toChars();
default:
fprintf(stderr, "'%s', linkage = %d\n", d->toChars(), d->linkage);
assert(0);
- return;
}
}
+ return NULL;
+ }
+ void visit(Declaration *d)
+ {
+ //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n",
+ // d, d->toChars(), d->parent ? d->parent->toChars() : "null", d->linkage);
+ if (const char *id = externallyMangledIdentifier(d))
+ {
+ buf->writestring(id);
+ return;
+ }
buf->writestring("_D");
mangleDecl(d);
}
}
if (fa)
{
- fa->accept(this);
+ mangleSymbol(fa);
return;
}
visit((Dsymbol *)fd);
{
if (!od->hasOverloads || td->overnext == NULL)
{
- td->accept(this);
+ mangleSymbol(td);
return;
}
}
else
mangleParent(ti);
- ti->getIdent();
- const char *id = ti->ident ? ti->ident->toChars() : ti->toChars();
- toBuffer(id, ti);
+ if (ti->isTemplateMixin() && ti->ident)
+ mangleIdentifier(ti->ident, ti);
+ else
+ mangleTemplateInstance(ti);
+ }
+
+ void mangleTemplateInstance(TemplateInstance *ti)
+ {
+ TemplateDeclaration *tempdecl = ti->tempdecl->isTemplateDeclaration();
+ assert(tempdecl);
+
+ // Use "__U" for the symbols declared inside template constraint.
+ const char T = ti->members ? 'T' : 'U';
+ buf->printf("__%c", T);
+ mangleIdentifier(tempdecl->ident, tempdecl);
- //printf("TemplateInstance::mangle() %s = %s\n", ti->toChars(), ti->id);
+ Objects *args = ti->tiargs;
+ size_t nparams = tempdecl->parameters->length - (tempdecl->isVariadic() ? 1 : 0);
+ for (size_t i = 0; i < args->length; i++)
+ {
+ RootObject *o = (*args)[i];
+ Type *ta = isType(o);
+ Expression *ea = isExpression(o);
+ Dsymbol *sa = isDsymbol(o);
+ Tuple *va = isTuple(o);
+ //printf("\to [%d] %p ta %p ea %p sa %p va %p\n", i, o, ta, ea, sa, va);
+ if (i < nparams && (*tempdecl->parameters)[i]->specialization())
+ buf->writeByte('H'); // https://issues.dlang.org/show_bug.cgi?id=6574
+ if (ta)
+ {
+ buf->writeByte('T');
+ visitWithMask(ta, 0);
+ }
+ else if (ea)
+ {
+ // Don't interpret it yet, it might actually be an alias template parameter.
+ // Only constfold manifest constants, not const/immutable lvalues, see https://issues.dlang.org/show_bug.cgi?id=17339.
+ const bool keepLvalue = true;
+ ea = ea->optimize(WANTvalue, keepLvalue);
+ if (ea->op == TOKvar)
+ {
+ sa = ((VarExp *)ea)->var;
+ ea = NULL;
+ goto Lsa;
+ }
+ if (ea->op == TOKthis)
+ {
+ sa = ((ThisExp *)ea)->var;
+ ea = NULL;
+ goto Lsa;
+ }
+ if (ea->op == TOKfunction)
+ {
+ if (((FuncExp *)ea)->td)
+ sa = ((FuncExp *)ea)->td;
+ else
+ sa = ((FuncExp *)ea)->fd;
+ ea = NULL;
+ goto Lsa;
+ }
+ buf->writeByte('V');
+ if (ea->op == TOKtuple)
+ {
+ ea->error("tuple is not a valid template value argument");
+ continue;
+ }
+ // Now that we know it is not an alias, we MUST obtain a value
+ unsigned olderr = global.errors;
+ ea = ea->ctfeInterpret();
+ if (ea->op == TOKerror || olderr != global.errors)
+ continue;
+
+ /* Use type mangling that matches what it would be for a function parameter
+ */
+ visitWithMask(ea->type, 0);
+ ea->accept(this);
+ }
+ else if (sa)
+ {
+ Lsa:
+ sa = sa->toAlias();
+ if (Declaration *d = sa->isDeclaration())
+ {
+ if (FuncAliasDeclaration *fad = d->isFuncAliasDeclaration())
+ d = fad->toAliasFunc();
+ if (d->mangleOverride.length)
+ {
+ buf->writeByte('X');
+ toBuffer(d->mangleOverride.ptr, d);
+ continue;
+ }
+ if (const char *id = externallyMangledIdentifier(d))
+ {
+ buf->writeByte('X');
+ toBuffer(id, d);
+ continue;
+ }
+ if (!d->type || !d->type->deco)
+ {
+ ti->error("forward reference of %s %s", d->kind(), d->toChars());
+ continue;
+ }
+ }
+ buf->writeByte('S');
+ mangleSymbol(sa);
+ }
+ else if (va)
+ {
+ assert(i + 1 == args->length); // must be last one
+ args = &va->objects;
+ i = -(size_t)1;
+ }
+ else
+ assert(0);
+ }
+ buf->writeByte('Z');
}
void visit(Dsymbol *s)
{
mangleParent(s);
-
- const char *id = s->ident ? s->ident->toChars() : s->toChars();
- toBuffer(id, s);
-
+ if (s->ident)
+ mangleIdentifier(s->ident, s);
+ else
+ toBuffer(s->toChars(), s);
//printf("Dsymbol::mangle() %s = %s\n", s->toChars(), id);
}
Mangler v(buf);
s->accept(&v);
}
+
+void mangleToBuffer(TemplateInstance *ti, OutBuffer *buf)
+{
+ Mangler v(buf);
+ v.mangleTemplateInstance(ti);
+}
Identifier *TemplateInstance::genIdent(Objects *args)
{
- TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration();
- assert(tempdecl);
-
//printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars());
+ assert(args == tiargs);
OutBuffer buf;
- const char *id = tempdecl->ident->toChars();
- if (!members)
- {
- // Use "__U" for the symbols declared inside template constraint.
- buf.printf("__U%llu%s", (ulonglong)strlen(id), id);
- }
- else
- buf.printf("__T%llu%s", (ulonglong)strlen(id), id);
- size_t nparams = tempdecl->parameters->length - (tempdecl->isVariadic() ? 1 : 0);
- for (size_t i = 0; i < args->length; i++)
- {
- RootObject *o = (*args)[i];
- Type *ta = isType(o);
- Expression *ea = isExpression(o);
- Dsymbol *sa = isDsymbol(o);
- Tuple *va = isTuple(o);
- //printf("\to [%d] %p ta %p ea %p sa %p va %p\n", i, o, ta, ea, sa, va);
- if (i < nparams && (*tempdecl->parameters)[i]->specialization())
- buf.writeByte('H'); // Bugzilla 6574
- if (ta)
- {
- buf.writeByte('T');
- if (ta->deco)
- buf.writestring(ta->deco);
- else
- {
- assert(global.errors);
- }
- }
- else if (ea)
- {
- // Don't interpret it yet, it might actually be an alias template parameter.
- // Only constfold manifest constants, not const/immutable lvalues, see https://issues.dlang.org/show_bug.cgi?id=17339.
- const bool keepLvalue = true;
- ea = ea->optimize(WANTvalue, keepLvalue);
- if (ea->op == TOKvar)
- {
- sa = ((VarExp *)ea)->var;
- ea = NULL;
- goto Lsa;
- }
- if (ea->op == TOKthis)
- {
- sa = ((ThisExp *)ea)->var;
- ea = NULL;
- goto Lsa;
- }
- if (ea->op == TOKfunction)
- {
- if (((FuncExp *)ea)->td)
- sa = ((FuncExp *)ea)->td;
- else
- sa = ((FuncExp *)ea)->fd;
- ea = NULL;
- goto Lsa;
- }
- buf.writeByte('V');
- if (ea->op == TOKtuple)
- {
- ea->error("tuple is not a valid template value argument");
- continue;
- }
- // Now that we know it is not an alias, we MUST obtain a value
- unsigned olderr = global.errors;
- ea = ea->ctfeInterpret();
- if (ea->op == TOKerror || olderr != global.errors)
- continue;
-
- /* Use deco that matches what it would be for a function parameter
- */
- buf.writestring(ea->type->deco);
- mangleToBuffer(ea, &buf);
- }
- else if (sa)
- {
- Lsa:
- buf.writeByte('S');
- sa = sa->toAlias();
- Declaration *d = sa->isDeclaration();
- if (d && (!d->type || !d->type->deco))
- {
- error("forward reference of %s %s", d->kind(), d->toChars());
- continue;
- }
-
- OutBuffer bufsa;
- mangleToBuffer(sa, &bufsa);
- const char *s = bufsa.extractChars();
-
- /* Bugzilla 3043: if the first character of s is a digit this
- * causes ambiguity issues because the digits of the two numbers are adjacent.
- * Current demanglers resolve this by trying various places to separate the
- * numbers until one gets a successful demangle.
- * Unfortunately, fixing this ambiguity will break existing binary
- * compatibility and the demanglers, so we'll leave it as is.
- */
- buf.printf("%u%s", (unsigned)strlen(s), s);
- }
- else if (va)
- {
- assert(i + 1 == args->length); // must be last one
- args = &va->objects;
- i = -(size_t)1;
- }
- else
- assert(0);
- }
- buf.writeByte('Z');
- id = buf.peekChars();
+ mangleToBuffer(this, &buf);
//printf("\tgenIdent = %s\n", id);
- return Identifier::idPool(id);
+ return Identifier::idPool(buf.peekChars());
}
/*************************************
/***************************************************/
// 8504
+import core.demangle : demangle;
+
void foo8504()()
{
static assert(typeof(foo8504!()).stringof == "void()");
static assert(typeof(foo8504!()).mangleof == "FZv");
- static assert(foo8504!().mangleof == "_D13testInference12__T7foo8504Z7foo8504FZv");
+ static assert(demangle(foo8504!().mangleof) == "void testInference.foo8504!().foo8504()");
}
auto toDelegate8504a(F)(auto ref F fp) { return fp; }
{
static assert(typeof(foo8504!()).stringof == "pure nothrow @nogc @safe void()");
static assert(typeof(foo8504!()).mangleof == "FNaNbNiNfZv");
- static assert(foo8504!().mangleof == "_D13testInference12__T7foo8504Z7foo8504FNaNbNiNfZv");
+ static assert(demangle(foo8504!().mangleof) == "pure nothrow @nogc @safe void testInference.foo8504!().foo8504()");
auto fp1 = toDelegate8504a(&testC8504);
auto fp2 = toDelegate8504b(&testC8504);
void dorecursive()
{
- recursive([0]);
+ recursive!"ratherLongSymbolNameToHitTheMaximumSymbolLengthEarlierThanTheTemplateRecursionLimit_";
}
-void recursive(R)(R r)
+void recursive(string name)()
{
- import std.algorithm;
- recursive( r.filter!(e=>true) );
+ struct S {} // define type to kick off mangler
+ static if (name.length <= (4 << 20))
+ recursive!(name ~ name);
}
--- /dev/null
+// helper for mangling tests with back references
+
+module imports.testmangle;
+
+public import core.demangle : demangle, demangleType;
+
+// detect mangle version
+private
+{
+ struct Detect;
+ Detect* detectMangle(Detect*);
+ void DetectTmpl(T)() {}
+}
+
+pragma(msg,detectMangle.mangleof);
+static if(detectMangle.mangleof == "_D7imports10testmangle12detectMangleFPSQL3H6DetectZQ1e")
+ enum { BackRefs = true, BackRefSymbols = true }
+else static if(detectMangle.mangleof == "_D7imports10testmangle12detectMangleFPSQBlQBg6DetectZQq")
+ enum { BackRefs = true, BackRefSymbols = false }
+else static if(detectMangle.mangleof == "_D7imports10testmangle12detectMangleFPS7imports10testmangle6DetectZPS7imports10testmangle6Detect")
+ enum { BackRefs = false, BackRefSymbols = false }
+else
+ static assert(false, "unknown mangling");
+
+private enum tmplMangle = (DetectTmpl!int).mangleof;
+pragma(msg,tmplMangle);
+static if(tmplMangle[0..40] == "_D7imports10testmangle__T10DetectTmplTiZ")
+ enum HasTemplateLength = false;
+else static if(tmplMangle[0..42] == "_D7imports10testmangle18__T10DetectTmplTiZ")
+ enum HasTemplateLength = true;
+else
+ static assert(false, "unknown mangling");
+
+pragma(msg,BackRefs);
+pragma(msg,BackRefSymbols);
+
+static if (BackRefs)
+{
+ string tl(string s)() { return null; }
+ string id(string s, string r, string r2 = null)() { return BackRefSymbols && r2 !is null ? r2 : r; }
+}
+else
+{
+ string tl(string s)() { return HasTemplateLength ? s : null; }
+ string id(string s, string r, string r2 = null)() { return s; }
+}
+
+bool equalDemangle(string m1, string m2)
+{
+ auto dm1 = demangle(m1);
+ auto dm2 = demangle(m2);
+ return dm1 == dm2;
+}
+
+string unsignedToString(ulong x)
+{
+ string s;
+ s ~= cast(char)('0' + (x % 10));
+ x /= 10;
+ while (x > 0)
+ {
+ s = cast(char)('0' + (x % 10)) ~ s;
+ x /= 10;
+ }
+ return s;
+}
// PERMUTE_ARGS:
module link6574;
+import imports.testmangle;
+
enum Method { A, B, }
int foo(Method method = Method.A)()
{
- static assert(foo.mangleof == "_D8link657428__T3fooVE8link65746Methodi0Z3fooFZi");
+ static assert(foo.mangleof == "_D8link6574"~tl!"28"~"__T3fooVE"~id!("8link6574","Qs")~"6Methodi0Z"~id!("3foo","Qs")~"FZi");
return 10 * foo!method();
}
int foo(Method method : Method.A)()
{
- static assert(foo.mangleof == "_D8link657429__T3fooHVE8link65746Methodi0Z3fooFZi");
+ static assert(foo.mangleof == "_D8link6574"~tl!"29"~"__T3fooHVE"~id!("8link6574","Qt")~"6Methodi0Z"~id!("3foo","Qt")~"FZi");
return 2;
}
int foo(Method method : Method.B)()
int bar(Method method = Method.B)()
{
- static assert(bar.mangleof == "_D8link657428__T3barVE8link65746Methodi1Z3barFZi");
+ static assert(bar.mangleof == "_D8link6574"~tl!"28"~"__T3barVE"~id!("8link6574","Qs")~"6Methodi1Z"~id!("3bar","Qs")~"FZi");
return 10 * bar!method();
}
int bar(Method method : Method.A)()
}
int bar(Method method : Method.B)()
{
- static assert(bar.mangleof == "_D8link657429__T3barHVE8link65746Methodi1Z3barFZi");
+ static assert(bar.mangleof == "_D8link6574"~tl!"29"~"__T3barHVE"~id!("8link6574","Qt")~"6Methodi1Z"~id!("3bar","Qt")~"FZi");
return 3;
}
// PERMUTE_ARGS:
// EXTRA_SOURCES: imports/mangle10077.d
+import imports.testmangle;
+
/***************************************************/
// 10077 - pragma(mangle)
static assert(C2774.foo2774.mangleof == "_D6mangle5C27747foo2774MFZi");
template TFoo2774(T) {}
-static assert(TFoo2774!int.mangleof == "6mangle15__T8TFoo2774TiZ");
+static assert(TFoo2774!int.mangleof == "6mangle"~tl!"15"~"__T8TFoo2774TiZ");
void test2774()
{
struct Test8847
{
- enum result1 = "S6mangle8Test88478__T3fooZ3fooMFZ6Result";
- enum result2 = "S6mangle8Test88478__T3fooZ3fooMxFiZ6Result";
+ enum result1 = "S6mangle8Test8847"~tl!("8")~"__T3fooZ"~id!("3foo","Qf")~"MFZ6Result";
+ enum result2 = "S6mangle8Test8847"~tl!("8")~"__T3fooZ"~id!("3foo","Qf")~"MxFiZ6Result";
auto foo()()
{
void test8847e()
{
- enum resultHere = "6mangle"~"9test8847eFZ"~"8__T3fooZ"~"3foo";
+ enum resultHere = "6mangle"~"9test8847eFZ"~tl!"8"~"__T3fooZ"~id!("3foo","Qf");
enum resultBar = "S"~resultHere~"MFNaNfNgiZ3Bar";
- enum resultFoo = "_D"~resultHere~"MFNaNbNiNfNgiZNg"~resultBar; // added 'Nb'
+ static if(BackRefs) {} else
+ enum resultFoo = "_D"~resultHere~"MFNaNbNiNfNgiZNg"~resultBar; // added 'Nb'
// Make template function to infer 'nothrow' attributes
auto foo()(inout int) pure @safe
return inout(Bar)();
}
+ import core.demangle : demangle, demangleType;
auto bar = foo(0);
static assert(typeof(bar).stringof == "Bar");
static assert(typeof(bar).mangleof == resultBar);
- static assert(foo!().mangleof == resultFoo);
+ enum fooDemangled = "pure nothrow @nogc @safe inout(mangle.test8847e().foo!().foo(inout(int)).Bar) mangle.test8847e().foo!().foo(inout(int))";
+
+ static if (BackRefs)
+ static assert(demangle(foo!().mangleof) == fooDemangled);
+ else
+ static assert(foo!().mangleof == resultFoo);
}
// --------
return S();
}
-static assert( bar12352 .mangleof == "_D6mangle8bar12352FNaNbNiNfZS6mangle8bar12352FZ1S");
+static assert( bar12352 .mangleof == "_D6mangle8bar12352FNaNbNiNfZS"~id!("6mangle8bar12352FZ","QBbQxFZ","QL2H")~"1S");
static assert(typeof(bar12352()) .mangleof == "S6mangle8bar12352FZ1S");
static assert(typeof(bar12352()).func.mangleof == "_D6mangle8bar12352FZ1S4funcMFZv");
return new C();
}
-static assert( baz12352 .mangleof == "_D6mangle8baz12352FNaNbNfZC6mangle8baz12352FZ1C");
+static assert( baz12352 .mangleof == "_D6mangle8baz12352FNaNbNfZC"~id!("6mangle8baz12352FZ","QzQuFZ","QL2F")~"1C");
static assert(typeof(baz12352()) .mangleof == "C6mangle8baz12352FZ1C");
static assert(typeof(baz12352()).func.mangleof == "_D6mangle8baz12352FZ1C4funcMFZv");
void test9525()
{
- enum result1 = "S6mangle8test9525FZ26__T5test1S136mangle5f9525Z5test1MFZ1S";
- enum result2 = "S6mangle8test9525FZ26__T5test2S136mangle5f9525Z5test2MFNaNbZ1S";
+ enum result1 = "S6mangle8test9525FZ"~tl!"26"~"__T5test1S"~tl!"13"~id!("6mangle","QBc")~"5f9525Z"~id!("5test1","Qr")~"MFZ1S";
+ enum result2 = "S6mangle8test9525FZ"~tl!"26"~"__T5test2S"~tl!"13"~id!("6mangle","QBc")~"5f9525Z"~id!("5test2","Qr")~"MFNaNbZ1S";
void test1(alias a)()
{
string TyName(string tail)()
{
enum s = "__T7Ty11718" ~ tail;
- enum int len = s.length;
- return "S6mangle" ~ len.stringof ~ s;
+ enum len = unsignedToString(s.length);
+ return "S6mangle" ~ tl!(len) ~ s;
}
string fnName(string paramPart)()
{
- enum s = "_D6mangle35__T7fn11718T"~
+ enum s = "_D6mangle"~tl!("35")~"__T7fn11718T"~
"S6mangle9test11718FZ1AZ7fn11718"~paramPart~"1a"~
"S6mangle9test11718FZ1A";
- enum int len = s.length;
- return len.stringof ~ s;
+ enum len = unsignedToString(s.length);
+ return tl!len ~ s;
}
enum result1 = TyName!("S" ~ fnName!("F"~"S6mangle9test11718FZ1A"~"Z") ~ "Z") ~ "7Ty11718";
enum result2 = TyName!("S" ~ fnName!("F"~"" ~"Z") ~ "Z") ~ "7Ty11718";
struct A {}
- static assert(fn11718(A.init) == result1);
- static assert(fn11718!A() == result2);
+ static if (BackRefs)
+ {
+ static assert(fn11718(A.init) == "S6mangle__T7Ty11718S_DQv__T7fn11718TSQBk9test11718FZ1AZQBcFQxZ1aQBcZQCf");
+ static assert(fn11718!A() == "S6mangle__T7Ty11718S_DQv__T7fn11718TSQBk9test11718FZ1AZQBcFZ1aQBaZQCd");
+ }
+ else
+ {
+ pragma(msg, fn11718(A.init));
+ static assert(fn11718(A.init) == result1);
+ static assert(fn11718!A() == result2);
+ }
}
/*******************************************/
{
auto s = S11776!(a => 1)();
static assert(typeof(s).mangleof ==
- "S"~"6mangle"~"56"~(
- "__T"~"6S11776"~"S42"~("6mangle"~"9test11776"~"FZ"~"9__lambda1MFZ"~"9__lambda1")~"Z"
- )~"6S11776");
+ "S"~"6mangle"~tl!("56")~
+ ("__T"~"6S11776"~"S"~tl!("42")~
+ (id!("6mangle","Qs")~"9test11776"~"FZ"~"9__lambda1MFZ"~id!("9__lambda1","Qn"))~"Z"
+ )~id!("6S11776", "QBm"));
}
};
}
static assert( S.mangleof == "S6mangle9test12217FiZ1S");
static assert( bar.mangleof == "_D6mangle9test12217FiZ3barMFNaNbNiNfZv");
static assert( var.mangleof == "_D6mangle9test12217FiZ3vari");
- static assert(X!int.mangleof == "6mangle9test12217FiZ8__T1XTiZ");
+ static assert(X!int.mangleof == "6mangle9test12217FiZ"~tl!("8")~"__T1XTiZ");
}
void test12217() {}
if (is(typeof({
class C {}
static assert(C.mangleof ==
- "C6mangle16__U10func12231aZ10func12231aFZ9__lambda1MFZ1C");
+ "C6mangle"~tl!("16")~"__U10func12231aZ"~id!("10func12231a","Qn")~"FZ9__lambda1MFZ1C");
// ### L #
})))
{}
void func12231b()()
if (is(typeof({
- class C {}
- static assert(C.mangleof ==
- "C6mangle16__U10func12231bZ10func12231bFZ9__lambda1MFZ1C");
+ class C {} static assert(C.mangleof ==
+ "C6mangle"~tl!("16")~"__U10func12231bZ"~id!("10func12231b","Qn")~"FZ9__lambda1MFZ1C");
// L__L L LL
- })) &&
+ })) &&
is(typeof({
class C {}
static assert(C.mangleof ==
- "C6mangle16__U10func12231bZ10func12231bFZ9__lambda2MFZ1C");
+ "C6mangle"~tl!("16")~"__U10func12231bZ"~id!("10func12231b","Qn")~"FZ9__lambda2MFZ1C");
// L__L L LL
})))
{}
if (is(typeof({
class C {}
static assert(C.mangleof ==
- "C6mangle16__U10func12231cZ10func12231cFZ9__lambda1MFZ1C");
+ "C6mangle"~tl!("16")~"__U10func12231cZ"~id!("10func12231c","Qn")~"FZ9__lambda1MFZ1C");
// L__L L LL
})))
{
(){
class C {}
static assert(C.mangleof ==
- "C6mangle16__T10func12231cZ10func12231cFZ9__lambda1MFZ1C");
+ "C6mangle"~tl!("16")~"__T10func12231cZ"~id!("10func12231c","Qn")~"FZ9__lambda1MFZ1C");
// L__L L LL
}();
}
void func12231c(X)()
if (is(typeof({
class C {}
- static assert(C.mangleof ==
- "C6mangle20__U10func12231cTAyaZ10func12231cFZ9__lambda1MFZ1C");
+ static assert(C.mangleof ==
+ "C6mangle"~tl!("20")~"__U10func12231cTAyaZ"~id!("10func12231c","Qr")~"FZ9__lambda1MFZ1C");
// L__L L___L LL
})))
{
(){
class C {}
static assert(C.mangleof ==
- "C6mangle20__T10func12231cTAyaZ10func12231cFZ9__lambda1MFZ1C");
+ "C6mangle"~tl!("20")~"__T10func12231cTAyaZ"~id!("10func12231c","Qr")~"FZ9__lambda1MFZ1C");
// L__L L___L LL
}();
}
struct Foo7469e(int a, T...) { }
struct Foo7469f(T, int k=1) { }
struct Foo7469g(T, int k=1) { }
+struct Foo7469h(uint x) { }
+
+import core.demangle : demangleType;
void test7469()
{
- static assert(Foo7469a!(3 ) .mangleof[$-28 .. $] == "17__T8Foo7469aVii3Z8Foo7469a");
- static assert(Foo7469a!(3u) .mangleof[$-28 .. $] == "17__T8Foo7469aVii3Z8Foo7469a");
- static assert(Foo7469b!(3u) .mangleof[$-28 .. $] == "17__T8Foo7469bVii3Z8Foo7469b");
- static assert(Foo7469b!(3 ) .mangleof[$-28 .. $] == "17__T8Foo7469bVii3Z8Foo7469b");
- static assert(Foo7469c!(3 ) .mangleof[$-28 .. $] == "17__T8Foo7469cVii3Z8Foo7469c");
- static assert(Foo7469c!(3u) .mangleof[$-28 .. $] == "17__T8Foo7469cVki3Z8Foo7469c");
- static assert(Foo7469d!(3 ) .mangleof[$-28 .. $] == "17__T8Foo7469dVii3Z8Foo7469d");
- static assert(Foo7469d!(3u) .mangleof[$-28 .. $] == "17__T8Foo7469dVki3Z8Foo7469d");
- static assert(Foo7469e!(3u, 5u).mangleof[$-32 .. $] == "21__T8Foo7469eVii3Vki5Z8Foo7469e");
- static assert(Foo7469f!(int, 1).mangleof[$-30 .. $] == "19__T8Foo7469fTiVii1Z8Foo7469f");
- static assert(Foo7469f!(int) .mangleof[$-30 .. $] == "19__T8Foo7469fTiVii1Z8Foo7469f");
- static assert(Foo7469g!(int) .mangleof[$-30 .. $] == "19__T8Foo7469gTiVii1Z8Foo7469g");
- static assert(Foo7469g!(int, 1).mangleof[$-30 .. $] == "19__T8Foo7469gTiVii1Z8Foo7469g");
+ static assert(demangleType(Foo7469a!(3 ) .mangleof) == "template4.Foo7469a!(3).Foo7469a");
+ static assert(demangleType(Foo7469a!(3u) .mangleof) == "template4.Foo7469a!(3).Foo7469a");
+ static assert(demangleType(Foo7469b!(3u) .mangleof) == "template4.Foo7469b!(3).Foo7469b");
+ static assert(demangleType(Foo7469b!(3 ) .mangleof) == "template4.Foo7469b!(3).Foo7469b");
+ static assert(demangleType(Foo7469c!(3 ) .mangleof) == "template4.Foo7469c!(3).Foo7469c");
+ static assert(demangleType(Foo7469c!(3u) .mangleof) == "template4.Foo7469c!(3u).Foo7469c");
+ static assert(demangleType(Foo7469d!(3 ) .mangleof) == "template4.Foo7469d!(3).Foo7469d");
+ static assert(demangleType(Foo7469d!(3u) .mangleof) == "template4.Foo7469d!(3u).Foo7469d");
+ static assert(demangleType(Foo7469e!(3u, 5u).mangleof) == "template4.Foo7469e!(3, 5u).Foo7469e");
+ static assert(demangleType(Foo7469f!(int, 1).mangleof) == "template4.Foo7469f!(int, 1).Foo7469f");
+ static assert(demangleType(Foo7469f!(int) .mangleof) == "template4.Foo7469f!(int, 1).Foo7469f");
+ static assert(demangleType(Foo7469g!(int) .mangleof) == "template4.Foo7469g!(int, 1).Foo7469g");
+ static assert(demangleType(Foo7469g!(int, 1).mangleof) == "template4.Foo7469g!(int, 1).Foo7469g");
+ static assert(demangleType(Foo7469h!(3 ) .mangleof) == "template4.Foo7469h!(3u).Foo7469h");
+ static assert(demangleType(Foo7469h!(3u) .mangleof) == "template4.Foo7469h!(3u).Foo7469h");
}
/******************************************/
/******************************************/
// 14174
+import imports.testmangle;
struct Config14174(a, b) {}
void accepter14174a(Config : Config14174!(T) = defConfig14174, T...)()
{
- static assert(accepter14174a.mangleof
- == "_D7breaker131__T14"~
+ static assert(equalDemangle(accepter14174a.mangleof,
+ "_D7breaker131__T14"~
"accepter14174a"~
"HTS7breaker51__T11Config14174TS7breaker6N14174TS7breaker6N14174Z11Config14174TS7breaker6N14174TS7breaker6N14174Z14"~
"accepter14174a"~
- "FZv");
+ "FZv"));
}
void accepter14174b(Config : Config14174!(T) = defConfig14174, T...)()
{
- static assert(accepter14174b.mangleof
- == "_D7breaker131__T14"~
+ static assert(equalDemangle(accepter14174b.mangleof,
+ "_D7breaker131__T14"~
"accepter14174b"~
"HTS7breaker51__T11Config14174TS7breaker6N14174TS7breaker6N14174Z11Config14174TS7breaker6N14174TS7breaker6N14174Z14"~
"accepter14174b"~
- "FZv");
+ "FZv"));
}
void test14174()
void test8()
{
+ import core.demangle : demangle;
auto p = &foo8;
showf(p.mangleof);
assert(typeof(p).mangleof == "PFxAaxC9testconst2C8xiZv");
- assert(p.mangleof == "_D9testconst5test8FZ1pPFxAaxC9testconst2C8xiZv");
+ assert(demangle(p.mangleof) == "void function(const(char[]), const(testconst.C8), const(int))* testconst.test8().p");
}
/************************************/