c - 使用 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
,它不只是从我传入的模块中获取它的上下文。
解决方案
嗯,我找到了答案。而不是LLVMIntType
,我应该使用LLVMIntTypeInContext
. 而不是LLVMAppendBasicBlock
,我应该使用LLVMAppendBasicBlockInContext
. 我没有意识到以前存在这样的功能。
推荐阅读
- swift - Firestore 按时间排序,但按 ID 排序
- php - insert key/value pair into an array with two level
- java - 在 Java 中如何计算一系列数字以找到乘积,即传递给使用可变长度参数列表的方法
- asp.net - JSON 列表不使用 Distinct 命令删除重复项
- jsp - 同一个jsp上的两个下拉列表返回null
- c# - 使用 ARBCreateSubscriptionRequest 验证信用卡或借记卡,例如 Customer Profile 的 validationMode 字段
- connection - Extracting amount of connected devices from a router
- mysql - MYSQL (large) UPDATE performance is essentially I/O bound: what lessons to learn?
- ios - 在 IOS 中切片和重塑 MLMultiArray
- c# - Is Math.Log implemented in a way to avoid loss of precision for log(1 + x)?