Search code examples
c++llvmllvm-irinstrumentation

Linking LLVM getOrInsertFunction to a external c++ function in a LLVM pass


I have written a LLVM pass that inserts a call to a external function (foo) in a C(count.c) file. Later when I link C file's object that contains foo function with LLVM instrumented c++ file, it works fine. The C file which contains foo function, looks like this.

#include <stdio.h>
int count = 0;

void foo(int id) {
    count++;
    printf("id = $d,  count = %d\n", id, count);
}

I create a call from LLVM pass using this code snippet:

ArrayRef<Type *> paramTypes = {Type::getInt8Ty(Ctx)};
Type *retType = Type::getVoidTy(Ctx);
FunctionType *funcType = FunctionType::get(retType, paramTypes, false);

FunctionCallee callee = M.getOrInsertFunction("foo", funcType);

All this works fine as long as foo function is in a C file. But if foo is in a C++ file, ld returns undefined references to 'foo'

Is there a way to link an external function in a C++ file to llvm getOrInsertFunction?


Solution

  • Yes, you need to make the C++ function as extern.

    foo.cpp can look like:

    extern "C" {
    
    void foo(int id) {
        count++;
        printf("id = $d,  count = %d\n", id, count);
    }
    
    }
    

    extern C tells the compiler to not mangle the name of scoped functions. You can learn more about name mangling and extern C here