LLVM LLJIT开发报错:ExecutorAddr无getAddress成员方法
问题描述
我正在跟着一份教程开发基于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();
相关代码
JIT类实现代码
#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
JIT使用代码
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()(); }
解决方案
这个错误是因为LLVM版本更新后,llvm::orc::ExecutorAddr的API发生了变更:旧版本中的getAddress()方法已被移除,取而代之的是类型安全的toPtr<T>()方法,或通过getValue()获取原始地址值再转换。
修改lookup模板函数中的返回行,替换为以下两种方式之一即可:
方式1:使用toPtr<T>()(推荐,类型安全)
return symbol.get().template toPtr<T>();
方式2:获取原始地址值后转换
return static_cast<T>(symbol.get().getValue());
修改后的完整lookup函数示例:
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 symbol.get().template toPtr<T>(); // return static_cast<T>(symbol.get().getValue()); }
内容的提问来源于stack exchange,提问作者Roy
相关产品推荐
相关产品推荐

