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
|