Add const-ability to types
This commit is contained in:
parent
f9208a525d
commit
8e6980715e
@ -52,7 +52,7 @@ namespace AST {
|
||||
: Expression{ meta }
|
||||
, m_value{ value }
|
||||
, m_ty{ { std::shared_ptr<types::Type>{
|
||||
new types::FundamentalType{types::FundamentalTypeKind::Int}
|
||||
new types::FundamentalType{true, types::FundamentalTypeKind::Int}
|
||||
} } } {
|
||||
}
|
||||
virtual ~IntLiteralExpression() override = default;
|
||||
|
||||
@ -6,11 +6,11 @@ namespace types {
|
||||
std::vector<BinopDefinition> definitions{};
|
||||
|
||||
auto int_ty = std::shared_ptr<types::Type>{
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Int } };
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Int } };
|
||||
auto char_ty = std::shared_ptr<types::Type>{
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Char } };
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Char } };
|
||||
auto bool_ty = std::shared_ptr<types::Type>{
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Bool } };
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
|
||||
|
||||
// Integer arithmetic binops
|
||||
for (auto& ty : { int_ty, char_ty, bool_ty }) {
|
||||
@ -40,7 +40,7 @@ namespace types {
|
||||
},
|
||||
[](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) {
|
||||
return std::shared_ptr<types::Type>{
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Bool } };
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
|
||||
}
|
||||
});
|
||||
|
||||
@ -51,7 +51,7 @@ namespace types {
|
||||
},
|
||||
[](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) {
|
||||
return std::shared_ptr<types::Type>{
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Bool } };
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -65,7 +65,7 @@ namespace types {
|
||||
},
|
||||
[](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) {
|
||||
return std::shared_ptr<types::Type>{
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Bool } };
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
|
||||
}
|
||||
});
|
||||
|
||||
@ -76,7 +76,7 @@ namespace types {
|
||||
},
|
||||
[](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) {
|
||||
return std::shared_ptr<types::Type>{
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Bool } };
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -7,11 +7,11 @@ namespace types {
|
||||
std::vector<CastDefinition> casts{};
|
||||
|
||||
auto int_ty = std::shared_ptr<Type>{
|
||||
new FundamentalType{ FundamentalTypeKind::Int } };
|
||||
new FundamentalType{ false, FundamentalTypeKind::Int } };
|
||||
auto char_ty = std::shared_ptr<Type>{
|
||||
new FundamentalType{ FundamentalTypeKind::Char } };
|
||||
new FundamentalType{ false, FundamentalTypeKind::Char } };
|
||||
auto bool_ty = std::shared_ptr<Type>{
|
||||
new FundamentalType{ FundamentalTypeKind::Bool } };
|
||||
new FundamentalType{ false, FundamentalTypeKind::Bool } };
|
||||
|
||||
auto numerical_types = { int_ty, char_ty, bool_ty };
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ namespace AST {
|
||||
|
||||
std::shared_ptr<types::Type> StringLiteralExpression::get_codegen_type(codegen::Scope&) {
|
||||
auto stack_type = new types::ArrayType{
|
||||
std::make_unique<types::FundamentalType>(types::FundamentalTypeKind::Char),
|
||||
std::make_shared<types::FundamentalType>(true, types::FundamentalTypeKind::Char),
|
||||
static_cast<uint32_t>(this->m_value.size()) + 1,
|
||||
true
|
||||
};
|
||||
@ -40,7 +40,7 @@ namespace AST {
|
||||
|
||||
codegen::StackValue StringLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
||||
auto stack_type = new types::ArrayType{
|
||||
std::make_unique<types::FundamentalType>(types::FundamentalTypeKind::Char),
|
||||
std::make_shared<types::FundamentalType>(true, types::FundamentalTypeKind::Char),
|
||||
static_cast<uint32_t>(this->m_value.size()) + 1,
|
||||
true
|
||||
};
|
||||
@ -52,7 +52,7 @@ namespace AST {
|
||||
return codegen::StackValue{
|
||||
global_str,
|
||||
std::unique_ptr<types::Type>{
|
||||
new types::PointerType { std::shared_ptr<types::Type> {stack_type } }
|
||||
new types::PointerType { false, std::shared_ptr<types::Type> {stack_type } }
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -205,7 +205,7 @@ namespace AST {
|
||||
|
||||
std::shared_ptr<types::Type> RefExpression::get_codegen_type(codegen::Scope& scope) {
|
||||
return std::shared_ptr<types::Type> {
|
||||
new types::PointerType{ this->m_expr->get_codegen_type(scope) }
|
||||
new types::PointerType{ false, this->m_expr->get_codegen_type(scope) }
|
||||
};
|
||||
}
|
||||
|
||||
@ -283,7 +283,7 @@ namespace AST {
|
||||
auto gep_value = builder.builder->CreateGEP(array_ty->m_inner->codegen(builder, scope.structs), value.value, idx_list, "GEP");
|
||||
|
||||
auto ptr_ty = std::shared_ptr<types::Type>{
|
||||
new types::PointerType { array_ty->m_inner}
|
||||
new types::PointerType { array_ty->m_inner->m_const, array_ty->m_inner}
|
||||
};
|
||||
|
||||
if (scope.is_lvalue) {
|
||||
@ -347,7 +347,7 @@ namespace AST {
|
||||
ptr_ty->m_inner->codegen(builder, scope.structs), struct_ptr.value, idx);
|
||||
|
||||
auto ptr_ty = std::shared_ptr<types::Type>{
|
||||
new types::PointerType { field_ty }
|
||||
new types::PointerType { field_ty->m_const, field_ty }
|
||||
};
|
||||
|
||||
if (scope.is_lvalue) {
|
||||
@ -392,7 +392,7 @@ namespace AST {
|
||||
}
|
||||
|
||||
auto ptr_ty = std::shared_ptr<types::Type>{
|
||||
new types::PointerType{this->m_ty}
|
||||
new types::PointerType{this->m_ty->m_const, this->m_ty}
|
||||
};
|
||||
|
||||
if (scope.is_lvalue) {
|
||||
@ -416,7 +416,7 @@ namespace AST {
|
||||
}
|
||||
|
||||
auto ptr_ty = std::shared_ptr<types::Type>{
|
||||
new types::PointerType{this->m_ty}
|
||||
new types::PointerType{this->m_ty->m_const, this->m_ty}
|
||||
};
|
||||
|
||||
if (scope.is_lvalue) {
|
||||
@ -481,7 +481,9 @@ namespace AST {
|
||||
builder.builder->CreateStore(value.value, ptr, false);
|
||||
}
|
||||
|
||||
auto ptr_ty = std::shared_ptr<types::Type>{ new types::PointerType{ this->m_type } };
|
||||
auto ptr_ty = std::shared_ptr<types::Type>{
|
||||
new types::PointerType{ this->m_type->m_const, this->m_type }
|
||||
};
|
||||
|
||||
scope.values[this->m_name] = codegen::StackValue{ ptr, ptr_ty };
|
||||
}
|
||||
@ -530,7 +532,9 @@ namespace AST {
|
||||
param_ty_ptrs.push_back(param.second);
|
||||
}
|
||||
|
||||
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_ptr = std::shared_ptr<types::Type>{
|
||||
new types::FunctionType{ true, ret_ty_ptr, param_ty_ptrs, this->m_is_vararg }
|
||||
};
|
||||
|
||||
auto fn_ty = fn_ty_ptr->codegen(builder, scope.structs);
|
||||
auto function = llvm::Function::Create(
|
||||
@ -568,7 +572,7 @@ namespace AST {
|
||||
builder.builder->SetInsertPoint(BB);
|
||||
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]}
|
||||
new types::PointerType { true, param_ty_ptrs[counter]}
|
||||
};
|
||||
auto arg = function->getArg(counter++);
|
||||
builder.builder->CreateStore(arg, arg_ptr);
|
||||
|
||||
@ -12,6 +12,11 @@ namespace parsing {
|
||||
Result<std::shared_ptr<types::Type>, std::string> parse_type(token::TokenStream& stream, Scope& scope) {
|
||||
token::TokenStream inner{ stream };
|
||||
try {
|
||||
bool is_const = false;
|
||||
if (inner.peek().type == token::Type::Ident && inner.peek().content == "const") {
|
||||
is_const = true;
|
||||
}
|
||||
|
||||
auto token = inner.expect(token::Type::Ident);
|
||||
|
||||
std::shared_ptr<types::Type> returned{};
|
||||
@ -56,7 +61,14 @@ namespace parsing {
|
||||
if (struct_name && !maybe_fields && scope.structs.find(*struct_name) != scope.structs.end()) {
|
||||
auto original_ty = scope.structs[*struct_name];
|
||||
auto original_struct_ty = dynamic_cast<types::StructType*>(original_ty.get());
|
||||
auto ty = new types::StructType{ struct_name, original_struct_ty->m_fields, true, false, original_struct_ty->m_id };
|
||||
auto ty = new types::StructType{
|
||||
is_const,
|
||||
struct_name,
|
||||
original_struct_ty->m_fields,
|
||||
true,
|
||||
false,
|
||||
original_struct_ty->m_id
|
||||
};
|
||||
returned = std::shared_ptr<types::Type>{ ty };
|
||||
}
|
||||
else {
|
||||
@ -64,16 +76,37 @@ namespace parsing {
|
||||
auto original_ty = scope.structs[*struct_name];
|
||||
auto original_struct_ty = dynamic_cast<types::StructType*>(original_ty.get());
|
||||
if (!original_struct_ty->m_fields.has_value()) {
|
||||
auto ty = new types::StructType{ struct_name, maybe_fields, false, true, original_struct_ty->m_id };
|
||||
auto ty = new types::StructType{
|
||||
is_const,
|
||||
struct_name,
|
||||
maybe_fields,
|
||||
false,
|
||||
true,
|
||||
original_struct_ty->m_id
|
||||
};
|
||||
returned = std::shared_ptr<types::Type>{ ty };
|
||||
}
|
||||
else {
|
||||
auto ty = new types::StructType{ struct_name, maybe_fields, false, false, struct_id_counter++ };
|
||||
auto ty = new types::StructType{
|
||||
is_const,
|
||||
struct_name,
|
||||
maybe_fields,
|
||||
false,
|
||||
false,
|
||||
struct_id_counter++
|
||||
};
|
||||
returned = std::shared_ptr<types::Type>{ ty };
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto ty = new types::StructType{ struct_name, maybe_fields, false, false, struct_id_counter++ };
|
||||
auto ty = new types::StructType{
|
||||
is_const,
|
||||
struct_name,
|
||||
maybe_fields,
|
||||
false,
|
||||
false,
|
||||
struct_id_counter++
|
||||
};
|
||||
returned = std::shared_ptr<types::Type>{ ty };
|
||||
}
|
||||
}
|
||||
@ -83,15 +116,15 @@ namespace parsing {
|
||||
std::string type_name = token.content;
|
||||
|
||||
if (type_name == "int") {
|
||||
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Int };
|
||||
auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::Int };
|
||||
returned = std::shared_ptr<types::Type>{ ty };
|
||||
}
|
||||
else if (type_name == "char") {
|
||||
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Char };
|
||||
auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::Char };
|
||||
returned = std::shared_ptr<types::Type>{ ty };
|
||||
}
|
||||
else if (type_name == "void") {
|
||||
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Void };
|
||||
auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::Void };
|
||||
returned = std::shared_ptr<types::Type>{ ty };
|
||||
}
|
||||
else {
|
||||
@ -101,7 +134,12 @@ namespace parsing {
|
||||
|
||||
while (inner.peek().type == token::Type::Symbol && inner.peek().content == "*") {
|
||||
inner.next();
|
||||
auto ty = new types::PointerType{ std::move(returned) };
|
||||
auto ptr_const = false;
|
||||
if (inner.peek().type == token::Type::Ident && inner.peek().content == "const") {
|
||||
inner.next();
|
||||
ptr_const = true;
|
||||
}
|
||||
auto ty = new types::PointerType{ ptr_const, std::move(returned) };
|
||||
returned = std::shared_ptr<types::Type>{ ty };
|
||||
}
|
||||
|
||||
@ -162,7 +200,7 @@ namespace parsing {
|
||||
before_meta + inner.metadata(),
|
||||
std::move(expressions),
|
||||
std::shared_ptr<types::Type> {
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Any }
|
||||
new types::FundamentalType{ true, types::FundamentalTypeKind::Any }
|
||||
})
|
||||
};
|
||||
}
|
||||
@ -390,16 +428,9 @@ namespace parsing {
|
||||
auto array_postfix = parse_array_postfix(inner, false, scope);
|
||||
while (array_postfix.ok()) {
|
||||
auto postfix = array_postfix.unwrap();
|
||||
if (postfix) {
|
||||
ty = std::shared_ptr<types::Type>{
|
||||
new types::ArrayType(ty, *postfix, false)
|
||||
};
|
||||
}
|
||||
else {
|
||||
ty = std::shared_ptr<types::Type>{
|
||||
new types::PointerType(ty)
|
||||
};
|
||||
}
|
||||
ty = std::shared_ptr<types::Type>{
|
||||
new types::ArrayType(ty, *postfix, false)
|
||||
};
|
||||
array_postfix = parse_array_postfix(inner, false, scope);
|
||||
}
|
||||
|
||||
@ -516,7 +547,7 @@ namespace parsing {
|
||||
}
|
||||
else {
|
||||
param_ty = std::shared_ptr<types::Type>{
|
||||
new types::PointerType(param_ty)
|
||||
new types::PointerType(true, param_ty)
|
||||
};
|
||||
}
|
||||
postfix = parse_array_postfix(inner, true, scope);
|
||||
|
||||
@ -136,7 +136,7 @@ namespace AST {
|
||||
std::optional<std::shared_ptr<types::Type>>
|
||||
) {
|
||||
auto char_ty = std::shared_ptr<types::Type>{
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Char }
|
||||
new types::FundamentalType{ true, types::FundamentalTypeKind::Char }
|
||||
};
|
||||
auto ptr_ty = new types::ArrayType{ char_ty, static_cast<uint32_t>(this->m_value.size()) + 1, true };
|
||||
return { std::shared_ptr<types::Type>{ptr_ty}, true, false };
|
||||
@ -155,7 +155,7 @@ namespace AST {
|
||||
|
||||
state.errors.push_back(CompileError("Value " + this->m_name + " not defined", this->m_meta));
|
||||
return { std::shared_ptr<types::Type>{
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Void }
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
|
||||
}, false, true };
|
||||
}
|
||||
|
||||
@ -255,7 +255,7 @@ namespace AST {
|
||||
this->m_meta));
|
||||
|
||||
return { std::shared_ptr<types::Type>{
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Void } }, false, false };
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Void } }, false, false };
|
||||
}
|
||||
|
||||
void FunctionCallExpression::typecheck_preprocess(typecheck::Scope& scope) {
|
||||
@ -275,7 +275,7 @@ namespace AST {
|
||||
if (expr_ty->m_kind != types::TypeKind::Function) {
|
||||
state.errors.push_back(CompileError("Tried calling a non-function", this->m_meta));
|
||||
return { std::shared_ptr<types::Type> {
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Void }
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
|
||||
}, false, false };
|
||||
}
|
||||
|
||||
@ -324,6 +324,7 @@ namespace AST {
|
||||
+ expr_ty->formatted() + "to type " + this->m_ty->formatted()
|
||||
+ " is not permitted", this->m_meta));
|
||||
return { std::shared_ptr<types::Type> { new types::FundamentalType{
|
||||
false,
|
||||
types::FundamentalTypeKind::Void
|
||||
} }, false, false };
|
||||
}
|
||||
@ -339,7 +340,7 @@ namespace AST {
|
||||
) {
|
||||
auto expr_ty = this->m_expr->typecheck(state, scope, {}).type;
|
||||
return { std::shared_ptr<types::Type> {
|
||||
new types::PointerType{ expr_ty }
|
||||
new types::PointerType{ false, expr_ty }
|
||||
}, false, false };
|
||||
}
|
||||
|
||||
@ -357,7 +358,7 @@ namespace AST {
|
||||
state.errors.push_back(
|
||||
CompileError("Tried to deref " + expr_ty.type->formatted(), this->m_meta));
|
||||
return { std::shared_ptr<types::Type> {
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Void }
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
|
||||
}, false, expr_ty.lvalue };
|
||||
}
|
||||
auto ptr_ty = dynamic_cast<types::PointerType*>(expr_ty.type.get());
|
||||
@ -378,7 +379,7 @@ namespace AST {
|
||||
state.errors.push_back(
|
||||
CompileError("Tried to index " + expr_ty.type->formatted(), this->m_meta));
|
||||
return { std::shared_ptr<types::Type> {
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Void }
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
|
||||
}, false, expr_ty.lvalue };
|
||||
}
|
||||
if (expr_ty.type->m_kind == types::TypeKind::Pointer) {
|
||||
@ -392,7 +393,7 @@ namespace AST {
|
||||
|
||||
// Default return type
|
||||
return { std::shared_ptr<types::Type> {
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Void }
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
|
||||
}, false, expr_ty.lvalue };
|
||||
}
|
||||
|
||||
@ -410,7 +411,7 @@ namespace AST {
|
||||
state.errors.push_back(
|
||||
CompileError("Tried to access " + expr_ty.type->formatted() + "." + this->m_field, this->m_meta));
|
||||
return { std::shared_ptr<types::Type> {
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Void }
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
|
||||
}, false, expr_ty.lvalue };
|
||||
}
|
||||
|
||||
@ -423,13 +424,13 @@ namespace AST {
|
||||
}
|
||||
state.errors.push_back(CompileError("No such field", this->m_meta));
|
||||
return { std::shared_ptr<types::Type> {
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Void }
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
|
||||
}, false, expr_ty.lvalue };
|
||||
}
|
||||
|
||||
state.errors.push_back(CompileError("Cannot access fields of opaque struct", this->m_meta));
|
||||
return { std::shared_ptr<types::Type> {
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Void }
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
|
||||
}, false, expr_ty.lvalue };
|
||||
}
|
||||
|
||||
@ -499,7 +500,7 @@ namespace AST {
|
||||
}
|
||||
else {
|
||||
return { std::shared_ptr<types::Type> {
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Void }
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
|
||||
}, true, false };
|
||||
}
|
||||
|
||||
@ -511,7 +512,7 @@ namespace AST {
|
||||
if (this->m_expressions.size() == 0) {
|
||||
this->m_ty = std::shared_ptr<types::Type>{
|
||||
new types::ArrayType{
|
||||
std::make_shared<types::FundamentalType>(types::FundamentalTypeKind::Void),
|
||||
std::make_shared<types::FundamentalType>(true, types::FundamentalTypeKind::Void),
|
||||
0,
|
||||
true
|
||||
}
|
||||
@ -585,7 +586,7 @@ namespace AST {
|
||||
|
||||
void IfStatement::typecheck(typecheck::State& state, typecheck::Scope& scope) {
|
||||
auto bool_ty = std::shared_ptr<types::Type>{
|
||||
new types::FundamentalType{ types::FundamentalTypeKind::Bool } };
|
||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
|
||||
auto expr_ty = this->m_condition->typecheck(state, scope, bool_ty).type;
|
||||
|
||||
auto check_res = check_type(state, expr_ty, bool_ty);
|
||||
@ -617,7 +618,7 @@ namespace AST {
|
||||
param_tys.push_back(param.second);
|
||||
}
|
||||
|
||||
auto function_ty = new types::FunctionType{ return_ty, param_tys, this->m_is_vararg };
|
||||
auto function_ty = new types::FunctionType{ true, return_ty, param_tys, this->m_is_vararg };
|
||||
scope.symbols[this->m_name] = std::shared_ptr<types::Type>{ function_ty };
|
||||
|
||||
typecheck::Scope inner{ scope };
|
||||
|
||||
35
src/types.h
35
src/types.h
@ -27,7 +27,9 @@ namespace types {
|
||||
class Type {
|
||||
public:
|
||||
TypeKind m_kind;
|
||||
Type(TypeKind kind) : m_kind{ kind } {}
|
||||
bool m_const;
|
||||
|
||||
Type(TypeKind kind, bool is_const) : m_kind{ kind }, m_const{ is_const } {}
|
||||
virtual ~Type() = default;
|
||||
virtual std::string formatted() = 0;
|
||||
virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) = 0;
|
||||
@ -40,7 +42,7 @@ namespace types {
|
||||
class FundamentalType : public Type {
|
||||
public:
|
||||
FundamentalTypeKind m_ty;
|
||||
FundamentalType(FundamentalTypeKind kind) : Type(TypeKind::Fundamental), m_ty{ kind } {}
|
||||
FundamentalType(bool is_const, FundamentalTypeKind kind) : Type(TypeKind::Fundamental, is_const), m_ty{ kind } {}
|
||||
virtual ~FundamentalType() override = default;
|
||||
virtual std::string formatted() override;
|
||||
virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override;
|
||||
@ -55,8 +57,8 @@ namespace types {
|
||||
std::shared_ptr<Type> m_ret_ty;
|
||||
std::vector<std::shared_ptr<Type>> m_param_tys;
|
||||
bool m_vararg;
|
||||
FunctionType(std::shared_ptr<Type> ret_ty, std::vector<std::shared_ptr<Type>> param_tys, bool vararg)
|
||||
: Type(TypeKind::Function)
|
||||
FunctionType(bool is_const, std::shared_ptr<Type> ret_ty, std::vector<std::shared_ptr<Type>> param_tys, bool vararg)
|
||||
: Type(TypeKind::Function, is_const)
|
||||
, m_ret_ty{ std::move(ret_ty) }
|
||||
, m_param_tys{ std::move(param_tys) }
|
||||
, m_vararg{ vararg } {
|
||||
@ -73,8 +75,8 @@ namespace types {
|
||||
public:
|
||||
std::shared_ptr<Type> m_inner;
|
||||
|
||||
PointerType(std::shared_ptr<Type> inner)
|
||||
: Type(TypeKind::Pointer), m_inner{ std::move(inner) } {
|
||||
PointerType(bool is_const, std::shared_ptr<Type> inner)
|
||||
: Type(TypeKind::Pointer, is_const), m_inner{ std::move(inner) } {
|
||||
}
|
||||
virtual ~PointerType() override = default;
|
||||
virtual std::string formatted() override;
|
||||
@ -90,7 +92,7 @@ namespace types {
|
||||
bool m_raw;
|
||||
|
||||
ArrayType(std::shared_ptr<Type> inner, uint32_t size, bool raw)
|
||||
: Type(TypeKind::Array), m_inner{ std::move(inner) }, m_size{ size }, m_raw{ raw } {
|
||||
: Type(TypeKind::Array, true), m_inner{ std::move(inner) }, m_size{ size }, m_raw{ raw } {
|
||||
}
|
||||
virtual ~ArrayType() override = default;
|
||||
virtual std::string formatted() override;
|
||||
@ -109,8 +111,8 @@ namespace types {
|
||||
bool m_is_def;
|
||||
uint32_t m_id;
|
||||
|
||||
StructType(std::optional<std::string> name, std::optional<std::vector<StructField>> fields, bool is_ref, bool is_def, uint32_t id)
|
||||
: Type(TypeKind::Struct), m_name{ name }, m_fields{ fields }, m_is_ref{ is_ref }, m_is_def{ is_def }, m_id{ id } {
|
||||
StructType(bool is_const, std::optional<std::string> name, std::optional<std::vector<StructField>> fields, bool is_ref, bool is_def, uint32_t id)
|
||||
: Type(TypeKind::Struct, is_const), m_name{ name }, m_fields{ fields }, m_is_ref{ is_ref }, m_is_def{ is_def }, m_id{ id } {
|
||||
}
|
||||
virtual ~StructType() override = default;
|
||||
virtual std::string formatted() override;
|
||||
@ -119,21 +121,6 @@ namespace types {
|
||||
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::StructRef), 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;
|
||||
// };
|
||||
|
||||
bool types_equal(std::shared_ptr<types::Type> type1, std::shared_ptr<types::Type> type2);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user