It's not foolproof, but I found it useful enough; maybe others will too. // Parsing mangles for fun and profit. char[] _getJustName(char[] mangle) { size_t idx = 1; size_t start = idx; size_t len = 0;
while(idx < mangle.length && mangle[idx] >= '0' && mangle[idx] <= '9') { int size = mangle[idx++] - '0'; while(mangle[idx] >= '0' && mangle[idx] <= '9') size = (size * 10) + (mangle[idx++] - '0'); start = idx; len = size; idx += size; } if(start < mangle.length) return mangle[start .. start + len]; else return ""; } // Eheheh, I has a __FUNCTION__. const char[] FuncNameMix = "static if(!is(typeof(__FUNCTION__)))" "{ struct __FUNCTION {} const char[] __FUNCTION__ =" "_getJustName(__FUNCTION.mangleof); }"; To use, just mix into any function where you want to use __FUNCTION__, and it'll be declared as a const char[]. void forble() { mixin(FuncNameMix); pragma(msg, __FUNCTION__); // shows "forble" } It doesn't seem to cause any noticeable bloat. The only reference I found to __FUNCTION in an executable compiled with -release was the contents of the FuncNameMix constant itself; I'm sure an "enum string" in D2 wouldn't be emitted like this. It doesn't work for nested functions, but that's just a little more parsing work. If you want a version that displays the FQN instead of just the function name, I have that too. For those wondering how this works, it's pretty simple: when you declare a type within a function, its mangleof contains the function's name. All the mixin is doing is declaring a type within the function (struct __FUNCTION), then parsing the owning function's name out of the type's mangleof.