我试图创建一个函数调用,该函数foo接收函数指针(带签名void bar(void))作为参数.从这篇文章我得到了完成这个的基本想法.首先我注册Foo功能.Bar实际上是一个由LLVM编译的函数,因此没有必要的注册.
FunctionType* BarType = FunctionType::get(Type::getVoidTy(getGlobalContext()), false);
Type* FooType[1];
FooType[0] = static_cast<Type*>(BarType)->getPointerTo();
ArrayRef<Type*> FooTypeARef(FooType, 1);
FunctionType* signature = FunctionType::get(Type::getInt32Ty(getGlobalContext()), FooTypeARef, false);
Function* func = Function::Create(signature, Function::ExternalLinkage, "Foo", TheModule);
LLVM_ExecutionEngine()->addGlobalMapping(func, const_cast<void*>(&Foo));
Run Code Online (Sandbox Code Playgroud)
这是插入实际调用的方式(案例I)
std::vector<Value*> ArgsV_Foo;
Function *FooFun= LLVM_Module()->getFunction("Foo");
Function* BarFun = LLVM_Module()->getFunction("Bar");
ArgsV_Foo.push_back( BarFun );
LLVM_Builder()->CreateCall(FooFun, ArgsV, "calltmp")
Run Code Online (Sandbox Code Playgroud)
但是,这会在CreateCall内部中止,原因是"调用带有错误签名的函数".我不确定这条线ArgsV_Foo.push_back( BarFun )是否正确.
我觉得可能的另一种方法是使用ExecutionEngine来获取指向Bar的指针,但我不明白如何将生成的函数指针转换为llvm::Value*(Case II)
std::vector<Value*> ArgsV_Foo;
Function *FooFun= LLVM_Module()->getFunction("Foo");
Function* BarFun = LLVM_Module()->getFunction("Bar");
void* BarFunPtr = LLVM_ExecutionEngine()->getPointerToFunction(BarFun);
Value* val = ??
ArgsV_FEFork.push_back(val);
LLVM_Builder()->CreateCall(FooFun, ArgsV, "calltmp")
Run Code Online (Sandbox Code Playgroud)
也许有人知道如何完成第二种情况或确认第一种情况下的分配是正确的(问题出在其他地方).
我不太确定那里发生了什么.BarType举个例子,为什么你要向上倾斜?在任何情况下,检查它的简单方法是调用所->dump()涉及的所有类型,并自己检查差异是什么.
另外,避免static_cast在LLVM对象上使用- 有更多规范的方法来进行强制转换.
BarFunPtr)转换为整数.inttoptr.指针的类型应该是匹配bar类型的函数指针.ArrayRefs最后,仅仅是FYI,有更简单的方法来创建ArrayRef实例....特别是你可能对它的隐式单元素构造函数感兴趣:-)