我遵循一个使用LLVM编写JIT编译器的教程 (代码如下所示,并使用了最新版本的LLVM )。除了这一行(如果我对此函数进行注释,代码会编译):
return (T)symbol.get().getAddress();
这将产生以下错误:
JIT.cpp:22:29: error: ‘std::remove_reference_t<llvm::orc::ExecutorAddr> {aka class llvm::orc::ExecutorAddr}’ has no member named ‘getAddress’
return (T)symbol.get().getAddress();
代码
#pragma once
#include <llvm/ExecutionEngine/Orc/LLJIT.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <memory>
#include <type_traits>
namespace FooLang
{
class JIT
{
private:
std::unique_ptr<llvm::orc::LLJIT> lljit;
public:
JIT(std::unique_ptr<llvm::orc::LLJIT> _lljit) : lljit(std::move(_lljit)) {}
void registerSymbols(
llvm::function_ref<llvm::orc::SymbolMap(llvm::orc::MangleAndInterner)> symbolMap) {
auto &mainJitDylib = this->lljit->getMainJITDylib();
llvm::cantFail(mainJitDylib.define(
absoluteSymbols(symbolMap(llvm::orc::MangleAndInterner(
mainJitDylib.getExecutionSession(), this->lljit->getDataLayout())))));
}
template <typename T, typename = std::enable_if_t<std::is_pointer<T>::value && std::is_function<std::remove_pointer_t<T>>::value>>
llvm::Expected<T> lookup(const std::string &name)
{
auto symbol = this->lljit->lookup(name);
if (!symbol)
{
return symbol.takeError();
}
return (T)symbol.get().getAddress();
}
template <typename T, typename = std::enable_if_t<std::is_function<T>::value>>
inline llvm::Expected<T *> lookup(const std::string &name)
{
return this->lookup<T *>(name);
}
static llvm::Expected<JIT> create(std::unique_ptr<llvm::Module> &module, std::unique_ptr<llvm::LLVMContext> &context)
{
auto lljit = llvm::orc::LLJITBuilder().create();
auto &jd = lljit.get()->getMainJITDylib();
jd.addGenerator(llvm::cantFail(llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess('_')));
if (!lljit)
{
return lljit.takeError();
}
if (auto err = lljit.get()->addIRModule(llvm::orc::ThreadSafeModule(std::move(module), std::move(context))))
{
return std::move(err);
}
return JIT(std::move(lljit.get()));
}
};
} // namespace FooLang
它的用途如下:
int run(IRgen* ir_gen)
{
auto jit = JIT::create(ir_gen->module, ir_gen->llvm_context);
jit->registerSymbols(
[&](llvm::orc::MangleAndInterner interner) {
llvm::orc::SymbolMap symbolMap;
// Add symbols here
symbolMap[interner("printf")] = llvm::JITEvaluatedSymbol::fromPointer(printf);
return symbolMap;
});
auto entry = jit->lookup<int()>("main");
if (!entry)
{
llvm::errs() << entry.takeError();
return 1;
}
return entry.get()();
}
发布于 2022-09-16 22:45:34
在最近的更改中,auto symbol = this->llvmjit->lookup(name);
将返回一个ExecutorAddr
而不是一个JITEvaluatedSymbols
,请参见:https://reviews.llvm.org/rG16dcbb53dc7968a3752661aac731172ebe0faf64
粘贴的代码返回模板参数类型T
,不显示调用者,因此我无法看到您打算返回的内容。我的建议是,您可能想使用ExecutorAddr::toPtr
,但我不能肯定。
https://stackoverflow.com/questions/73742249
复制相似问题