Как легко добавить объявления в модуль LLVM?

Я пишу свой собственный язык в LLVM и использую внешние функции C из стандартных и пользовательских. Теперь я добавляю объявления, используя классы C++ для LLVM IR. Как это:

void register_malloc(llvm::Module *module) {
    std::vector<llvm::Type*> arg_types;
    arg_types.push_back(Type::getInt32Ty(getGlobalContext()));

    FunctionType* type = FunctionType::get(
            Type::getInt8PtrTy(getGlobalContext()), arg_types, false);

    Function *func = Function::Create(
                type, llvm::Function::ExternalLinkage,
                llvm::Twine("malloc"),
                module
           );
    func->setCallingConv(llvm::CallingConv::C);
}

void register_printf(llvm::Module *module) {
    std::vector<llvm::Type*> printf_arg_types;
    printf_arg_types.push_back(llvm::Type::getInt8PtrTy(getGlobalContext()));

    llvm::FunctionType* printf_type =
        llvm::FunctionType::get(
            llvm::Type::getInt32Ty(getGlobalContext()), printf_arg_types, true);

    llvm::Function *func = llvm::Function::Create(
                printf_type, llvm::Function::ExternalLinkage,
                llvm::Twine("printf"),
                module
           );
    func->setCallingConv(llvm::CallingConv::C);
}

Я собираюсь определить десятки внешних функций, есть ли простой способ их определить и как?

Я думаю о «включении» заголовка C (или файла LLVM IR .ll) в модуль. Но я не мог найти ни одного примера, как это сделать...


person kravemir    schedule 23.09.2015    source источник
comment
я думаю, что нет include; для удобства взгляните на мой предыдущий ответ на другой вопрос, специально для printf_prototype.   -  person Hongxu Chen    schedule 24.09.2015
comment
Вы можете использовать clang -S -emit-llvm для компиляции заголовков, а затем использовать CPPBackend для создания кода C++, который создает эти определения.   -  person arrowd    schedule 24.09.2015
comment
@arrowd Я думал о чем-то подобном. Как добавить/загрузить объявления из файла LLVM в модуль?   -  person kravemir    schedule 24.09.2015


Ответы (1)


Создайте пустой исходный код C и включите все необходимые заголовки, а затем скомпилируйте его в LLVM IR с помощью clang -S -emit-llvm. Этот источник будет содержать объявления для каждой функции из заголовков. Теперь используйте llc -march=cpp out.ll, и он создаст исходный код C++, который вызывает LLVM API для создания заданного IR. Вы можете скопировать и вставить этот код в свою программу.

Убедитесь, что у вас включен бэкэнд cpp во время сборки LLVM.

person arrowd    schedule 28.09.2015
comment
Есть ли способ сделать это в проходе модуля вместо копирования и вставки кода в начале файла? У меня есть пропуск, который должен ввести вызов внешней функции. - person foki; 30.11.2018
comment
Поскольку сейчас нет cpp бэкэнда, остается только скомпилировать в биткод и загрузить его в проходе с помощью parseIRFile. - person arrowd; 30.11.2018