Hello, thank you for the collaboration invite =D
I have been investigating + experimenting with converting C++ headers to Dlang extern (C++) bindings and also more recently to Nim.
Maybe I can share some thoughts/findings with you 馃檪
libclang vs LibTooling
Probably not so important for just one library, but I have been doing reading on which approach is best for translating headers to other languages + bindgen/codegen.
There are some screenshots of experiences from the authors of c2rust and dpp:
馃専 Click for relevant parts of conversation 馃憞



(I am not certain, but I think the newer libclang-cpp shared lib that contains all of the clang-based libraries also contains the LibTooling stuff and would be much smaller.)
# For MinGW we only enable shared library if LLVM_LINK_LLVM_DYLIB=ON.
# Without that option resulting library is too close to 2^16 DLL exports limit.
if(UNIX OR (MINGW AND LLVM_LINK_LLVM_DYLIB))
add_clang_subdirectory(clang-shlib)
endif()
It's possible to use cppyy for LibTooling access, if you build LLVM on Linux/MinGW with BUILD_SHARED_LIBS set to ON (I think it's also possible with LLVM_BUILD_DYLIB)
Doing this gives you:

API/codegen approach
I found two interesting approaches others have taken for the actual codegen that I have been experimenting with. Maybe you have some ideas?
The first
Create decorators in Python which hold rules, the argument is a clang::QualType or clang::Type. Nodes are evaluated against rules, the one matching is chosen for codegen.
Each class is a "frontend" driver/generator for a language to create from C++ headers. It's very clever! Currently he has:
Here is the repo where I found this. In his approach, he has used PyBind for binding the Clang/LibTooling C++ API to Python, which could also be used instead of cppyy I suppose (not sure why you'd do that)
class NimCodegen():
# t = clang::Type or clang::QualType
@rule(lambda t: t.is_pointer() or t.is_reference() and \
t.pointee().is_record_indirection())
def input(cls, t, args):
return f"{{interm}} = &{c_util.struct_cast(t, '{inp}')};"
@rule(lambda t: t.is_pointer() or t.is_reference())
def input(cls, t, args):
raise ValueError("unsupported input pointer/reference type {}".format(t))
The second
Use template languages like Jinja/Moustache to create declarative template files for codegen. This allows easy visualization of what the output will be, and for people to tweak it or pass a custom template file easily.
I saw this approach here:
Generate arbitrary files from C/C++ header files using CppHeaderParser to read the input files and Jinja2 templates to generate the outputs.
This grew out of a desire to generate pybind11 wrapping code from C++ header files. pybind11gen was created, but then I wanted to generate more things...
{# Silly example that shows how to convert a header file to YAML #}
---
{% for header in headers %}
{% for fn in header.functions %}
{{ fn.name }}:
returns: {{ fn.returns }}
params:
{% for param in fn.parameters %}
- { name: {{ param.name }}, type: "{{ param.type }}" }
{% endfor %}
{% endfor %}
{% endfor %}
I imagine that if clang nodes were passed into here, and a template language was used which allowed to evaluate expressions like t.is_pointer() then it could actually be pretty okay.
The approach with this library for evaluating expressions is by using a custom "hooks" file for defining pre-processing logic.
It's very basic though and does not use clang, but a custom Python preprocessor.
Hello, thank you for the collaboration invite =D
I have been investigating + experimenting with converting C++ headers to Dlang
extern (C++)bindings and also more recently to Nim.Maybe I can share some thoughts/findings with you 馃檪
libclang vs LibTooling
Probably not so important for just one library, but I have been doing reading on which approach is best for translating headers to other languages + bindgen/codegen.
There are some screenshots of experiences from the authors of c2rust and dpp:
馃専 Click for relevant parts of conversation 馃憞
It's possible to use
cppyyfor LibTooling access, if you build LLVM on Linux/MinGW withBUILD_SHARED_LIBSset toON(I think it's also possible withLLVM_BUILD_DYLIB)Doing this gives you:
API/codegen approach
I found two interesting approaches others have taken for the actual codegen that I have been experimenting with. Maybe you have some ideas?
The first
Create decorators in Python which hold rules, the argument is a
clang::QualTypeorclang::Type. Nodes are evaluated against rules, the one matching is chosen for codegen.Each class is a "frontend" driver/generator for a language to create from C++ headers. It's very clever! Currently he has:
Here is the repo where I found this. In his approach, he has used
PyBindfor binding the Clang/LibTooling C++ API to Python, which could also be used instead ofcppyyI suppose (not sure why you'd do that)The second
Use template languages like Jinja/Moustache to create declarative template files for codegen. This allows easy visualization of what the output will be, and for people to tweak it or pass a custom template file easily.
I saw this approach here:
I imagine that if clang nodes were passed into here, and a template language was used which allowed to evaluate expressions like
t.is_pointer()then it could actually be pretty okay.The approach with this library for evaluating expressions is by using a custom "hooks" file for defining pre-processing logic.
It's very basic though and does not use clang, but a custom Python preprocessor.