Skip to content

Instantly share code, notes, and snippets.

@MartinNowak
Created November 25, 2011 18:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MartinNowak/1394145 to your computer and use it in GitHub Desktop.
Save MartinNowak/1394145 to your computer and use it in GitHub Desktop.
import std.conv;
struct CppMangler
{
CppMangler namespace(string name)
{
return nested(name);
}
CppMangler klass(string name)
{
return nested(name);
}
CppMangler meth(string name)
{
assert(_nested);
_mangle ~= to!string(name.length) ~ name ~ "E";
_nested = false;
return this;
}
CppMangler func(string name)
{
assert(!_nested);
_mangle ~= to!string(name.length) ~ name;
return this;
}
CppMangler args(Args...)()
{
/* ABI spec says:
* v void
* w wchar_t
* b bool
* c char
* a signed char
* h unsigned char
* s short
* t unsigned short
* i int
* j unsigned int
* l long
* m unsigned long
* x long long, __int64
* y unsigned long long, __int64
* n __int128
* o unsigned __int128
* f float
* d double
* e long double, __float80
* g __float128
* z ellipsis
* u <source-name> # vendor extended type
*/
if (!Args.length)
_mangle ~= "v";
foreach(Arg; Args)
{
static if (is(Arg == bool))
_mangle ~= "b";
else static if (is(Arg == char))
_mangle ~= "c";
else static if (is(Arg == byte))
_mangle ~= "a";
else static if (is(Arg == ubyte))
_mangle ~= "h";
else static if (is(Arg == short))
_mangle ~= "s";
else static if (is(Arg == ushort))
_mangle ~= "t";
else static if (is(Arg == int))
_mangle ~= "i";
else static if (is(Arg == uint))
_mangle ~= "j";
else static if (is(Arg == sizediff_t))
_mangle ~= "l";
else static if (is(Arg == size_t))
_mangle ~= "m";
else static if (is(Arg == long))
_mangle ~= "x";
else static if (is(Arg == ulong))
_mangle ~= "y";
else static if (is(Arg == float))
_mangle ~= "f";
else static if (is(Arg == double))
_mangle ~= "d";
else static if (is(Arg == real))
_mangle ~= "e";
else
static assert(0, "Don't know how to mangle a " ~ Arg.stringof);
}
return this;
}
@property string get() const
{
return _mangle;
}
@property ref string mangle()
{
return _mangle;
}
private:
CppMangler nested(string name)
{
if (!_nested)
_mangle ~= "N";
_nested = true;
_mangle ~= to!string(name.length) ~ name;
return this;
}
version (OSX)
string _mangle="__Z";
else
string _mangle="_Z";
bool _nested;
}
template decl_cpp(string mangle, RT, Args...)
{
mixin("alias " ~ mangle ~ " func;");
}
unittest
{
enum s1 = CppMangler().func("foo").args!()().get();
enum s2 = CppMangler().klass("S").meth("bar").args!()().get();
enum s3 = CppMangler().klass("S").meth("bari").args!(int)().get();
enum s4 = CppMangler().klass("S").meth("ibar").args!()().get();
enum s5 = CppMangler().namespace("baz").klass("S").meth("bar").args!()().get();
enum s6 = CppMangler().namespace("baz").klass("S").meth("bari").args!(int)().get();
enum s7 = CppMangler().namespace("baz").klass("S").meth("ibar").args!()().get();
pragma(msg, s1);
pragma(msg, s2);
pragma(msg, s3);
pragma(msg, s4);
pragma(msg, s5);
pragma(msg, s6);
pragma(msg, s7);
// calls namespace baz { struct S { void bari(int i); }; };
mixin("extern(C) void " ~ s6 ~ "(int);");
mixin("alias "~s6~" baz_S_bari;");
baz_S_bari(12);
}
void main()
{
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment