3 #include <unordered_set>
5 #include <fmt/format.h>
7 using namespace tanlang;
11 PrimitiveType *PrimitiveType::Create(PrimitiveType::Kind kind) {
12 auto it = CACHE.find(kind);
13 if (it != CACHE.end()) {
18 ret->_type_name = TYPE_NAMES[kind];
24 PrimitiveType *Type::GetVoidType() {
return PrimitiveType::Create(PrimitiveType::VOID); }
26 PrimitiveType *Type::GetBoolType() {
return PrimitiveType::Create(PrimitiveType::BOOL); }
28 PrimitiveType *Type::GetCharType() {
return PrimitiveType::Create(PrimitiveType::CHAR); }
30 PrimitiveType *Type::GetIntegerType(
size_t bit_size,
bool is_unsigned) {
34 return PrimitiveType::Create(PrimitiveType::U8);
36 return PrimitiveType::Create(PrimitiveType::I8);
40 return PrimitiveType::Create(PrimitiveType::U16);
42 return PrimitiveType::Create(PrimitiveType::I16);
46 return PrimitiveType::Create(PrimitiveType::U32);
48 return PrimitiveType::Create(PrimitiveType::I32);
52 return PrimitiveType::Create(PrimitiveType::U64);
54 return PrimitiveType::Create(PrimitiveType::I64);
64 return PrimitiveType::Create(PrimitiveType::F32);
66 return PrimitiveType::Create(PrimitiveType::F64);
72 StringType *Type::GetStringType() {
return STRING_TYPE; }
75 auto it = POINTER_TYPE_CACHE.find(pointee);
76 if (it != POINTER_TYPE_CACHE.end()) {
77 TAN_ASSERT(it->second->is_pointer() && it->second->get_pointee() == pointee);
81 POINTER_TYPE_CACHE[pointee] = ret;
87 auto it = ARRAY_TYPE_CACHE.find({element_type, size});
88 if (it != ARRAY_TYPE_CACHE.end()) {
91 auto *ret =
new ArrayType(element_type, size);
92 ARRAY_TYPE_CACHE[{element_type, size}] = ret;
98 FunctionType *Type::GetFunctionType(
Type *ret_type,
const vector<Type *> &arg_types) {
103 auto it = NAMED_TYPE_CACHE.find(decl->get_name());
104 if (it != NAMED_TYPE_CACHE.end()) {
105 auto *t = pcast<StructType>(it->second);
106 t->_member_types = decl->get_member_types();
110 NAMED_TYPE_CACHE[decl->get_name()] = ret;
115 TypeRef *Type::GetTypeRef(
const str &name) {
return new TypeRef(name); }
117 int Type::get_align_bits() {
122 int Type::get_size_bits() {
127 vector<Type *> Type::children()
const {
132 int PrimitiveType::get_size_bits() {
return SIZE_BITS[_kind]; }
134 int PrimitiveType::get_align_bits() {
135 TAN_ASSERT(_kind != VOID);
136 return SIZE_BITS[_kind];
139 PointerType::PointerType(
Type *pointee_type) : _pointee_type(pointee_type) {
140 _type_name = pointee_type->get_typename() +
"*";
143 vector<Type *> PointerType::children()
const {
return {_pointee_type}; }
146 int PointerType::get_align_bits() {
return 64; }
147 int PointerType::get_size_bits() {
return 64; }
148 int ArrayType::get_align_bits() {
return 64; }
149 int ArrayType::get_size_bits() {
return 64; }
150 int StringType::get_align_bits() {
return 64; }
151 int StringType::get_size_bits() {
return 64; }
153 ArrayType::ArrayType(
Type *element_type,
int size) : _element_type(element_type), _size(size) {
154 _type_name = element_type->get_typename() +
"[" + std::to_string(size) +
"]";
157 vector<Type *> ArrayType::children()
const {
return {_element_type}; }
159 StringType::StringType() { _type_name =
"str"; }
163 _type_name = decl->get_name();
164 _member_types = decl->get_member_types();
167 int StructType::get_align_bits() {
169 for (
auto *t : _member_types) {
170 ret = std::max(t->get_align_bits(), ret);
176 int StructType::get_size_bits() {
181 void StructType::append_member_type(
Type *t) { _member_types.push_back(t); }
182 Type *&StructType::operator[](
size_t index) {
return _member_types[index]; }
183 Type *StructType::operator[](
size_t index)
const {
return _member_types[index]; }
184 vector<Type *> StructType::children()
const {
return _member_types; }
185 vector<Type *> StructType::get_member_types()
const {
return _member_types; }
186 StructDecl *StructType::get_decl()
const {
return _decl; }
188 TypeRef::TypeRef(
const str &name) { _type_name = name; }
190 FunctionType::FunctionType(
Type *ret_type,
const vector<Type *> &arg_types) {
191 _ret_type = ret_type;
192 _arg_types = arg_types;
195 Type *FunctionType::get_return_type()
const {
return _ret_type; }
197 vector<Type *> FunctionType::get_arg_types()
const {
return _arg_types; }
199 void FunctionType::set_arg_types(
const vector<Type *> &arg_types) { _arg_types = arg_types; }
201 void FunctionType::set_return_type(
Type *t) { _ret_type = t; }
203 vector<Type *> FunctionType::children()
const {
204 vector<Type *> ret{_ret_type};
205 ret.insert(ret.begin(), _arg_types.begin(), _arg_types.end());
210 std::queue<Type const *> q{};
211 std::unordered_set<Type const *> s{};
214 umap<Type *, bool> met_pointer{};
216 auto *t = (
Type *)q.front();
220 if (!t || t->is_ref()) {
222 }
else if (t->is_array() || t->is_pointer() || t->is_function()) {
224 met_pointer[t] =
true;
226 auto children = t->children();
227 for (
auto *c : children) {
228 met_pointer[c] = met_pointer[t];
232 }
else if (!s.contains(c))
235 }
else if (t->is_struct()) {
236 auto children = t->children();
237 for (
auto *c : children) {
241 met_pointer[c] = met_pointer[t];
243 if (!s.contains(c)) {
245 }
else if (c->is_struct() && !met_pointer[t]) {
246 Error err(fmt::format(
"Recursive type reference to {} without using a pointer", c->get_typename()));
257 bool Type::is_primitive()
const {
return false; }
258 bool Type::is_pointer()
const {
return false; }
259 bool Type::is_array()
const {
return false; }
260 bool Type::is_string()
const {
return false; }
261 bool Type::is_struct()
const {
return false; }
262 bool Type::is_function()
const {
return false; }
263 bool Type::is_ref()
const {
return false; }
264 bool Type::is_float()
const {
return false; }
265 bool Type::is_int()
const {
return false; }
266 bool Type::is_num()
const {
return false; }
267 bool Type::is_unsigned()
const {
return false; }
268 bool Type::is_bool()
const {
return false; }
269 bool Type::is_void()
const {
return false; }
270 bool Type::is_char()
const {
return false; }
Placeholder during parsing.
Type is immutable once created. The exception is StructType. Its information is updated in multiple s...
static bool IsCanonical(const Type &type)
A composite type is canonical only if its subtype(s) are also canonical. A non-composite type is cano...