Минимальный пример использования C API LLVM приводит к ошибке: функция и модуль имеют разные контексты - PullRequest
3 голосов
/ 26 мая 2019

Я пытаюсь реализовать небольшой пример с использованием 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, он не просто берет свой контекст из модуля, который я передал.

1 Ответ

3 голосов
/ 27 мая 2019

Ну, я нашел ответ. Вместо LLVMIntType я должен использовать LLVMIntTypeInContext. И вместо LLVMAppendBasicBlock я должен использовать LLVMAppendBasicBlockInContext. Я раньше не понимал, что такие функции существуют.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...