从C++类创建LLVM字节码
Create LLVM bytecode from C++ classes
我正在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-Weror编译)
- 对于重载,您必须指定难看的强制转换来消除它们的歧义
HTH
如果只想使用几个库函数,则可以使用另一种方法:为您使用的所有函数创建一个包装器。
// wrapper.cc
A* A_create() {
return new A();
}
// and so on
这样你就不必修改你的库,但这肯定是一些额外的类型。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 在UNIX系统中使用DIR查找文件的字节大小
- 如何将 I->getType() 作为参数传递给 llvm 中的 CreateCall?
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- std::当在256字节边界上写入整数时,流的奇怪行为
- 将尾部调用void(i32,..)位转换为llvm::函数以获取FnAttribute
- 当比特(而不是字节)的顺序至关重要时的持久性
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 如何在文件中查找字节序列
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- llvm构建器向基本块添加终止符
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 字节到位运算符重载C++
- 在java中读取c++字节的位字段
- 正在LLVM中检测整数比较条件
- 如何使用调用和别名指令在 llvm 字节码中查找函数名称
- 如何使用调用和分配指令在 llvm 字节码中查找类名
- c++的LLVM替代方案(字节码生成)
- 从C++类创建LLVM字节码