Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
342 changes: 284 additions & 58 deletions src/ddmd/dmangle.d

Large diffs are not rendered by default.

117 changes: 2 additions & 115 deletions src/ddmd/dtemplate.d
Original file line number Diff line number Diff line change
Expand Up @@ -8223,123 +8223,10 @@ extern (C++) class TemplateInstance : ScopeDsymbol
*/
final Identifier genIdent(Objects* args)
{
TemplateDeclaration tempdecl = this.tempdecl.isTemplateDeclaration();
assert(tempdecl);

//printf("TemplateInstance.genIdent('%s')\n", tempdecl.ident.toChars());
assert(args is tiargs);
OutBuffer buf;

const id = tempdecl.ident.toString();
// Use "__U" for the symbols declared inside template constraint.
const char T = members ? 'T' : 'U';
buf.printf("__%c%u%.*s", T, cast(int)id.length, cast(int)id.length, id.ptr);

size_t nparams = tempdecl.parameters.dim - (tempdecl.isVariadic() ? 1 : 0);
for (size_t i = 0; i < args.dim; 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');
if (ta.deco)
buf.writestring(ta.deco);
else
{
debug
{
if (!global.errors)
printf("ta = %d, %s\n", ta.ty, ta.toChars());
}
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.
enum keepLvalue = true;
ea = ea.optimize(WANTvalue, keepLvalue);
if (ea.op == TOKvar)
{
sa = (cast(VarExp)ea).var;
ea = null;
goto Lsa;
}
if (ea.op == TOKthis)
{
sa = (cast(ThisExp)ea).var;
ea = null;
goto Lsa;
}
if (ea.op == TOKfunction)
{
if ((cast(FuncExp)ea).td)
sa = (cast(FuncExp)ea).td;
else
sa = (cast(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
uint 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);
auto s = bufsa.peekSlice();

/* https://issues.dlang.org/show_bug.cgi?id=3043
* If the first character of p 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", cast(uint)s.length, cast(int)s.length, s.ptr);
}
else if (va)
{
assert(i + 1 == args.dim); // must be last one
args = &va.objects;
i = -cast(size_t)1;
}
else
assert(0);
}
buf.writeByte('Z');
mangleToBuffer(this, &buf);
//printf("\tgenIdent = %s\n", buf.peekString());
return Identifier.idPool(buf.peekSlice());
}
Expand Down
36 changes: 18 additions & 18 deletions src/ddmd/toir.d
Original file line number Diff line number Diff line change
Expand Up @@ -415,15 +415,15 @@ int intrinsic_op(FuncDeclaration fd)
"4math6yl2xp1FNaNbNiNfeeZe",

"4simd10__prefetchFNaNbNiNfxPvhZv",
"4simd10__simd_stoFNaNbNiNfE4core4simd3XMMNhG16vNhG16vZNhG16v",
"4simd10__simd_stoFNaNbNiNfE4core4simd3XMMdNhG16vZNhG16v",
"4simd10__simd_stoFNaNbNiNfE4core4simd3XMMfNhG16vZNhG16v",
"4simd6__simdFNaNbNiNfE4core4simd3XMMNhG16vNhG16vZNhG16v",
"4simd6__simdFNaNbNiNfE4core4simd3XMMNhG16vNhG16vhZNhG16v",
"4simd6__simdFNaNbNiNfE4core4simd3XMMNhG16vZNhG16v",
"4simd6__simdFNaNbNiNfE4core4simd3XMMdZNhG16v",
"4simd6__simdFNaNbNiNfE4core4simd3XMMfZNhG16v",
"4simd9__simd_ibFNaNbNiNfE4core4simd3XMMNhG16vhZNhG16v",
"4simd10__simd_stoFNaNbNiNfEQBgQBe3XMMNhG16vQgZQj",
"4simd10__simd_stoFNaNbNiNfEQBgQBe3XMMdNhG16vZQh",
"4simd10__simd_stoFNaNbNiNfEQBgQBe3XMMfNhG16vZQh",
"4simd6__simdFNaNbNiNfEQBbQz3XMMNhG16vQgZQj",
"4simd6__simdFNaNbNiNfEQBbQz3XMMNhG16vQghZQk",
"4simd6__simdFNaNbNiNfEQBbQz3XMMNhG16vZQh",
"4simd6__simdFNaNbNiNfEQBbQz3XMMdZNhG16v",
"4simd6__simdFNaNbNiNfEQBbQz3XMMfZNhG16v",
"4simd9__simd_ibFNaNbNiNfEQBeQBc3XMMNhG16vhZQi",

"5bitop12volatileLoadFNbNiNfPhZh",
"5bitop12volatileLoadFNbNiNfPkZk",
Expand Down Expand Up @@ -469,15 +469,15 @@ int intrinsic_op(FuncDeclaration fd)
"4math6yl2xp1FNaNbNiNfeeZe",

"4simd10__prefetchFNaNbNiNfxPvhZv",
"4simd10__simd_stoFNaNbNiNfE4core4simd3XMMNhG16vNhG16vZNhG16v",
"4simd10__simd_stoFNaNbNiNfE4core4simd3XMMdNhG16vZNhG16v",
"4simd10__simd_stoFNaNbNiNfE4core4simd3XMMfNhG16vZNhG16v",
"4simd6__simdFNaNbNiNfE4core4simd3XMMNhG16vNhG16vZNhG16v",
"4simd6__simdFNaNbNiNfE4core4simd3XMMNhG16vNhG16vhZNhG16v",
"4simd6__simdFNaNbNiNfE4core4simd3XMMNhG16vZNhG16v",
"4simd6__simdFNaNbNiNfE4core4simd3XMMdZNhG16v",
"4simd6__simdFNaNbNiNfE4core4simd3XMMfZNhG16v",
"4simd9__simd_ibFNaNbNiNfE4core4simd3XMMNhG16vhZNhG16v",
"4simd10__simd_stoFNaNbNiNfEQBgQBe3XMMNhG16vQgZQj",
"4simd10__simd_stoFNaNbNiNfEQBgQBe3XMMdNhG16vZQh",
"4simd10__simd_stoFNaNbNiNfEQBgQBe3XMMfNhG16vZQh",
"4simd6__simdFNaNbNiNfEQBbQz3XMMNhG16vQgZQj",
"4simd6__simdFNaNbNiNfEQBbQz3XMMNhG16vQghZQk",
"4simd6__simdFNaNbNiNfEQBbQz3XMMNhG16vZQh",
"4simd6__simdFNaNbNiNfEQBbQz3XMMdZNhG16v",
"4simd6__simdFNaNbNiNfEQBbQz3XMMfZNhG16v",
"4simd9__simd_ibFNaNbNiNfEQBeQBc3XMMNhG16vhZQi",

"5bitop12volatileLoadFNbNiNfPhZh",
"5bitop12volatileLoadFNbNiNfPkZk",
Expand Down
7 changes: 5 additions & 2 deletions test/compilable/extra-files/json-postscript.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#!/usr/bin/env bash

grep -v "\"file\" : " ${RESULTS_DIR}/compilable/json.out | grep -v "\"offset\" : " > ${RESULTS_DIR}/compilable/json.out.2
diff --strip-trailing-cr compilable/extra-files/json.out ${RESULTS_DIR}/compilable/json.out.2
grep -v "\"deco\" : " ${RESULTS_DIR}/compilable/json.out.2 > ${RESULTS_DIR}/compilable/json.out.3
grep -v "\"deco\" : " compilable/extra-files/json.out > ${RESULTS_DIR}/compilable/json.out.4

diff --strip-trailing-cr ${RESULTS_DIR}/compilable/json.out.4 ${RESULTS_DIR}/compilable/json.out.3
if [ $? -ne 0 ]; then
exit 1;
fi

rm ${RESULTS_DIR}/compilable/json.out{,.2}
rm ${RESULTS_DIR}/compilable/json.out{,.2,.3,.4}

6 changes: 5 additions & 1 deletion test/compilable/test10993.d
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module test10993;

import core.demangle : demangleType;

auto foo(T)(T a)
{
static immutable typeof(a) q;
Expand Down Expand Up @@ -29,5 +31,7 @@ void main()
auto y = cast()x;
enum mangle_y = typeof(y).mangleof;
// pragma(msg, "y : " ~ mangle_y);
static assert (mangle_y == mangle_x[1..$]);
enum demangle_x = demangleType(mangle_x);
enum demangle_y = demangleType(mangle_y);
static assert ("immutable(" ~ demangle_y ~ ")" == demangle_x);
}
6 changes: 4 additions & 2 deletions test/compilable/testInference.d
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion test/runnable/extra-files/test10386.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ module test10386;
// import lib.foo.bar; // ok
import lib10386.foo; // linker failure

import imports.testmangle;

void main()
{
static assert(foo.mangleof == "_D8lib103863foo3bar3fooFiZv");
static assert(equalDemangle(foo.mangleof, "_D8lib103863foo3bar3fooFiZv"));
foo(1);
}

66 changes: 66 additions & 0 deletions test/runnable/imports/testmangle.d
Original file line number Diff line number Diff line change
@@ -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;
}
10 changes: 6 additions & 4 deletions test/runnable/link6574.d
Original file line number Diff line number Diff line change
@@ -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)()
Expand All @@ -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)()
Expand All @@ -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;
}

Expand Down
Loading