在LLVM模块中使用C++类

4
基于Kaleidoscope带有MCJIT的Kaleidoscope教程,我有代码来创建一个模块和函数,并使用MCJIT调用它。该函数需要一个原型:
auto ft = llvm::FunctionType::get(llvm::Type::getInt32Ty(Context), argTypes, false);

然而,该示例仅涵盖Double作为参数和返回值(以上使用int)。要做任何高级事情,您需要传递诸如类和容器之类的东西。
您如何在模块中使用现有的C++类?
当然,您可以链接到任何库,但是您需要声明函数原型才能使用它们。如果库API具有类,您如何声明它们?
我想要的是这样的:
auto ft = llvm::FunctionType::get(llvm::Type::getStructTy("class.std::string"), argTypes, false);

class.std::string是从string.h中导入的。

LLVM API只有基本类型。您可以定义结构来表示类,但手动执行此操作太困难(并且不可移植)。

一种方法是将类编译为位代码并将其读入模块中,但如果可能的话,我想避免使用临时文件。而且我不确定如何从模块中提取类型,但应该是可能的。我尝试在我的一个类的头文件上尝试了这个方法(我将头文件重命名为cpp文件,否则clang会将其制作成.gch预编译头文件),结果只是一个常数......也许它被优化掉了?我在cpp文件上尝试它,结果是36000行代码......

然后我找到了this page。我应该使用Clang API而不是LLVM API,因为作为编译器,Clang可以将代码编译为模块。然后我可以使用导入的模块与LLVM API一起使用。这是正确的方法吗?任何工作源代码都将不胜感激,因为使函数调用起作用需要很长时间(教程已过时,文档很少)。

1个回答

1
我会将其编译为LLVM IR类,然后链接这两个模块。然后,有两种方法可以从模块中提取类型:
第一种方法是使用llvm::TypeFinder。使用方法是创建它,然后使用模块作为参数调用run()。以下代码片段将打印出模块中的所有类型:
llvm::TypeFinder type_finder;
type_finder.run(module, true);
for (auto t : type_finder) {
  std::cout << t->getName().str() << std::endl;
}

或者,也可以使用ModulegetIdentifiedStructTypes()方法,并以与上述相同的方式迭代结果向量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接