Add Struct and StructRef-types
This commit is contained in:
parent
5fc58ea1c5
commit
bca18b4f1b
@ -1,6 +1,8 @@
|
||||
#ifndef BUILDER_H
|
||||
#define BUILDER_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <llvm/IR/LLVMContext.h>
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
|
||||
@ -11,6 +13,8 @@ namespace codegen {
|
||||
std::unique_ptr<llvm::IRBuilder<>> builder;
|
||||
llvm::BasicBlock* block;
|
||||
};
|
||||
|
||||
typedef std::map<std::string, llvm::Type*> TypeMap;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -32,13 +32,15 @@ namespace types {
|
||||
if (target_ty->is_signed()) {
|
||||
casts.push_back(CastDefinition{ source_ty, target_ty, allow_implicit,
|
||||
[](codegen::Builder& builder, std::shared_ptr<Type> target, llvm::Value* value) {
|
||||
return builder.builder->CreateSExtOrTrunc(value, target->codegen(builder), "cast");
|
||||
codegen::TypeMap empty {};
|
||||
return builder.builder->CreateSExtOrTrunc(value, target->codegen(builder, empty), "cast");
|
||||
} });
|
||||
}
|
||||
else {
|
||||
casts.push_back(CastDefinition{ source_ty, target_ty, allow_implicit,
|
||||
[](codegen::Builder& builder, std::shared_ptr<Type> target, llvm::Value* value) {
|
||||
return builder.builder->CreateZExtOrTrunc(value, target->codegen(builder), "cast");
|
||||
codegen::TypeMap empty {};
|
||||
return builder.builder->CreateZExtOrTrunc(value, target->codegen(builder, empty), "cast");
|
||||
} });
|
||||
}
|
||||
}
|
||||
@ -60,14 +62,6 @@ namespace types {
|
||||
return {};
|
||||
return CastDefinition{ casted_ty, target_ty, true,
|
||||
[](codegen::Builder&, std::shared_ptr<Type>, llvm::Value* value) {
|
||||
// auto ptr_ty = dynamic_cast<types::PointerType*>(target.get());
|
||||
|
||||
// std::vector<llvm::Value*> indices {};
|
||||
// indices.push_back(llvm::ConstantInt::get(
|
||||
// builder.builder->getInt32Ty(),
|
||||
// 0
|
||||
// ));
|
||||
// return builder.builder->CreateGEP(ptr_ty->m_inner->codegen(builder), value, indices, "arraydecay");
|
||||
return value;
|
||||
} };
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
|
||||
namespace codegen {
|
||||
Scope Scope::with_lvalue() {
|
||||
return Scope{ this->binops, this->casts, this->values, true };
|
||||
return Scope{ this->binops, this->casts, this->structs, this->values, true };
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,8 +20,8 @@ namespace AST {
|
||||
return this->m_ty;
|
||||
}
|
||||
|
||||
codegen::StackValue IntLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope&) {
|
||||
auto ty = this->m_ty->codegen(builder);
|
||||
codegen::StackValue IntLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
||||
auto ty = this->m_ty->codegen(builder, scope.structs);
|
||||
|
||||
return codegen::StackValue{
|
||||
llvm::ConstantInt::get(ty, this->m_value),
|
||||
@ -56,7 +56,7 @@ namespace AST {
|
||||
}
|
||||
else {
|
||||
return codegen::StackValue{
|
||||
builder.builder->CreateLoad(stack_type->codegen(builder), global_str, "literal"),
|
||||
builder.builder->CreateLoad(stack_type->codegen(builder, scope.structs), global_str, "literal"),
|
||||
std::unique_ptr<types::Type>{stack_type},
|
||||
};
|
||||
}
|
||||
@ -83,7 +83,7 @@ namespace AST {
|
||||
return value->second;
|
||||
}
|
||||
else {
|
||||
auto loaded = value->second.ty->load(builder, value->second.value);
|
||||
auto loaded = value->second.ty->load(builder, value->second.value, scope.structs);
|
||||
return codegen::StackValue{
|
||||
loaded.first,
|
||||
loaded.second
|
||||
@ -160,7 +160,7 @@ namespace AST {
|
||||
}
|
||||
auto function = this->m_fn_expr->codegen(builder, scope);
|
||||
|
||||
auto value = builder.builder->CreateCall(llvm::dyn_cast<llvm::FunctionType>(function.ty->codegen(builder)), function.value, args, "call");
|
||||
auto value = builder.builder->CreateCall(llvm::dyn_cast<llvm::FunctionType>(function.ty->codegen(builder, scope.structs)), function.value, args, "call");
|
||||
return codegen::StackValue{
|
||||
value,
|
||||
*function.ty->return_type(),
|
||||
@ -226,7 +226,7 @@ namespace AST {
|
||||
codegen::StackValue DerefExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
||||
auto value = this->m_expr->codegen(builder, scope);
|
||||
if (value.ty->m_kind == types::TypeKind::Pointer) {
|
||||
auto loaded = value.ty->load(builder, value.value);
|
||||
auto loaded = value.ty->load(builder, value.value, scope.structs);
|
||||
return codegen::StackValue{
|
||||
loaded.first,
|
||||
loaded.second
|
||||
@ -267,7 +267,7 @@ namespace AST {
|
||||
if (ptr_ty->m_inner->m_kind == types::TypeKind::Pointer) {
|
||||
auto inner_ptr_ty = dynamic_cast<types::PointerType*>(ptr_ty->m_inner.get());
|
||||
|
||||
auto gep_value = builder.builder->CreateGEP(inner_ptr_ty->m_inner->codegen(builder), value.value, idx_list, "GEP");
|
||||
auto gep_value = builder.builder->CreateGEP(inner_ptr_ty->m_inner->codegen(builder, scope.structs), value.value, idx_list, "GEP");
|
||||
if (scope.is_lvalue) {
|
||||
return codegen::StackValue{
|
||||
gep_value,
|
||||
@ -275,7 +275,7 @@ namespace AST {
|
||||
};
|
||||
}
|
||||
else {
|
||||
auto loaded = value.ty->load(builder, gep_value);
|
||||
auto loaded = value.ty->load(builder, gep_value, scope.structs);
|
||||
return codegen::StackValue{
|
||||
loaded.first,
|
||||
loaded.second
|
||||
@ -287,7 +287,7 @@ namespace AST {
|
||||
|
||||
// Must be an array otherwise
|
||||
auto arr_ty = dynamic_cast<types::ArrayType*>(ptr_ty->m_inner.get());
|
||||
auto gep_value = builder.builder->CreateGEP(arr_ty->m_inner->codegen(builder), value.value, idx_list, "GEP");
|
||||
auto gep_value = builder.builder->CreateGEP(arr_ty->m_inner->codegen(builder, scope.structs), value.value, idx_list, "GEP");
|
||||
if (scope.is_lvalue) {
|
||||
return codegen::StackValue{
|
||||
gep_value,
|
||||
@ -296,7 +296,7 @@ namespace AST {
|
||||
}
|
||||
else {
|
||||
auto inner_ptr_ty = types::PointerType{ arr_ty->m_inner };
|
||||
auto loaded = inner_ptr_ty.load(builder, gep_value);
|
||||
auto loaded = inner_ptr_ty.load(builder, gep_value, scope.structs);
|
||||
return codegen::StackValue{
|
||||
loaded.first,
|
||||
loaded.second
|
||||
@ -304,7 +304,7 @@ namespace AST {
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto gep_value = builder.builder->CreateGEP(ptr_ty->m_inner->codegen(builder), value.value, idx_list, "GEP");
|
||||
auto gep_value = builder.builder->CreateGEP(ptr_ty->m_inner->codegen(builder, scope.structs), value.value, idx_list, "GEP");
|
||||
if (scope.is_lvalue) {
|
||||
return codegen::StackValue{
|
||||
gep_value,
|
||||
@ -312,7 +312,7 @@ namespace AST {
|
||||
};
|
||||
}
|
||||
else {
|
||||
auto loaded = value.ty->load(builder, gep_value);
|
||||
auto loaded = value.ty->load(builder, gep_value, scope.structs);
|
||||
return codegen::StackValue{
|
||||
loaded.first,
|
||||
loaded.second
|
||||
@ -331,7 +331,7 @@ namespace AST {
|
||||
}
|
||||
|
||||
codegen::StackValue ListInitializerExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
||||
auto array_ptr = builder.builder->CreateAlloca(this->m_ty->codegen(builder));
|
||||
auto array_ptr = builder.builder->CreateAlloca(this->m_ty->codegen(builder, scope.structs));
|
||||
|
||||
if (this->m_ty->m_kind == types::TypeKind::Array) {
|
||||
auto array_ty = dynamic_cast<types::ArrayType*>(this->m_ty.get());
|
||||
@ -341,7 +341,7 @@ namespace AST {
|
||||
std::vector<llvm::Value*> indices{};
|
||||
indices.push_back(llvm::ConstantInt::get(builder.builder->getInt32Ty(), counter++));
|
||||
auto gep = builder.builder->CreateGEP(
|
||||
array_ty->m_inner->codegen(builder), array_ptr, indices, "GEP");
|
||||
array_ty->m_inner->codegen(builder, scope.structs), array_ptr, indices, "GEP");
|
||||
builder.builder->CreateStore(expr->codegen(builder, scope).value, gep);
|
||||
}
|
||||
|
||||
@ -353,7 +353,7 @@ namespace AST {
|
||||
return codegen::StackValue{ array_ptr, ptr_ty };
|
||||
}
|
||||
else {
|
||||
auto loaded = ptr_ty->load(builder, array_ptr);
|
||||
auto loaded = ptr_ty->load(builder, array_ptr, scope.structs);
|
||||
return codegen::StackValue{ loaded.first, loaded.second };
|
||||
}
|
||||
}
|
||||
@ -387,7 +387,7 @@ namespace AST {
|
||||
|
||||
builder.builder->SetInsertPoint(builder.block);
|
||||
|
||||
auto ty = this->m_type->codegen(builder);
|
||||
auto ty = this->m_type->codegen(builder, scope.structs);
|
||||
auto ptr = builder.builder->CreateAlloca(ty);
|
||||
if (this->m_expr.has_value()) {
|
||||
auto value = this->m_expr->get()->codegen(builder, scope);
|
||||
@ -445,7 +445,7 @@ namespace AST {
|
||||
|
||||
auto fn_ty_ptr = std::shared_ptr<types::Type>{ new types::FunctionType{ ret_ty_ptr, param_ty_ptrs, this->m_is_vararg } };
|
||||
|
||||
auto fn_ty = fn_ty_ptr->codegen(builder);
|
||||
auto fn_ty = fn_ty_ptr->codegen(builder, scope.structs);
|
||||
auto function = llvm::Function::Create(
|
||||
llvm::dyn_cast<llvm::FunctionType>(fn_ty),
|
||||
llvm::GlobalValue::LinkageTypes::ExternalLinkage,
|
||||
@ -476,7 +476,7 @@ namespace AST {
|
||||
}
|
||||
else {
|
||||
builder.builder->SetInsertPoint(BB);
|
||||
auto arg_ptr = builder.builder->CreateAlloca(param_ty_ptrs[counter]->codegen(builder));
|
||||
auto arg_ptr = builder.builder->CreateAlloca(param_ty_ptrs[counter]->codegen(builder, scope.structs));
|
||||
auto param_ty_ptr = std::shared_ptr<types::Type>{
|
||||
new types::PointerType { param_ty_ptrs[counter]}
|
||||
};
|
||||
@ -506,7 +506,7 @@ namespace AST {
|
||||
}
|
||||
|
||||
namespace types {
|
||||
llvm::Type* FundamentalType::codegen(codegen::Builder& builder) {
|
||||
llvm::Type* FundamentalType::codegen(codegen::Builder& builder, codegen::TypeMap&) {
|
||||
switch (this->m_ty) {
|
||||
case FundamentalTypeKind::Int:
|
||||
return builder.builder->getInt32Ty();
|
||||
@ -521,23 +521,44 @@ namespace types {
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Type* FunctionType::codegen(codegen::Builder& builder) {
|
||||
llvm::Type* FunctionType::codegen(codegen::Builder& builder, codegen::TypeMap& structs) {
|
||||
std::vector<llvm::Type*> params{};
|
||||
|
||||
for (auto& param : this->m_param_tys) {
|
||||
params.push_back(param->codegen(builder));
|
||||
params.push_back(param->codegen(builder, structs));
|
||||
}
|
||||
|
||||
auto ret_ty = this->m_ret_ty->codegen(builder);
|
||||
auto ret_ty = this->m_ret_ty->codegen(builder, structs);
|
||||
|
||||
return llvm::FunctionType::get(ret_ty, params, this->m_vararg);
|
||||
}
|
||||
|
||||
llvm::Type* PointerType::codegen(codegen::Builder& builder) {
|
||||
llvm::Type* PointerType::codegen(codegen::Builder& builder, codegen::TypeMap&) {
|
||||
return llvm::PointerType::get(*builder.context, 0);
|
||||
}
|
||||
|
||||
llvm::Type* ArrayType::codegen(codegen::Builder& builder) {
|
||||
return llvm::ArrayType::get(this->m_inner->codegen(builder), this->m_size);
|
||||
llvm::Type* ArrayType::codegen(codegen::Builder& builder, codegen::TypeMap& structs) {
|
||||
return llvm::ArrayType::get(this->m_inner->codegen(builder, structs), this->m_size);
|
||||
}
|
||||
|
||||
llvm::Type* StructType::codegen(codegen::Builder& builder, codegen::TypeMap& structs) {
|
||||
if (this->m_fields) {
|
||||
std::vector<llvm::Type*> fields{};
|
||||
for (auto& field : *this->m_fields) {
|
||||
fields.push_back(field.second->codegen(builder, structs));
|
||||
}
|
||||
|
||||
auto ty = llvm::StructType::get(*builder.context, fields);
|
||||
if (this->m_name)
|
||||
ty->setName(*this->m_name);
|
||||
return ty;
|
||||
}
|
||||
else {
|
||||
return llvm::StructType::get(*builder.context);
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Type* StructRef::codegen(codegen::Builder&, codegen::TypeMap& structs) {
|
||||
return structs[this->m_name];
|
||||
}
|
||||
}
|
||||
@ -22,7 +22,9 @@ namespace codegen {
|
||||
std::vector<types::BinopDefinition>& binops;
|
||||
std::vector<types::CastDefinition>& casts;
|
||||
|
||||
TypeMap structs;
|
||||
std::map<std::string, StackValue> values;
|
||||
|
||||
bool is_lvalue;
|
||||
|
||||
Scope with_lvalue();
|
||||
|
||||
@ -124,6 +124,7 @@ std::optional<CompileOutput> compile(std::string_view in_filename) {
|
||||
codegen::Scope cg_scope{
|
||||
.binops = typecheck_state.binops,
|
||||
.casts = typecheck_state.casts,
|
||||
.structs = {},
|
||||
.values = {},
|
||||
.is_lvalue = false,
|
||||
};
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "binops.h"
|
||||
#include "builder.h"
|
||||
|
||||
namespace types {
|
||||
int operator_precedence(BinOp& op) {
|
||||
@ -63,7 +64,7 @@ namespace types {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::pair<llvm::Value*, std::shared_ptr<Type>> FundamentalType::load(codegen::Builder&, llvm::Value* ptr) {
|
||||
std::pair<llvm::Value*, std::shared_ptr<Type>> FundamentalType::load(codegen::Builder&, llvm::Value* ptr, codegen::TypeMap&) {
|
||||
auto self = std::make_shared<FundamentalType>(*this);
|
||||
return std::pair(ptr, self);
|
||||
}
|
||||
@ -118,7 +119,7 @@ namespace types {
|
||||
return this->m_ret_ty;
|
||||
}
|
||||
|
||||
std::pair<llvm::Value*, std::shared_ptr<Type>> FunctionType::load(codegen::Builder&, llvm::Value* ptr) {
|
||||
std::pair<llvm::Value*, std::shared_ptr<Type>> FunctionType::load(codegen::Builder&, llvm::Value* ptr, codegen::TypeMap&) {
|
||||
auto self = std::make_shared<FunctionType>(*this);
|
||||
return std::pair(ptr, self);
|
||||
}
|
||||
@ -133,9 +134,9 @@ namespace types {
|
||||
return out.str();
|
||||
}
|
||||
|
||||
std::pair<llvm::Value*, std::shared_ptr<Type>> PointerType::load(codegen::Builder& builder, llvm::Value* ptr) {
|
||||
std::pair<llvm::Value*, std::shared_ptr<Type>> PointerType::load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) {
|
||||
return std::pair(
|
||||
builder.builder->CreateLoad(this->m_inner->codegen(builder), ptr),
|
||||
builder.builder->CreateLoad(this->m_inner->codegen(builder, structs), ptr),
|
||||
this->m_inner
|
||||
);
|
||||
}
|
||||
@ -151,7 +152,7 @@ namespace types {
|
||||
return out.str();
|
||||
}
|
||||
|
||||
std::pair<llvm::Value*, std::shared_ptr<Type>> ArrayType::load(codegen::Builder&, llvm::Value* ptr) {
|
||||
std::pair<llvm::Value*, std::shared_ptr<Type>> ArrayType::load(codegen::Builder&, llvm::Value* ptr, codegen::TypeMap&) {
|
||||
auto self = std::make_shared<ArrayType>(*this);
|
||||
return std::pair(ptr, self);
|
||||
}
|
||||
@ -160,18 +161,59 @@ namespace types {
|
||||
return this->m_size * this->m_inner->size();
|
||||
}
|
||||
|
||||
bool types_equal(std::shared_ptr<types::Type> type1, std::shared_ptr<types::Type> type2) {
|
||||
// if (type1->m_kind == TypeKind::Array && type2->m_kind == TypeKind::Pointer) {
|
||||
// auto ty1 = dynamic_cast<ArrayType*>(type1.get());
|
||||
// auto ty2 = dynamic_cast<PointerType*>(type2.get());
|
||||
// return types_equal(ty1->m_inner, ty2->m_inner);
|
||||
// }
|
||||
// else if (type1->m_kind == TypeKind::Pointer && type2->m_kind == TypeKind::Array) {
|
||||
// auto ty1 = dynamic_cast<PointerType*>(type1.get());
|
||||
// auto ty2 = dynamic_cast<ArrayType*>(type2.get());
|
||||
// return types_equal(ty1->m_inner, ty2->m_inner);
|
||||
// }
|
||||
std::string StructType::formatted() {
|
||||
std::stringstream out{ "" };
|
||||
out << "struct ";
|
||||
if (this->m_name) {
|
||||
out << *this->m_name << " ";
|
||||
}
|
||||
if (this->m_fields) {
|
||||
out << "{ ";
|
||||
int counter = 0;
|
||||
for (auto& field : *this->m_fields) {
|
||||
if (counter++ > 0)
|
||||
out << ", ";
|
||||
out << field.first << ": " << field.second->formatted() << " ";
|
||||
}
|
||||
out << "}";
|
||||
}
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
||||
std::pair<llvm::Value*, std::shared_ptr<Type>> StructType::load(codegen::Builder&, llvm::Value* ptr, codegen::TypeMap&) {
|
||||
auto self = std::make_shared<StructType>(*this);
|
||||
return std::pair(ptr, self);
|
||||
}
|
||||
|
||||
uint32_t StructType::size() {
|
||||
uint32_t size{ 0 };
|
||||
if (this->m_fields) {
|
||||
for (auto& field : *this->m_fields) {
|
||||
size += field.second->size();
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
std::string StructRef::formatted() {
|
||||
std::stringstream out{ "" };
|
||||
out << "struct(ref) " << this->m_name;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
std::pair<llvm::Value*, std::shared_ptr<Type>> StructRef::load(codegen::Builder&, llvm::Value* ptr, codegen::TypeMap&) {
|
||||
auto self = std::make_shared<StructRef>(*this);
|
||||
return std::pair(ptr, self);
|
||||
}
|
||||
|
||||
uint32_t StructRef::size() {
|
||||
return this->m_referred->size();
|
||||
}
|
||||
|
||||
bool types_equal(std::shared_ptr<types::Type> type1, std::shared_ptr<types::Type> type2) {
|
||||
if (type1->m_kind != type2->m_kind)
|
||||
return false;
|
||||
|
||||
|
||||
52
src/types.h
52
src/types.h
@ -29,8 +29,8 @@ namespace types {
|
||||
Type(TypeKind kind) : m_kind{ kind } {}
|
||||
virtual ~Type() = default;
|
||||
virtual std::string formatted() = 0;
|
||||
virtual llvm::Type* codegen(codegen::Builder& builder) = 0;
|
||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) = 0;
|
||||
virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) = 0;
|
||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) = 0;
|
||||
virtual std::optional<std::shared_ptr<Type>> return_type();
|
||||
virtual bool is_signed();
|
||||
virtual uint32_t size() = 0;
|
||||
@ -42,8 +42,8 @@ namespace types {
|
||||
FundamentalType(FundamentalTypeKind kind) : Type(TypeKind::Fundamental), m_ty{ kind } {}
|
||||
virtual ~FundamentalType() override = default;
|
||||
virtual std::string formatted() override;
|
||||
virtual llvm::Type* codegen(codegen::Builder& builder) override;
|
||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) override;
|
||||
virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override;
|
||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override;
|
||||
virtual bool is_signed() override;
|
||||
virtual uint32_t size() override;
|
||||
};
|
||||
@ -62,8 +62,8 @@ namespace types {
|
||||
}
|
||||
virtual ~FunctionType() override = default;
|
||||
virtual std::string formatted() override;
|
||||
virtual llvm::Type* codegen(codegen::Builder& builder) override;
|
||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) override;
|
||||
virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override;
|
||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override;
|
||||
virtual std::optional<std::shared_ptr<Type>> return_type() override;
|
||||
virtual uint32_t size() override;
|
||||
};
|
||||
@ -77,8 +77,8 @@ namespace types {
|
||||
}
|
||||
virtual ~PointerType() override = default;
|
||||
virtual std::string formatted() override;
|
||||
virtual llvm::Type* codegen(codegen::Builder& builder) override;
|
||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) override;
|
||||
virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override;
|
||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override;
|
||||
virtual uint32_t size() override;
|
||||
};
|
||||
|
||||
@ -92,8 +92,40 @@ namespace types {
|
||||
}
|
||||
virtual ~ArrayType() override = default;
|
||||
virtual std::string formatted() override;
|
||||
virtual llvm::Type* codegen(codegen::Builder& builder) override;
|
||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) override;
|
||||
virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override;
|
||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override;
|
||||
virtual uint32_t size() override;
|
||||
};
|
||||
|
||||
typedef std::pair<std::string, std::shared_ptr<types::Type>> StructField;
|
||||
|
||||
class StructType : public Type {
|
||||
public:
|
||||
std::optional<std::string> m_name;
|
||||
std::optional<std::vector<StructField>> m_fields;
|
||||
|
||||
StructType(std::optional<std::string> name, std::optional<std::vector<StructField>> fields)
|
||||
: Type(TypeKind::Array), m_name{ name }, m_fields{ fields } {
|
||||
}
|
||||
virtual ~StructType() override = default;
|
||||
virtual std::string formatted() override;
|
||||
virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override;
|
||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override;
|
||||
virtual uint32_t size() override;
|
||||
};
|
||||
|
||||
class StructRef : public Type {
|
||||
public:
|
||||
std::string m_name;
|
||||
std::shared_ptr<types::Type> m_referred;
|
||||
|
||||
StructRef(std::string name, std::shared_ptr<types::Type> referred)
|
||||
: Type(TypeKind::Array), m_name{ name }, m_referred{ referred } {
|
||||
}
|
||||
virtual ~StructRef() override = default;
|
||||
virtual std::string formatted() override;
|
||||
virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override;
|
||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override;
|
||||
virtual uint32_t size() override;
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user