LLVMでJITアドレス空間にある関数を使用する

前の記事に引き続いてLLVMJITアドレス空間にある関数にアクセスする方法。

LLVMチュートリアルのCh.4にやり方が載っているのだが、そのままでは動かなかった。理由はLLVMが関数のシンボルを見つけられないかららしい。VisualStudioではシンボルのエクスポートをするおまじない(?)を書く必要がある。Linuxでは"-rdynamic"コンパイルオプション付きでコンパイルすればよいらしいが、試していないのでよく分からない。ソースコードは以下の通り。

extern "C"
__declspec(dllexport) void printHelloWorld() {
	printf("Hello, World!\n");
}

int main() {
	InitializeNativeTarget();

	LLVMContext Context;

	Module *M = new Module("test", Context);

	Function *testFunction = cast<Function>(M->getOrInsertFunction("testFunction", Type::getVoidTy(Context), (Type *)0));
	BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", testFunction);
	IRBuilder<> builder(BB);

	FunctionType *FT = FunctionType::get(Type::getVoidTy(Context), false);
	Function *F = Function::Create(FT, Function::ExternalLinkage, "printHelloWorld", M);
	builder.CreateCall(M->getFunction("printHelloWorld"));

	builder.CreateRetVoid();

	ExecutionEngine* EE = EngineBuilder(M).create();

	std::vector<GenericValue> noargs;
	EE->runFunction(testFunction, noargs);

	EE->freeMachineCodeForFunction(testFunction);
	delete EE;
	llvm_shutdown();
	return 0;
}