diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/d/dmd/MERGE | 2 | ||||
-rw-r--r-- | gcc/d/dmd/dmangle.c | 319 | ||||
-rw-r--r-- | gcc/d/dmd/dtemplate.c | 116 | ||||
-rw-r--r-- | gcc/testsuite/gdc.test/compilable/testInference.d | 6 | ||||
-rw-r--r-- | gcc/testsuite/gdc.test/fail_compilation/fail12485.d | 9 | ||||
-rw-r--r-- | gcc/testsuite/gdc.test/runnable/imports/testmangle.d | 66 | ||||
-rw-r--r-- | gcc/testsuite/gdc.test/runnable/link6574.d | 10 | ||||
-rw-r--r-- | gcc/testsuite/gdc.test/runnable/mangle.d | 82 | ||||
-rw-r--r-- | gcc/testsuite/gdc.test/runnable/template4.d | 31 | ||||
-rw-r--r-- | gcc/testsuite/gdc.test/runnable/template9.d | 13 | ||||
-rw-r--r-- | gcc/testsuite/gdc.test/runnable/testconst.d | 3 |
11 files changed, 429 insertions, 228 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 4fa62a9..1f695b9 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -45fa6cfd20827bb4252a616dc789514a1e673687 +2bd4fc3fed8b8cd9760e77c6b2a1905cd84d0e70 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/dmangle.c b/gcc/d/dmd/dmangle.c index 8f86926..f6eee52 100644 --- a/gcc/d/dmd/dmangle.c +++ b/gcc/d/dmd/dmangle.c @@ -10,6 +10,7 @@ #include "root/dsystem.h" #include "root/root.h" +#include "root/aav.h" #include "mangle.h" #include "init.h" @@ -133,13 +134,114 @@ void MODtoDecoBuffer(OutBuffer *buf, MOD mod) 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); + } //////////////////////////////////////////////////////////////////////////// @@ -153,7 +255,7 @@ public: { MODtoDecoBuffer(buf, t->mod); } - t->accept(this); + mangleType(t); } void visit(Type *t) @@ -207,8 +309,9 @@ public: 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; } @@ -280,35 +383,29 @@ public: 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) @@ -323,16 +420,14 @@ public: 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); @@ -349,12 +444,14 @@ public: 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); } @@ -375,13 +472,13 @@ public: 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. } } @@ -392,8 +489,8 @@ public: 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); @@ -401,39 +498,40 @@ public: } } - 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); } @@ -481,7 +579,7 @@ public: } if (fa) { - fa->accept(this); + mangleSymbol(fa); return; } visit((Dsymbol *)fd); @@ -507,7 +605,7 @@ public: { if (!od->hasOverloads || td->overnext == NULL) { - td->accept(this); + mangleSymbol(td); return; } } @@ -586,20 +684,131 @@ public: 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); } @@ -859,3 +1068,9 @@ void mangleToBuffer(Dsymbol *s, OutBuffer *buf) Mangler v(buf); s->accept(&v); } + +void mangleToBuffer(TemplateInstance *ti, OutBuffer *buf) +{ + Mangler v(buf); + v.mangleTemplateInstance(ti); +} diff --git a/gcc/d/dmd/dtemplate.c b/gcc/d/dmd/dtemplate.c index caa8a5b..fe65bd2 100644 --- a/gcc/d/dmd/dtemplate.c +++ b/gcc/d/dmd/dtemplate.c @@ -7546,122 +7546,12 @@ Dsymbols *TemplateInstance::appendToModuleMember() 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()); } /************************************* diff --git a/gcc/testsuite/gdc.test/compilable/testInference.d b/gcc/testsuite/gdc.test/compilable/testInference.d index 95f4fcb..5a8e1e2 100644 --- a/gcc/testsuite/gdc.test/compilable/testInference.d +++ b/gcc/testsuite/gdc.test/compilable/testInference.d @@ -261,11 +261,13 @@ void test8234() /***************************************************/ // 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; } @@ -277,7 +279,7 @@ void test8504() { 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); diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail12485.d b/gcc/testsuite/gdc.test/fail_compilation/fail12485.d index 71f8698..e1b1577 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail12485.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail12485.d @@ -1,11 +1,12 @@ 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); } diff --git a/gcc/testsuite/gdc.test/runnable/imports/testmangle.d b/gcc/testsuite/gdc.test/runnable/imports/testmangle.d new file mode 100644 index 0000000..5311a83 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/imports/testmangle.d @@ -0,0 +1,66 @@ +// 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; +} diff --git a/gcc/testsuite/gdc.test/runnable/link6574.d b/gcc/testsuite/gdc.test/runnable/link6574.d index 0f97ed7..ab5e552 100644 --- a/gcc/testsuite/gdc.test/runnable/link6574.d +++ b/gcc/testsuite/gdc.test/runnable/link6574.d @@ -1,16 +1,18 @@ // 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)() @@ -21,7 +23,7 @@ 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)() @@ -31,7 +33,7 @@ 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; } diff --git a/gcc/testsuite/gdc.test/runnable/mangle.d b/gcc/testsuite/gdc.test/runnable/mangle.d index 8820a6d..883d58a 100644 --- a/gcc/testsuite/gdc.test/runnable/mangle.d +++ b/gcc/testsuite/gdc.test/runnable/mangle.d @@ -1,6 +1,8 @@ // PERMUTE_ARGS: // EXTRA_SOURCES: imports/mangle10077.d +import imports.testmangle; + /***************************************************/ // 10077 - pragma(mangle) @@ -79,7 +81,7 @@ class C2774 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() { @@ -175,8 +177,8 @@ void test8847b() 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()() { @@ -236,9 +238,10 @@ void test8847d() 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 @@ -248,10 +251,16 @@ void test8847e() 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); } // -------- @@ -287,7 +296,7 @@ auto bar12352() 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"); @@ -301,7 +310,7 @@ auto baz12352() 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"); @@ -312,8 +321,8 @@ void f9525(T)(in T*) { } 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)() { @@ -383,23 +392,32 @@ void test11718() 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); + } } /*******************************************/ @@ -417,9 +435,10 @@ void test11776() { 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")); } }; } @@ -464,7 +483,7 @@ void test12217(int) 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() {} @@ -476,22 +495,21 @@ void func12231a()() 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 }))) {} @@ -500,14 +518,14 @@ void func12231c()() 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 }(); } @@ -515,15 +533,15 @@ if (is(typeof({ 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 }(); } diff --git a/gcc/testsuite/gdc.test/runnable/template4.d b/gcc/testsuite/gdc.test/runnable/template4.d index 77d6254..81723f6 100644 --- a/gcc/testsuite/gdc.test/runnable/template4.d +++ b/gcc/testsuite/gdc.test/runnable/template4.d @@ -1074,22 +1074,27 @@ struct Foo7469d(T...) { } 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"); } /******************************************/ diff --git a/gcc/testsuite/gdc.test/runnable/template9.d b/gcc/testsuite/gdc.test/runnable/template9.d index 4f18295..b016ff9 100644 --- a/gcc/testsuite/gdc.test/runnable/template9.d +++ b/gcc/testsuite/gdc.test/runnable/template9.d @@ -4465,6 +4465,7 @@ void test13807() /******************************************/ // 14174 +import imports.testmangle; struct Config14174(a, b) {} @@ -4474,22 +4475,22 @@ alias defConfig14174 = Config14174!(N14174, N14174); 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() diff --git a/gcc/testsuite/gdc.test/runnable/testconst.d b/gcc/testsuite/gdc.test/runnable/testconst.d index 2da39a2..42f9c1b 100644 --- a/gcc/testsuite/gdc.test/runnable/testconst.d +++ b/gcc/testsuite/gdc.test/runnable/testconst.d @@ -84,10 +84,11 @@ void foo8(const char[] s, const C8 c, const int x) 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"); } /************************************/ |