Skip to content
Closed
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
7 changes: 6 additions & 1 deletion src/dmd/cppmangle.d
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,12 @@ public:
else
{
// For value types, strip const/immutable/shared from the head of the type
t.mutableOf().unSharedOf().accept(this);
auto unqualified = t.mutableOf().unSharedOf();

if (unqualified.mangleOverride)
buf.writestring(unqualified.mangleOverride);
else
unqualified.accept(this);
}
}

Expand Down
8 changes: 6 additions & 2 deletions src/dmd/dmangle.d
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,9 @@ public:

final void mangleType(Type t)
{
if (!backrefType(t))
if (t.mangleOverride)
buf.writestring(t.mangleOverride);
else if (!backrefType(t))
t.accept(this);
}

Expand Down Expand Up @@ -1106,7 +1108,9 @@ extern (C++) const(char)* mangleExact(FuncDeclaration fd)

extern (C++) void mangleToBuffer(Type t, OutBuffer* buf)
{
if (t.deco)
if (t.mangleOverride)
buf.writestring(t.mangleOverride);
else if (t.deco)
buf.writestring(t.deco);
else
{
Expand Down
16 changes: 10 additions & 6 deletions src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ import dmd.visitor;

enum LOG = false;

private uint setMangleOverride(Dsymbol s, char* sym)
private uint setMangleOverride(Dsymbol s, char* sym, Scope* sc)
{
AttribDeclaration ad = s.isAttribDeclaration();
if (ad)
Expand All @@ -82,12 +82,16 @@ private uint setMangleOverride(Dsymbol s, char* sym)
uint nestedCount = 0;
if (decls && decls.dim)
for (size_t i = 0; i < decls.dim; ++i)
nestedCount += setMangleOverride((*decls)[i], sym);
nestedCount += setMangleOverride((*decls)[i], sym, sc);
return nestedCount;
}
else if (s.isFuncDeclaration() || s.isVarDeclaration())
else if (s.isFuncDeclaration() || s.isVarDeclaration() || s.isAliasDeclaration)
{
s.isDeclaration().mangleOverride = sym;

if (s.isAliasDeclaration)
semantic2(s, sc);

return 1;
}
else
Expand Down Expand Up @@ -1307,7 +1311,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
override void visit(PragmaDeclaration pd)
{
// Should be merged with PragmaStatement
//printf("\tPragmaDeclaration::semantic '%s'\n", pd.toChars());
//printf("PragmaDeclaration::semantic '%s'\n", pd.toChars());
if (pd.ident == Id.msg)
{
if (pd.args)
Expand Down Expand Up @@ -1518,7 +1522,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
char* name = cast(char*)mem.xmalloc(se.len + 1);
memcpy(name, se.string, se.len);
name[se.len] = 0;
uint cnt = setMangleOverride(s, name);
uint cnt = setMangleOverride(s, name, sc2);
if (cnt > 1)
pd.error("can only apply to a single declaration");
}
Expand Down Expand Up @@ -5414,7 +5418,7 @@ Laftersemantic:
// function used to perform semantic on AliasDeclaration
void aliasSemantic(AliasDeclaration ds, Scope* sc)
{
//printf("AliasDeclaration::semantic() %s\n", toChars());
//printf("AliasDeclaration::semantic() %s\n", ds.toChars());
if (ds.aliassym)
{
auto fd = ds.aliassym.isFuncLiteralDeclaration();
Expand Down
29 changes: 22 additions & 7 deletions src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -9429,7 +9429,17 @@ extern (C++) Expression expressionSemantic(Expression e, Scope* sc)

Expression semanticX(DotIdExp exp, Scope* sc)
{
//printf("DotIdExp::semanticX(this = %p, '%s')\n", this, toChars());
static Expression mangleToBuffer(Node)(Node node, DotIdExp exp, Scope* sc)
if (is(Node == Type) || is(Node == Dsymbol))
{
OutBuffer buf;
.mangleToBuffer(node, &buf);
const s = buf.peekSlice();
auto e = new StringExp(exp.loc, buf.extractString(), s.length);
return e.expressionSemantic(sc);
}

//printf("DotIdExp::semanticX(this = %p, '%s')\n", exp, exp.toChars());
if (Expression ex = unaSemantic(exp, sc))
return ex;

Expand All @@ -9455,7 +9465,17 @@ Expression semanticX(DotIdExp exp, Scope* sc)
{
TemplateExp te = cast(TemplateExp)exp.e1;
ds = te.fd ? cast(Dsymbol)te.fd : te.td;
goto L1;
}
case TOKtype:
{
auto type = (cast(TypeExp)exp.e1).type;

if (type.mangleOverride)
return mangleToBuffer(type, exp, sc);
else
break;
}
L1:
{
assert(ds);
Expand All @@ -9466,12 +9486,7 @@ Expression semanticX(DotIdExp exp, Scope* sc)
return new ErrorExp();
}
}
OutBuffer buf;
mangleToBuffer(ds, &buf);
const s = buf.peekSlice();
Expression e = new StringExp(exp.loc, buf.extractString(), s.length);
e = e.expressionSemantic(sc);
return e;
return mangleToBuffer(ds, exp, sc);
}
default:
break;
Expand Down
10 changes: 10 additions & 0 deletions src/dmd/mtype.d
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,9 @@ extern (C++) abstract class Type : RootObject

type* ctype; // for back end

/// Overridden symbol with `pragma(mangle, "...")`.
const(char)* mangleOverride;

extern (C++) static __gshared Type tvoid;
extern (C++) static __gshared Type tint8;
extern (C++) static __gshared Type tuns8;
Expand Down Expand Up @@ -1052,8 +1055,15 @@ extern (C++) abstract class Type : RootObject
StringValue* sv = stringtable.lookup(t.deco, strlen(t.deco));
if (sv && sv.ptrvalue)
{
auto mangleOverride = t.mangleOverride;
t = cast(Type)sv.ptrvalue;
assert(t.deco);

if (mangleOverride)
{
t = t.copy();
t.mangleOverride = mangleOverride;
}
}
else
assert(0);
Expand Down
2 changes: 2 additions & 0 deletions src/dmd/mtype.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ class Type : public RootObject

type *ctype; // for back end

const char *mangleOverride; // overridden symbol with pragma(mangle, "...")

static Type *tvoid;
static Type *tint8;
static Type *tuns8;
Expand Down
13 changes: 13 additions & 0 deletions src/dmd/semantic2.d
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,19 @@ private extern(C++) final class Semantic2Visitor : Visitor
}
}

override void visit(AliasDeclaration ad)
{
//printf("AliasDeclaration.semantic2 %s\n", ad.toChars);

if (!ad.mangleOverride || ad.type.mangleOverride)
return;

// make a copy to make sure the mangling of the original type isn't
// overwritten
ad.type = ad.type.copy();
ad.type.mangleOverride = ad.mangleOverride;
}

override void visit(Import i)
{
//printf("Import::semantic2('%s')\n", toChars());
Expand Down
7 changes: 7 additions & 0 deletions src/dmd/typesem.d
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,7 @@ static Type merge(Type type)
StringValue* sv = type.stringtable.update(cast(char*)buf.data, buf.offset);
if (sv.ptrvalue)
{
auto mangleOverride = t.mangleOverride;
t = cast(Type)sv.ptrvalue;
debug
{
Expand All @@ -1409,6 +1410,12 @@ static Type merge(Type type)
}
assert(t.deco);
//printf("old value, deco = '%s' %p\n", t.deco, t.deco);

if (mangleOverride)
{
t = t.copy();
t.mangleOverride = mangleOverride;
}
}
else
{
Expand Down
37 changes: 37 additions & 0 deletions test/compilable/cppmangle.d
Original file line number Diff line number Diff line change
Expand Up @@ -444,3 +444,40 @@ version (linux)
{
static assert(test36.mangleof == "_Z6test36PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPiPS12_");
}

// test overriding mangling for alias declaration
version (Posix) extern (C++) struct TestOverridingManglingAlias
{
version (OSX)
enum prefix = "_";
else
enum prefix = "";

enum baseMangling = prefix ~ "_ZN27TestOverridingManglingAlias";

// basic type

// override mangling
pragma(mangle, "bar") alias a = int;
static assert(a.mangleof == "bar");

// alias without overriding
alias b = int;
static assert(b.mangleof == "i");

// default mangling of basic type
static assert(int.mangleof == "i");



// function

// type of parameter is an alias"
pragma(mangle, "foo") alias c = int;
void d(c);
static assert(d.mangleof == baseMangling ~ "1dEfoo");

// default mangling of function"
void e(int);
static assert(e.mangleof == baseMangling ~ "1eEi");
}
83 changes: 83 additions & 0 deletions test/runnable/mangle.d
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,89 @@ void fooB(void delegate (void delegate()) scope dg)
//pragma(msg, fooB.mangleof);
static assert(typeof(fooA).mangleof != typeof(fooB).mangleof);

/***************************************************/

// test overriding mangling for alias declaration
struct TestOverridingManglingAlias
{
enum baseMangling = "6mangle27TestOverridingManglingAlias";

// basic type

// override mangling
pragma(mangle, "bar") alias a = int;
static assert(a.mangleof == "bar");

// alias without overriding
alias b = int;
static assert(b.mangleof == "i");

// default mangling of basic type
static assert(int.mangleof == "i");

// verify that the alias and the aliased type is the same type
pragma(mangle, "bar") alias c = int;
static assert(is(int == c));

// override mangling at intermediate step
alias d = int;
pragma(mangle, "foo") alias e = d;
alias f = e;
f g;
static assert(g.mangleof == "_D" ~ baseMangling ~ "1g" ~ e.mangleof);



// struct

struct Struct
{
enum defaultMangling = "S" ~ baseMangling ~"6Struct";
}

// override mangling
pragma(mangle, "Bar") alias h = Struct;
static assert(h.mangleof == "Bar");

// alias without overriding
alias i = Struct;
static assert(i.mangleof == Struct.defaultMangling);

// default mangling of struct
static assert(Struct.mangleof == Struct.defaultMangling);



// class
struct Class
{
enum defaultMangling = "S" ~ baseMangling ~ "5Class";
}

// override mangling
pragma(mangle, "Bar") alias j = Struct;
static assert(j.mangleof == "Bar");

// alias without overriding
alias k = Class;
static assert(k.mangleof == Class.defaultMangling);

// default mangling of class
static assert(Class.mangleof == Class.defaultMangling);



// function

// type of parameter is an alias"
pragma(mangle, "foo") alias l = int;
void m(l);
static assert(m.mangleof == "_D" ~ baseMangling ~ "1mMFfooZv");

// default mangling of function"
void n(int);
static assert(n.mangleof == "_D" ~ baseMangling ~ "1nMFiZv");
}

/***************************************************/

Expand Down