3

I'm writing my own language in LLVM and I'm using external C functions from std and custom. I'm now adding declarations using C++ classes for LLVM IR. Like this:

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);
}

I'm gonna define tens of external functions, is there some easy way to define them, and how?

I think about "including" C header(or LLVM IR file .ll) to the module. But I couldn't find any example how to do this...

kravemir
  • 10,636
  • 17
  • 64
  • 111
  • i guess there is no `include`; for a little bit convenience, take a look at [my previous answer to another question](http://stackoverflow.com/a/28175502/528929), specially for `printf_prototype`. – Hongxu Chen Sep 24 '15 at 05:50
  • 1
    You can use `clang -S -emit-llvm` to "compile" headers and then use CPPBackend to generate C++ code that creates these definitions. – arrowd Sep 24 '15 at 07:01
  • @arrowd I was thinking about something like that. How do I add/load declarations from LLVM file to the module? – kravemir Sep 24 '15 at 10:12

1 Answers1

2

Create an empty C source and include every header you need, then compile it to LLVM IR with clang -S -emit-llvm. This source would contain declarations for every function from headers. Now use llc -march=cpp out.ll and it will produce C++ source that calls LLVM API to generate given IR. You can copy-paste this code into your program.

Make sure you have cpp backend enabled during LLVM build.

arrowd
  • 33,231
  • 8
  • 79
  • 110
  • Is there a way to do that within a Module pass instead of copy and pasting the code at the beginning of the file? I have a pass that needs to inject an external function call. – foki Nov 30 '18 at 16:58
  • As there is no `cpp` backend now, the only way left is to compile to bitcode and load it in the pass using `parseIRFile`. – arrowd Nov 30 '18 at 19:55