首页 > 解决方案 > 使用 LLVM 的 C API 的最小示例会产生错误:函数和模块具有不同的上下文

问题描述

我正在尝试使用 C API 实现一个小示例。我收到一条错误消息,指出函数上下文与模块上下文不匹配,我无法弄清楚。

这是我的代码:

#include <stdio.h>

#include <llvm-c/Analysis.h>
#include <llvm-c/Core.h>
#include <llvm-c/Target.h>
#include <llvm-c/TargetMachine.h>

int
main() {
    LLVMInitializeNativeTarget();
    LLVMInitializeNativeAsmPrinter();
    char* triple = LLVMGetDefaultTargetTriple();
    char* error;
    LLVMTargetRef target_ref;
    if (LLVMGetTargetFromTriple(triple, &target_ref, &error)) {
        printf("Error: %s\n", error);
        return 1;
    }
    LLVMTargetMachineRef tm_ref = LLVMCreateTargetMachine(
      target_ref,
      triple,
      "",
      "",
      LLVMCodeGenLevelDefault,
      LLVMRelocStatic,
      LLVMCodeModelJITDefault);
    LLVMDisposeMessage(triple);

    LLVMContextRef context = LLVMContextCreate();
    LLVMModuleRef module = LLVMModuleCreateWithNameInContext("module_name", context);
    // LLVMModuleRef module = LLVMModuleCreateWithName("module_name");

    LLVMTypeRef param_types[] = {LLVMIntType(32), LLVMIntType(32)};
    LLVMTypeRef func_type = LLVMFunctionType(LLVMIntType(32), param_types, 2, 0);

    LLVMValueRef func = LLVMAddFunction(module, "function_name", func_type);
    LLVMBasicBlockRef entry = LLVMAppendBasicBlock(func, "entry");

    LLVMBuilderRef builder = LLVMCreateBuilderInContext(context);
    // LLVMBuilderRef builder = LLVMCreateBuilder();
    LLVMPositionBuilderAtEnd(builder, entry);
    LLVMValueRef tmp = LLVMBuildAdd(builder, LLVMGetParam(func, 0), LLVMGetParam(func, 1), "add");
    LLVMBuildRet(builder, tmp);

    LLVMVerifyModule(module, LLVMAbortProcessAction, &error);
    LLVMDisposeMessage(error);
}

然后我的执行:

$ llvm-config --version
8.0.0
$ clang++ trash.cpp `llvm-config --cflags --ldflags` `llvm-config --libs` `llvm-config --system-libs`
$ ./a.out 
Function context does not match Module context!
i32 (i32, i32)* @function_name
LLVM ERROR: Broken module found, compilation aborted!

这不是一个适用于非常小的示例的 API;因此,这里有相当多的代码。

如果我使用当前注释掉的未引用的代码context,一切正常。我不清楚为什么,当我调用 时LLVMAddFunction,它不只是从我传入的模块中获取它的上下文。

标签: cllvm

解决方案


嗯,我找到了答案。而不是LLVMIntType,我应该使用LLVMIntTypeInContext. 而不是LLVMAppendBasicBlock,我应该使用LLVMAppendBasicBlockInContext. 我没有意识到以前存在这样的功能。


推荐阅读