diff options
| author | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
|---|---|---|
| committer | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
| commit | 967be9e750221ab2ab783f95df79bb26d290a45e (patch) | |
| tree | 6802900a5e975f9f68b169f0f503f040056d6952 /tiger-compiler/src/llvmtranslate/llvm-type-visitor.cc | |
Diffstat (limited to 'tiger-compiler/src/llvmtranslate/llvm-type-visitor.cc')
| -rw-r--r-- | tiger-compiler/src/llvmtranslate/llvm-type-visitor.cc | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/tiger-compiler/src/llvmtranslate/llvm-type-visitor.cc b/tiger-compiler/src/llvmtranslate/llvm-type-visitor.cc new file mode 100644 index 0000000..a2130c9 --- /dev/null +++ b/tiger-compiler/src/llvmtranslate/llvm-type-visitor.cc @@ -0,0 +1,110 @@ +/** + ** \file llvmtranslate/llvm-type-visitor.cc + ** \brief Implementation of llvmtranslator::LLVMTypeVisitor. + */ + +#include <llvm/IR/DerivedTypes.h> + +#include <llvmtranslate/llvm-type-visitor.hh> +#include <type/types.hh> + +namespace llvmtranslate +{ + LLVMTypeVisitor::LLVMTypeVisitor(llvm::LLVMContext& ctx) + : ctx_{ctx} + {} + + llvm::Type* LLVMTypeVisitor::llvm_type_get() { return type_; } + + llvm::Type* LLVMTypeVisitor::get_record_ltype(const type::Record* e) + { + return structs_[e]; + } + + llvm::Type* LLVMTypeVisitor::llvm_type(const type::Type& type) + { + operator()(type); + return type_; + } + + void LLVMTypeVisitor::operator()(const type::Nil& e) + { + if (auto record_type = e.record_type_get()) + type_ = llvm_type(*record_type); + else + unreachable(); + } + + void LLVMTypeVisitor::operator()(const type::Void&) + { + // FIXME DONE: Some code was deleted here (Void types can be interpreted as int or void type). + // Je cite : "a variable can hold a void value (that are represented using an integer in LLVM)" + // Mais du coup, je sais pas ce qui détermine quel type on lui donne. + // En attendant je mets void tout le temps jusqu'à ce qu'on trouve pourquoi on le mettrait à int + // Y a un monde où ça se gère au dessus (genre les vardecs et les assignexp ?) + // Source : Un YAKA qui dit que en gros on a le choix mais qu'il vaut mieux le représenter comme int + // Du coup pour le distinguer c'est un int sur 0 bits + type_ = llvm::Type::getIntNTy(ctx_,0); + } + + void LLVMTypeVisitor::operator()(const type::Int&) + { + type_ = llvm::Type::getInt32Ty(ctx_); + } + + void LLVMTypeVisitor::operator()(const type::String&) + { + // Strings are pointers to characters in LLVM. + // FIXME DONE: Some code was deleted here. + // Bon vu qu'on a pas accès à la taille de la string on y va yolo. + // Du coup c'est un PointerType de Int8 (du coup 8 bits pour un char) + type_ = llvm::PointerType::get(llvm::Type::getInt8Ty(ctx_), 0); + } + + void LLVMTypeVisitor::operator()(const type::Named& e) + { + // FIXME DONE: Some code was deleted here. + llvm_type(e.actual()); + + const std::string reference_name = e.name_get().get(); + + if (const auto record_ref = dynamic_cast<const type::Record*>(&e.type_get()->actual()); + record_ref != nullptr && structs_[record_ref]->getName() != reference_name) + { + structs_[record_ref]->setName(reference_name); + } + } + + void LLVMTypeVisitor::operator()(const type::Record& e) + { + // If the record was never translated, translate it + if (!structs_[&e]) + { + // We need to create the struct in two passes to support recursive + // types, like 'type a = { next : a } + // So, first we create an empty struct + structs_[&e] = llvm::StructType::create(ctx_); + // Then set the body of the structure + std::vector<llvm::Type*> field_types; + field_types.reserve(e.fields_get().size()); + // FIXME DONE: Some code was deleted here. + //Martial: Copy and convert the fields ig + for (const auto& field : e.fields_get()) + { + super_type::operator()(field.type_get()); + field_types.push_back(type_); + } + //Martial: Set the body with the converted types + structs_[&e]->setBody(std::move(field_types), false); + } + type_ = llvm::PointerType::getUnqual(structs_[&e]); + } + + void LLVMTypeVisitor::operator()(const type::Array& e) + { + // Arrays are pointers to the array elements, like in C. + // FIXME DONE: Some code was deleted here. + llvm_type(*e.get_element_type()); + type_ = llvm::PointerType::getUnqual(type_); + } +} // namespace llvmtranslate |
