Nicolas Winkler 6 лет назад
Родитель
Сommit
e66d89c8a4
6 измененных файлов с 105 добавлено и 15 удалено
  1. 84 8
      src/CodeGeneration.cpp
  2. 3 2
      src/CodeGeneration.h
  3. 4 1
      src/CodegenVisitor.cpp
  4. 3 2
      src/CodegenVisitor.h
  5. 4 0
      src/main.cpp
  6. 7 2
      src/makefile

+ 84 - 8
src/CodeGeneration.cpp

@@ -1,38 +1,111 @@
 #include "CodeGeneration.h"
 
 #include <llvm/IR/LLVMContext.h>
-#include <llvm/IR/PassManager.h>
+#include <llvm/IR/LegacyPassManager.h>
+#include <llvm/IR/Type.h>
+#include <llvm/IR/Constants.h>
+#include <llvm/IR/BasicBlock.h>
 #include <llvm/IR/Verifier.h>
+#include <llvm/IR/IRBuilder.h>
+#include <llvm/Target/TargetMachine.h>
+#include <llvm/Support/TargetRegistry.h>
+#include <llvm/Support/TargetSelect.h>
+#include <llvm/Support/FileSystem.h>
+
 
 using namespace qlow;
 
 static llvm::LLVMContext context;
 
+namespace qlow
+{
+namespace gen
+{
+
 std::unique_ptr<llvm::Module> generateModule(const sem::SymbolTable<sem::Class>& classes)
 {
     using llvm::Module;
-    std::unique_ptr<Module> module = llvm::make_unique<Module>("qlow_module", context);
+    using llvm::Function;
+    using llvm::Argument;
+    using llvm::Type;
+    using llvm::FunctionType;
+    using llvm::BasicBlock;
+    using llvm::Value;
+    using llvm::IRBuilder;
 
+    std::unique_ptr<Module> module = llvm::make_unique<Module>("qlow_module", context);
+    
+    std::vector<Type*> doubles(1, Type::getDoubleTy(context));
+    FunctionType* funcType = FunctionType::get(Type::getDoubleTy(context), doubles, false);
+    Function* func = Function::Create(funcType, Function::ExternalLinkage, "qlow_function", module.get());
+    BasicBlock* bb = BasicBlock::Create(context, "entry", func);
+    IRBuilder<> builder(context);
+    builder.SetInsertPoint(bb);
+
+    Function::arg_iterator args = func->arg_begin();
+
+    Argument* arg = &(*args);
+    
+    Value* val = llvm::ConstantFP::get(context, llvm::APFloat(5.0));
+    Value* val2 = llvm::ConstantFP::get(context, llvm::APFloat(1.0));
+    Value* result = builder.CreateFAdd(arg, val2, "add_constants");
+    builder.CreateRet(result);
     return module;
 }
 
 
-void gen::generateObjectFile(const std::string& name, std::unique_ptr<llvm::Module> module,
-        const sem::SymbolTable<sem::Class>& classes)
+void generateObjectFile(const std::string& filename, std::unique_ptr<llvm::Module> module)
 {
-    using llvm::PassManager;
+    using llvm::legacy::PassManager;
+    using llvm::raw_fd_ostream;
+    using llvm::Target;
+    using llvm::TargetMachine;
+    using llvm::TargetRegistry;
+    using llvm::TargetOptions;
 
 
     llvm::verifyModule(*module);
 
-    PassManager<llvm::Module> pm;
-    //pm.add(createPrintModulePass(&outs()));
-    //pm.run(module);
 
+    llvm::InitializeAllTargetInfos();
+    llvm::InitializeAllTargets();
+    llvm::InitializeAllTargetMCs();
+    llvm::InitializeAllAsmParsers();
+    llvm::InitializeAllAsmPrinters();
+
+    PassManager pm;
 
     const char cpu[] = "generic";
     const char features[] = "";
 
+    std::string error;
+    std::string targetTriple = llvm::sys::getDefaultTargetTriple();
+    const Target* target = TargetRegistry::lookupTarget(targetTriple, error);
+
+    if (!target)
+        fprintf(stderr, "could not create target: %s", error.c_str());
+
+    TargetOptions targetOptions;
+    auto relocModel = llvm::Optional<llvm::Reloc::Model>();
+    TargetMachine* targetMachine = target->createTargetMachine(targetTriple, cpu,
+            features, targetOptions, relocModel);
+
+    std::error_code errorCode;
+    raw_fd_ostream dest(filename, errorCode, llvm::sys::fs::F_None);
+    targetMachine->addPassesToEmitFile(pm, dest, llvm::LLVMTargetMachine::CGFT_ObjectFile,
+            llvm::TargetMachine::CGFT_ObjectFile);
+
+    pm.run(*module);
+    dest.flush();
+    dest.close();
+
+    return;
+
+    //pm.add(createPrintModulePass(&outs()));
+    //pm.run(module);
+
+
+
 
     /*
     auto RM = llvm::Optional<llvm::Reloc::Model>();
@@ -72,4 +145,7 @@ void gen::generateObjectFile(const std::string& name, std::unique_ptr<llvm::Modu
   return 0;*/
 }
 
+}
+}
+
 

+ 3 - 2
src/CodeGeneration.h

@@ -8,8 +8,9 @@ namespace qlow
 {
     namespace gen
     {
-        void generateObjectFile(const std::string& name, std::unique_ptr<llvm::Module> module,
-            const sem::SymbolTable<sem::Class>& classes);
+        std::unique_ptr<llvm::Module> generateModule(const sem::SymbolTable<sem::Class>& classes);
+        void generateObjectFile(const std::string& name, std::unique_ptr<llvm::Module> module);
+            
     }
 }
 

+ 4 - 1
src/CodegenVisitor.cpp

@@ -1,11 +1,14 @@
 #include "CodegenVisitor.h"
 
+#include <llvm/IR/Constants.h>
+
 
 using namespace qlow;
 
 llvm::Value* CodegenVisitor::visit(sem::IntConst& node, llvm::LLVMContext& context)
 {
-    return nullptr;
+    return llvm::ConstantInt::get(context, llvm::APInt(32, std::to_string(node.value), 10));
 }
 
 
+

+ 3 - 2
src/CodegenVisitor.h

@@ -1,8 +1,8 @@
 #ifndef QLOW_CODEGEN_VISITOR_H
 #define QLOW_CODEGEN_VISITOR_H
 
-#include "llvm/IR/Value.h"
-#include "llvm/IR/LLVMContext.h"
+#include <llvm/IR/Value.h>
+#include <llvm/IR/LLVMContext.h>
 
 #include "Visitor.h"
 #include "Semantic.h"
@@ -16,6 +16,7 @@ namespace qlow
 {
     namespace gen
     {
+        
     }
 }
 

+ 4 - 0
src/main.cpp

@@ -4,6 +4,7 @@
 
 #include "Ast.h"
 #include "Semantic.h"
+#include "CodeGeneration.h"
 
 extern std::unique_ptr<std::vector<std::unique_ptr<qlow::ast::Class>>> parsedClasses;
 extern FILE* qlow_parser_in;
@@ -60,6 +61,9 @@ int main(int argc, char** argv)
         else {
             mainMethod = mainmain->second.get();
         }
+
+        auto mod = qlow::gen::generateModule(semClasses);
+        qlow::gen::generateObjectFile("obj.o", std::move(mod));
     }
     catch (qlow::sem::SemanticException& se)
     {

+ 7 - 2
src/makefile

@@ -5,7 +5,12 @@ CXX := g++
 
 INCLUDEDIRS := -I`llvm-config --includedir`
 CXXFLAGS := -std=c++17 $(INCLUDEDIRS) # -Wall -Wextra
+
+ifdef STATIC
+LDFLAGS := `llvm-config --link-static --ldflags --system-libs --libs all` -static
+else
 LDFLAGS := `llvm-config --ldflags --system-libs --libs all`
+endif
 
 YACC := bison
 YACCFLAGS := -d
@@ -21,8 +26,6 @@ EXECUTABLE := qlow
 .PHONY: all
 all: $(EXECUTABLE)
 
-
-
 release: CXXFLAGS += -O3 -flto
 release: LDFLAGS += -O3 -flto
 release: all
@@ -33,6 +36,8 @@ debug: all
 $(EXECUTABLE): $(OBJECTS)
 	$(CXX) $^ $(LDFLAGS) -o $@
 
+parser.o: parser.cpp
+	$(CXX) -c -o $@ $< $(CXXFLAGS) -fno-strict-aliasing
 
 %.o: %.cpp
 	$(CXX) -c -o $@ $< $(CXXFLAGS)