You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 11:45:39