forked from cosmonaut/wraith-lang
emitting linkable object code
parent
c2efcbd7d2
commit
28402f534a
77
compiler.c
77
compiler.c
|
@ -11,6 +11,7 @@
|
|||
#include <llvm-c/Transforms/Scalar.h>
|
||||
#include <llvm-c/Transforms/Utils.h>
|
||||
#include <llvm-c/TargetMachine.h>
|
||||
#include <llvm-c/Target.h>
|
||||
|
||||
#include "y.tab.h"
|
||||
#include "ast.h"
|
||||
|
@ -480,6 +481,7 @@ static uint8_t CompileStatement(LLVMBuilderRef builder, LLVMValueRef function, N
|
|||
|
||||
static void CompileFunction(
|
||||
LLVMModuleRef module,
|
||||
char *parentStructName,
|
||||
LLVMTypeRef wStructPointerType,
|
||||
Node **fieldDeclarations,
|
||||
uint32_t fieldDeclarationCount,
|
||||
|
@ -522,7 +524,12 @@ static void CompileFunction(
|
|||
|
||||
LLVMTypeRef returnType = WraithTypeToLLVMType(functionSignature->children[1]->type);
|
||||
LLVMTypeRef functionType = LLVMFunctionType(returnType, paramTypes, paramIndex, 0);
|
||||
LLVMValueRef function = LLVMAddFunction(module, functionSignature->children[0]->value.string, functionType);
|
||||
|
||||
char *functionName = strdup(parentStructName);
|
||||
strcat(functionName, "_");
|
||||
strcat(functionName, functionSignature->children[0]->value.string);
|
||||
LLVMValueRef function = LLVMAddFunction(module, functionName, functionType);
|
||||
free(functionName);
|
||||
|
||||
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry");
|
||||
LLVMBuilderRef builder = LLVMCreateBuilder();
|
||||
|
@ -560,6 +567,8 @@ static void CompileFunction(
|
|||
}
|
||||
|
||||
PopScopeFrame(scope);
|
||||
|
||||
LLVMDisposeBuilder(builder);
|
||||
}
|
||||
|
||||
static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *node)
|
||||
|
@ -571,10 +580,11 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
|
|||
LLVMTypeRef types[declarationCount];
|
||||
Node *currentDeclarationNode;
|
||||
Node *fieldDeclarations[declarationCount];
|
||||
char *structName = node->children[0]->value.string;
|
||||
|
||||
PushScopeFrame(scope);
|
||||
|
||||
LLVMTypeRef wStruct = LLVMStructCreateNamed(context, node->children[0]->value.string);
|
||||
LLVMTypeRef wStruct = LLVMStructCreateNamed(context, structName);
|
||||
LLVMTypeRef wStructPointerType = LLVMPointerType(wStruct, 0); /* FIXME: is this address space correct? */
|
||||
|
||||
/* first, build the structure definition */
|
||||
|
@ -604,7 +614,7 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
|
|||
switch (currentDeclarationNode->syntaxKind)
|
||||
{
|
||||
case FunctionDeclaration:
|
||||
CompileFunction(module, wStructPointerType, fieldDeclarations, fieldCount, currentDeclarationNode);
|
||||
CompileFunction(module, structName, wStructPointerType, fieldDeclarations, fieldCount, currentDeclarationNode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -659,13 +669,46 @@ int main(int argc, char *argv[])
|
|||
|
||||
Compile(module, context, rootNode);
|
||||
|
||||
/* add main call */
|
||||
LLVMBuilderRef builder = LLVMCreateBuilder();
|
||||
|
||||
LLVMTypeRef mainFunctionType = LLVMFunctionType(LLVMInt64Type(), NULL, 0, 0);
|
||||
LLVMValueRef mainFunction = LLVMAddFunction(module, "main", mainFunctionType);
|
||||
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(mainFunction, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, entry);
|
||||
|
||||
LLVMValueRef wraithMainFunction = LLVMGetNamedFunction(module, "Program_Main");
|
||||
|
||||
LLVMValueRef mainResult = LLVMBuildCall(builder, wraithMainFunction, NULL, 0, "result");
|
||||
LLVMBuildRet(builder, mainResult);
|
||||
|
||||
LLVMDisposeBuilder(builder);
|
||||
|
||||
/* verify */
|
||||
char *error = NULL;
|
||||
LLVMVerifyModule(module, LLVMAbortProcessAction, &error);
|
||||
|
||||
/* prepare to emit assembly */
|
||||
LLVMInitializeNativeTarget();
|
||||
LLVMInitializeAllTargetInfos();
|
||||
LLVMInitializeAllTargets();
|
||||
LLVMInitializeAllTargetMCs();
|
||||
LLVMInitializeAllAsmParsers();
|
||||
LLVMInitializeAllAsmPrinters();
|
||||
|
||||
LLVMSetTarget(module, LLVM_DEFAULT_TARGET_TRIPLE);
|
||||
LLVMTargetRef target;
|
||||
if (LLVMGetTargetFromTriple(LLVM_DEFAULT_TARGET_TRIPLE, &target, &error) != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to get target!\n");
|
||||
fprintf(stderr, "%s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LLVMPassManagerRef passManager = LLVMCreatePassManager();
|
||||
LLVMAddInstructionCombiningPass(passManager);
|
||||
|
||||
//LLVMAddInstructionCombiningPass(passManager);
|
||||
LLVMAddCFGSimplificationPass(passManager);
|
||||
LLVMAddReassociatePass(passManager);
|
||||
LLVMAddPromoteMemoryToRegisterPass(passManager);
|
||||
|
@ -680,11 +723,29 @@ int main(int argc, char *argv[])
|
|||
fprintf(stderr, "error writing bitcode to file\n");
|
||||
}
|
||||
|
||||
LLVMMemoryBufferRef memoryBuffer = LLVMWriteBitcodeToMemoryBuffer(module);
|
||||
LLVMCreateBinary(memoryBuffer, context, &error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeMemoryBuffer(memoryBuffer);
|
||||
char *cpu = "generic";
|
||||
char *features = "";
|
||||
|
||||
LLVMTargetMachineRef targetMachine = LLVMCreateTargetMachine(
|
||||
target,
|
||||
LLVM_DEFAULT_TARGET_TRIPLE,
|
||||
cpu,
|
||||
features,
|
||||
LLVMCodeGenLevelDefault,
|
||||
LLVMRelocDefault,
|
||||
LLVMCodeModelDefault
|
||||
);
|
||||
|
||||
if (LLVMTargetMachineEmitToFile(targetMachine, module, "test.o", LLVMObjectFile, &error) != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to emit machine code!\n");
|
||||
fprintf(stderr, "%s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeTargetMachine(targetMachine);
|
||||
LLVMPassManagerBuilderDispose(passManagerBuilder);
|
||||
LLVMDisposePassManager(passManager);
|
||||
LLVMDisposeModule(module);
|
||||
|
|
Loading…
Reference in New Issue