diff --git a/clean.sh b/clean.sh index f466c62..f618bdf 100755 --- a/clean.sh +++ b/clean.sh @@ -2,4 +2,5 @@ rm -f brb rm -f *.o +rm -f *.asm rm -rf *.dSYM \ No newline at end of file diff --git a/src/CodeGenerator.cpp b/src/CodeGenerator.cpp index 0abd80c..7c7b0af 100644 --- a/src/CodeGenerator.cpp +++ b/src/CodeGenerator.cpp @@ -5,7 +5,7 @@ using namespace std; CodeGenerator::CodeGenerator(shared_ptr module): module(module) { } -void CodeGenerator::generateObjectFile(string fileName) { +void CodeGenerator::generateObjectFile(OutputKind outputKind) { llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargets(); llvm::InitializeAllTargetMCs(); @@ -26,6 +26,19 @@ void CodeGenerator::generateObjectFile(string fileName) { module->setDataLayout(targetMachine->createDataLayout()); module->setTargetTriple(targetTriple); + string fileName; + llvm::CodeGenFileType codeGenFileType; + switch (outputKind) { + case OutputKind::ASSEMBLY: + fileName = string(module->getName()) + ".asm"; + codeGenFileType = llvm::CodeGenFileType::AssemblyFile; + break; + case OutputKind::OBJECT: + fileName = string(module->getName()) + ".o"; + codeGenFileType = llvm::CodeGenFileType::ObjectFile; + break; + } + error_code errorCode; llvm::raw_fd_ostream outputFile(fileName, errorCode, llvm::sys::fs::OF_None); if (errorCode) { @@ -34,8 +47,8 @@ void CodeGenerator::generateObjectFile(string fileName) { } llvm::legacy::PassManager passManager; - if (targetMachine->addPassesToEmitFile(passManager, outputFile, nullptr, llvm::CodeGenFileType::AssemblyFile)) { - cerr << "Failed to emit file" << endl; + if (targetMachine->addPassesToEmitFile(passManager, outputFile, nullptr, codeGenFileType)) { + cerr << "Failed to generate file " << fileName << endl; exit(1); } diff --git a/src/CodeGenerator.h b/src/CodeGenerator.h index 5dc3a44..48efa5d 100644 --- a/src/CodeGenerator.h +++ b/src/CodeGenerator.h @@ -14,12 +14,18 @@ using namespace std; class CodeGenerator { +public: + enum class OutputKind { + ASSEMBLY, + OBJECT + }; + private: shared_ptr module; public: CodeGenerator(shared_ptr module); - void generateObjectFile(string fileName); + void generateObjectFile(OutputKind outputKind); }; #endif \ No newline at end of file diff --git a/src/ModuleBuilder.cpp b/src/ModuleBuilder.cpp index caddce7..29670cf 100644 --- a/src/ModuleBuilder.cpp +++ b/src/ModuleBuilder.cpp @@ -51,7 +51,7 @@ void ModuleBuilder::buildFunctionDeclaration(shared_ptrgetReturnValueType()), types, false); - llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::InternalLinkage, statement->getName(), module.get()); + llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::ExternalLinkage, statement->getName(), module.get()); funMap[statement->getName()] = fun; // define function body diff --git a/src/main.cpp b/src/main.cpp index f9b2f36..f6ecc7a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,8 +37,15 @@ void versionPrinter(llvm::raw_ostream &os) { int main(int argc, char **argv) { llvm::cl::SetVersionPrinter(versionPrinter); llvm::cl::extrahelp("\nADDITIONAL HELP:\n\n This is the extra help\n"); - llvm::cl::opt isVerbose("v", llvm::cl::desc("Verbos output"), llvm::cl::init(false)); + llvm::cl::opt outputKind( + llvm::cl::desc("Choose generated output:"), + llvm::cl::init(CodeGenerator::OutputKind::OBJECT), + llvm::cl::values( + clEnumValN(CodeGenerator::OutputKind::OBJECT, "c", "Generate object file"), + clEnumValN(CodeGenerator::OutputKind::ASSEMBLY, "S", "Generate assembly file") + ) + ); llvm::cl::opt inputFileName(llvm::cl::Positional, llvm::cl::desc(""), llvm::cl::Required); llvm::cl::ParseCommandLineOptions(argc, argv, "Bits Runner Builder - LLVM based compiler for the Bits Runner Code language"); @@ -73,8 +80,8 @@ int main(int argc, char **argv) { module->print(llvm::outs(), nullptr); } - //CodeGenerator codeGenerator(module); - //codeGenerator.generateObjectFile("dummy.s"); + CodeGenerator codeGenerator(module); + codeGenerator.generateObjectFile(outputKind); return 0; } \ No newline at end of file