summaryrefslogtreecommitdiff
path: root/tiger-compiler/src/llvmtranslate/translator.hh
diff options
context:
space:
mode:
Diffstat (limited to 'tiger-compiler/src/llvmtranslate/translator.hh')
-rw-r--r--tiger-compiler/src/llvmtranslate/translator.hh145
1 files changed, 145 insertions, 0 deletions
diff --git a/tiger-compiler/src/llvmtranslate/translator.hh b/tiger-compiler/src/llvmtranslate/translator.hh
new file mode 100644
index 0000000..3ddb625
--- /dev/null
+++ b/tiger-compiler/src/llvmtranslate/translator.hh
@@ -0,0 +1,145 @@
+/**
+ ** \file llvmtranslate/translator.hh
+ ** \brief Declaration of llvmtranslate::Translator
+ */
+
+#pragma once
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+
+#include <llvm/IR/IRBuilder.h>
+#include <llvm/IR/Module.h>
+#include <llvm/IR/Value.h>
+
+#pragma GCC diagnostic pop
+
+#include <ast/default-visitor.hh>
+#include <ast/non-assert-visitor.hh>
+#include <ast/non-object-visitor.hh>
+#include <llvmtranslate/fwd.hh>
+#include <llvmtranslate/llvm-type-visitor.hh>
+
+namespace llvmtranslate
+{
+ class Translator
+ : public ast::DefaultConstVisitor
+ , public ast::NonObjectConstVisitor
+ , public ast::NonAssertConstVisitor
+ {
+ public:
+ /// Super class.
+ using super_type = ast::DefaultConstVisitor;
+ /// Import overloaded operator() methods.
+ using super_type::operator();
+
+ Translator(llvm::Module& module, escaped_map_type&& escaped);
+
+ /// Run the translation.
+ void operator()(const ast::Ast& e) override;
+
+ /// \brief Run this visitor on \a node, and return its translation.
+ ///
+ /// It is also guaranteed that \a value_ is set to it.
+ /// More generally, this routine saves from direct calls to \a accept.
+ llvm::Value* translate(const ast::Ast& node);
+
+ /// \name Lvalues
+ /// \{
+ void operator()(const ast::SimpleVar& e) override;
+ void operator()(const ast::FieldVar& e) override;
+ void operator()(const ast::SubscriptVar& e) override;
+ /// \}
+
+ /// \name Expressions
+ /// \{
+ void operator()(const ast::NilExp&) override;
+ void operator()(const ast::IntExp& e) override;
+ void operator()(const ast::StringExp& e) override;
+ void operator()(const ast::RecordExp& e) override;
+ void operator()(const ast::CallExp& e) override;
+ void operator()(const ast::OpExp& e) override;
+ void operator()(const ast::SeqExp& e) override;
+ void operator()(const ast::AssignExp& e) override;
+ void operator()(const ast::IfExp& e) override;
+ void operator()(const ast::WhileExp& e) override;
+ void operator()(const ast::BreakExp&) override;
+ void operator()(const ast::ArrayExp& e) override;
+ void operator()(const ast::CastExp& e) override;
+ /// \}
+
+ /// \name Declarations
+ /// \{
+ void operator()(const ast::FunctionChunk& e) override;
+ void visit_function_dec_header(const ast::FunctionDec& e);
+ void visit_function_dec_body(const ast::FunctionDec& e);
+ void operator()(const ast::VarDec& e) override;
+
+ /**
+ * Check for the existence of a VarDec node within the current function
+ * scoped (locals_[current_function_]).
+ *
+ * If the node does exist within the scope, its LLVM reference is returned
+ * afterward. If not, nullptr is returned instead.
+ *
+ * @param e The node to look for
+ * @return The associated LLVM value if e does exist within the scope.
+ * nullptr otherwise
+ */
+ llvm::Value* declaration_in_current_scope(const ast::VarDec& e) const;
+
+ /// \}
+
+ protected:
+ /// The translation of the last visited node.
+ llvm::Value* value_ = nullptr;
+
+ /// The current function.
+ llvm::Function* current_function_ = nullptr;
+
+ /// The module containing the metadata and this file's AST.
+ llvm::Module& module_;
+
+ /// The global context of the translator.
+ llvm::LLVMContext& ctx_;
+
+ /// IR builder to simplify building nodes and instructions.
+ llvm::IRBuilder<> builder_;
+
+ /// Access for each "variable".
+ /// Since the AST doesn't contain the arguments added
+ /// for the lambda lifting, we need to identify them by their declaration.
+ std::map<const llvm::Function*, std::map<const ast::VarDec*, llvm::Value*>>
+ locals_;
+
+ /// For each loop, the basic block immediately after it.
+ std::map<const ast::WhileExp*, llvm::BasicBlock*> loop_end_;
+
+ /// Access every escaped variable for each function.
+ escaped_map_type escaped_;
+
+ /// The llvm type translator.
+ LLVMTypeVisitor type_visitor_;
+
+ /// Get a Tiger void value.
+ inline llvm::Value* get_void_value();
+
+ inline llvm::Value* get_dereferenced(llvm::Value* ptr, const type::Type* type);
+
+ private:
+ /// Get a LLVM access to a variable, usually to be loaded right after.
+ llvm::Value* access_var(const ast::Var& e);
+
+ /// Call the init_array function that allocates and initialize the array.
+ llvm::Value* init_array(llvm::Value* count_val, llvm::Value* init_val);
+
+ /// Get a llvm::Type from a type::Type using the type_visitor_.
+ llvm::Type* llvm_type(const type::Type& type);
+
+ /// Create a llvm function from a function type.
+ llvm::FunctionType* llvm_function_type(const type::Function& function_t);
+ };
+
+} // namespace llvmtranslate
+
+#include <llvmtranslate/translator.hxx>