summaryrefslogtreecommitdiff
path: root/tiger-compiler/src/llvmtranslate/llvm-type-visitor.cc
blob: a2130c965cf3b35449737b72e4cf6d84ebe57734 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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