Calling C-language variadic functions

Such as printf, etc., from IR created using the API (IRBuilder).

Google hasn't provided much help, and I can't find anything relevant in the docs (the docs talk about how to do varargs in LLVM ASM, but not how to call an external vararg function that exists in a library that gets linked to the LLVM module).

Is there something special I need to do? Simply calling IRBuilder::CreateCall() isn't working for me. I see the call to the variadic function in the asm dump, and also in the generated code, but the code (x86_64) doesn't seem to have enough activity going on at the call site (and I get a possibly predictable "illegal instruction" abort when I try to run the code).

Any ideas?

Thanks
Greg

Gregory Junker <gjunker@dayark.com> writes:

Such as printf, etc., from IR created using the API (IRBuilder).

Google hasn't provided much help, and I can't find anything relevant in
the docs (the docs talk about how to do varargs in LLVM ASM, but not how
to call an external vararg function that exists in a library that gets
linked to the LLVM module).

Is there something special I need to do?

Declare the function with the right type:

FunctionType* FuncTy_7 = FunctionType::get(
  /*Result=*/IntegerType::get(mod->getContext(), 32),
  /*Params=*/FuncTy_7_args,
  /*isVarArg=*/true);

Function* func_foo = Function::Create(
  /*Type=*/FuncTy_7,
  /*Linkage=*/GlobalValue::ExternalLinkage,
  /*Name=*/"foo", mod); // (external, no body)
func_foo->setCallingConv(CallingConv::C);

Note the `` /*isVarArg=*/true " part.

These are excerpts taken from the online LLVM demo, which is very useful
as a quick method for seeing how the C++ API is used (it doesn't use
IRBuilder, though).

Simply calling
IRBuilder::CreateCall() isn't working for me. I see the call to the
variadic function in the asm dump, and also in the generated code, but
the code (x86_64) doesn't seem to have enough activity going on at the
call site (and I get a possibly predictable "illegal instruction" abort
when I try to run the code).

I guess that you are not using `verifyModule' before generating the
native code, because the sort of declaration/call mismatch you are
experiencing is detected there. Or you are calling the external vaarg
function with the same number of parameters listed on the faulty
declaration, in which case `verifyModule' has no reason for complaning.

Gregory Junker<gjunker@dayark.com> writes:

Such as printf, etc., from IR created using the API (IRBuilder).

Google hasn't provided much help, and I can't find anything relevant in
the docs (the docs talk about how to do varargs in LLVM ASM, but not how
to call an external vararg function that exists in a library that gets
linked to the LLVM module).

Is there something special I need to do?

Declare the function with the right type:

FunctionType* FuncTy_7 = FunctionType::get(
   /*Result=*/IntegerType::get(mod->getContext(), 32),
   /*Params=*/FuncTy_7_args,
   /*isVarArg=*/true);

Ah this must be the primary issue -- will give that a shot, thanks!

I guess that you are not using `verifyModule' before generating the
native code, because the sort of declaration/call mismatch you are
experiencing is detected there. Or you are calling the external vaarg
function with the same number of parameters listed on the faulty
declaration, in which case `verifyModule' has no reason for complaning.

I am not, but I will start doing so.

Greg