Metaprogramming without templates
Stefan Koch
uplink.coder at googlemail.com
Tue Jun 29 14:26:10 UTC 2021
On Friday, 25 June 2021 at 15:07:54 UTC, Stefan Koch wrote:
> On Thursday, 24 June 2021 at 11:53:00 UTC, Stefan Koch wrote:
>> On Sunday, 20 June 2021 at 22:51:06 UTC, Stefan Koch wrote:
>>> [snip]
Hi there, I have just been able to do the first thing I wanted to
use core reflect for.
dynamically loading function pointers for debugging functions.
In case the function cannot be loaded because it's not running in
the debug environment I want the function pointers to be
initialized to dummy functions which do nothing.
Let's have a look at the code:
```D
import core.reflect.reflect;
static immutable decls = declarationsFromTokenString(
q{
// extern (C) @nogc pure nothrow __gshared {
void __itt_sync_create (void *addr, const char *objtype,
const char *objname, int attribute);
void __itt_sync_cancel (void* addr);
void __itt_sync_acquired (void* addr);
void __itt_sync_releasing (void* addr);
void __itt_sync_prepare (void* addr);
// }
});
import core.reflect.nodeToSource;
pragma(msg, () {
string result;
foreach(d;decls)
{
if (auto fd = cast(FunctionDeclaration) d)
{
result ~= fd
.makeFunctionVariableWithDummyInit()
.nodeToSource()
;
}
}
return result;
} ());
VariableDeclaration makeFunctionVariableWithDummyInit(const
FunctionDeclaration fd) {
auto type = new TypePointer();
type.nextOf = cast()fd.type;
auto name = fd.name;
auto result = new VariableDeclaration();
result.type = type;
result.name = name;
auto func = new FunctionLiteral();
func.parameters = cast()fd.parameters;
func.fbody = makeDummyBody(fd.type.returnType);
result._init = func;
return result;
}
BlockStatement makeDummyBody(const Type returnType)
{
BlockStatement stmt = new BlockStatement();
if (cast(TypeBasic) returnType && returnType.identifier ==
"void")
{
stmt.statements ~= new ReturnStatement();
}
else
assert(0, "non void return not supported as of now");
return stmt;
}
```
and the output of this will be
```D
void function (void* addr, char* objtype, char* objname, int
attribute) __itt_sync_create = () {
return ;
};
void function (void* addr) __itt_sync_cancel = () {
return ;
};
void function (void* addr) __itt_sync_acquired = () {
return ;
};
void function (void* addr) __itt_sync_releasing = () {
return ;
};
void function (void* addr) __itt_sync_prepare = () {
return ;
};
```
which does exactly what I want it declares function pointers with
the same name as the functions extracted from the intel header.
and initializes them to dummy functions be default.
yay.
Creating a string is not how it's supposed to be spliced in
though!
rather I will special case `mixin` to splice in `core.reflect`
directly nodes when it is used on them.
Or maybe something more clever :)
More information about the Digitalmars-d
mailing list