Last active
February 26, 2024 19:03
-
-
Save iK4tsu/5e8a714e3aa35f5b5b7f52d798267493 to your computer and use it in GitHub Desktop.
LLVM-C 'Hello World' using D Programming Language
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module app; | |
import llvm; | |
int main() | |
{ | |
// module preparation | |
LLVMModuleRef mod = LLVMModuleCreateWithName("main".ptr); | |
// build a main function | |
// functions in LLVM are created by steps | |
// first define the function type | |
// second append the body | |
// third add functionality to the body | |
LLVMTypeRef funType = LLVMFunctionType(LLVMInt32Type(), null, 0, false); // create the function type | |
LLVMValueRef mainFn = LLVMAddFunction(mod, "main".ptr, funType); // add function 'main' to 'mainMod' | |
LLVMSetLinkage(mainFn, LLVMExternalLinkage); // update the linkage of 'main' | |
LLVMBasicBlockRef mainBody = LLVMAppendBasicBlock(mainFn, "mainBody".ptr); // create a body for 'main' | |
// every operation must be performed using a builder | |
LLVMBuilderRef builder = LLVMCreateBuilder(); // create a builder for 'mainBody' | |
LLVMPositionBuilderAtEnd(builder, mainBody); // add the builder to 'mainBody' | |
// use libc's printf function to print 'hello world' | |
// the following steps are similar to what was done above | |
// the function type has it's return type as a pointer | |
// this is because it is function pointer being declared | |
// since 'printf' is a function of libc, no body is added | |
LLVMTypeRef i8p = LLVMPointerType(LLVMInt8Type(), 8); // create the return type | |
LLVMTypeRef printfType = LLVMFunctionType(LLVMInt32Type(), &i8p, 1, true); // create the function type | |
LLVMValueRef printfFun = LLVMAddFunction(mod, "printf".ptr, printfType); // add function 'printf' to 'mainMod' | |
LLVMSetLinkage(printfFun, LLVMExternalLinkage); // update the linkage of 'printf' | |
// create the content to pass into 'printf' and call the function | |
// once again, operations are performed using a builder | |
// in this case, the builder associated with function 'main' | |
LLVMValueRef str = LLVMBuildGlobalStringPtr(builder, "hello world\n".ptr, "hello_world"); | |
LLVMValueRef format = LLVMBuildPointerCast(builder, format, LLVMPointerType(LLVMInt8Type(), 8), "format"); | |
LLVMValueRef printfCall = LLVMBuildCall(builder, printfFun, &format, 1, "call"); | |
// setup the return value | |
// return '0' from 'main' | |
LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 0, true)); | |
// check the module for any potential errors | |
char* err; | |
LLVMVerifyModule(mod, LLVMAbortProcessAction, &err); | |
LLVMDisposeMessage(err); | |
// prepare the execution engine to run the program | |
LLVMExecutionEngineRef engine; | |
err = null; | |
LLVMInitializeNativeTarget(); | |
if (LLVMCreateExecutionEngineForModule(&engine, mod, &err) != LLVMErrorSuccess) | |
{ | |
import std.stdio : stderr; | |
import std.string : fromStringz; | |
stderr.writefln!"[Error]: [Execution Engine]: %s"(err.fromStringz()); | |
return 1; | |
} | |
LLVMInitializeNativeAsmPrinter(); | |
LLVMInitializeNativeAsmParser(); | |
// access function 'main' | |
alias MainFn = extern (C) int function(); | |
auto fn = cast(MainFn) LLVMGetFunctionAddress(engine, "main".ptr); | |
// print LLVM-IR | |
import std.stdio : writeln; | |
import std.string : fromStringz; | |
LLVMPrintModuleToString(mod).fromStringz.writeln(); | |
// run function 'main' | |
return fn(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"authors": [ "João Lourenço" ], | |
"copyright": "Copyright © 2022, João Lourenço", | |
"description": "LLVM-C 'Hello World' using D", | |
"license": "GPL-3.0", | |
"name": "llvm-hello-world", | |
"dependencies": { | |
"llvm-d": "~>3.0.0" | |
}, | |
"libs": ["LLVM-14", "LTO"], | |
"versions": ["LLVM_8_0_0"] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment