从C ++类创建LLVM字节码

| 我正在为LLVM中的专用语言编写编译器。我想为已经用C ++编写的库添加绑定。我的想法是将库编译为LLVM字节码(使用
clang -emit-llvm -S abc.c
)并在编译过程中将其链接。这适用于类似的代码
// lib.c
int f() {
    return 123;
}
但是库的一部分写成
// A.cc
class A {
    public:
        int f() { return 123; }
};
导致空字节码文件。我知道我可以通过分离实现来解决此问题:
// A.cc
class A {
    public:
        int f();
};

int A::f() {
    return 123;
}
但这将是很多繁琐的工作。有什么办法可以从我的库源文件中创建有用的字节码吗?还是通过其他方法使该库在我的编译器中可用?     
已邀请:
        您可以看到clang是否支持显式模板实例化的外部链接。这可能适用于非模板,但否则,您可以“强制它”为模板工作。 简单简介: lib1.h
template <typename T=int>
struct ATemplate { T f() { return 123; } };
添加文件
lib1_instantiate.cpp
#include \"lib1.h\"
template struct ATemplate<int>;
template struct ATemplate<unsigned int>;
template struct ATemplate<long>; // etc.
这应该使用外部链接实例化命名模板。 如果您坚持使用非模板类,而上面的技巧对此不起作用,则可以这样包装它:
instantiate.cpp:
namespace hidden_details
{
    template <class libtype> struct instantiator : public libtype 
    // derives... just do something that requires a complete type (not a forward!)
    { };
}

template struct hidden_details::instantiator<A>;
如果您不走运,则必须“使用”内联成员才能使他们获得外部链接。一个常见的技巧是使用这些成员的地址(您无需实现委派的工作):
instantiate.cpp:
static void force_use_A()
{
    void* unused = (void*) &A::f;
}
然而 转换为(void *)会调用未定义的行为(您无法在gcc上使用-pedantic -Werror进行编译) 对于超载,您必须指定丑陋的演员表以消除歧义 高温超导     
        如果只想使用一些库函数,则另一种方法可行:为您使用的所有内容创建包装器。
// wrapper.cc
A* A_create() {
    return new A();
}

// and so on
这样,您不必修改库,但这肯定是一些额外的输入。     

要回复问题请先登录注册