Codegen of enum and error

This commit is contained in:
Christoffer Lerno
2020-04-04 01:28:15 +02:00
parent bb2aa6e27a
commit bbef467317
9 changed files with 43 additions and 44 deletions

View File

@@ -148,6 +148,7 @@ typedef Inf as BooInf;
func void enumInferenceTest()
{
OtherError e = OtherError.FOO_BAR;
Inf x = Inf.A;
x = BooInf.B;
x = A;

View File

@@ -30,8 +30,6 @@ typedef struct _Expr Expr;
typedef struct _Module Module;
typedef struct _Type Type;
typedef bool(*CastFunc)(Expr *, Type *, Type *, Type *, CastType cast_type);
typedef struct _BigInt
{
unsigned digit_count;
@@ -888,14 +886,7 @@ extern Type *type_byte, *type_ushort, *type_uint, *type_ulong, *type_usize;
extern Type *type_compint, *type_compfloat;
extern Type *type_c_short, *type_c_int, *type_c_long, *type_c_longlong;
extern Type *type_c_ushort, *type_c_uint, *type_c_ulong, *type_c_ulonglong;
extern Type t_i8, t_i16, t_i32, t_i64, t_isz, t_ixx;
extern Type t_u1, t_u8, t_u16, t_u32, t_u64, t_usz, t_uxx;
extern Type t_f32, t_f64, t_fxx;
extern Type t_u0, t_str;
extern Type t_cus, t_cui, t_cul, t_cull;
extern Type t_cs, t_ci, t_cl, t_cll;
extern Type t_voidstar;
extern Type *type_typeid, *type_error;
extern const char *main_name;
@@ -1159,7 +1150,7 @@ static inline Type *type_reduced(Type *type)
{
Type *canonical = type->canonical;
if (canonical->type_kind == TYPE_ENUM) return canonical->decl->enums.type_info->type->canonical;
if (canonical->type_kind == TYPE_ERROR) TODO;
if (canonical->type_kind == TYPE_ERROR) return type_error->canonical;
return canonical;
}

View File

@@ -46,7 +46,7 @@ static void gencontext_emit_global_variable_definition(GenContext *context, Decl
}
// TODO fix name
decl->var.backend_ref = LLVMAddGlobal(context->module, decl->type->backend_type, decl->name);
decl->var.backend_ref = LLVMAddGlobal(context->module, llvm_type(decl->type), decl->name);
// If read only: LLVMSetGlobalConstant(decl->var.backend_ref, 1);

View File

@@ -227,7 +227,7 @@ LLVMValueRef gencontext_emit_unary_expr(GenContext *context, Expr *expr)
case UNARYOP_ERROR:
FATAL_ERROR("Illegal unary op %s", expr->unary_expr.operator);
case UNARYOP_NOT:
return LLVMBuildXor(context->builder, gencontext_emit_expr(context, expr->unary_expr.expr), LLVMConstInt(type_bool->backend_type, 1, 0), "not");
return LLVMBuildXor(context->builder, gencontext_emit_expr(context, expr->unary_expr.expr), LLVMConstInt(llvm_type(type_bool), 1, 0), "not");
case UNARYOP_BITNEG:
return LLVMBuildNot(context->builder, gencontext_emit_expr(context, expr->unary_expr.expr), "bnot");
case UNARYOP_NEGMOD:
@@ -286,7 +286,7 @@ static LLVMValueRef gencontext_emit_logical_and_or(GenContext *context, Expr *ex
// Generate phi
gencontext_emit_block(context, phi_block);
LLVMValueRef phi = LLVMBuildPhi(context->builder, type_bool->backend_type, "val");
LLVMValueRef phi = LLVMBuildPhi(context->builder, llvm_type(type_bool), "val");
// Simplify for LLVM by entering the constants we already know of.
LLVMValueRef result_on_skip = LLVMConstInt(LLVMInt1TypeInContext(context->context), op == BINARYOP_AND ? 0 : 1, false);
@@ -616,7 +616,7 @@ LLVMValueRef gencontext_emit_elvis_expr(GenContext *context, Expr *expr)
// Generate phi
gencontext_emit_block(context, phi_block);
LLVMValueRef phi = LLVMBuildPhi(context->builder, expr->type->backend_type, "val");
LLVMValueRef phi = LLVMBuildPhi(context->builder, llvm_type(expr->type), "val");
LLVMValueRef logic_values[2] = { lhs, rhs };
LLVMBasicBlockRef blocks[2] = { current_block, rhs_block };
@@ -649,20 +649,15 @@ LLVMValueRef gencontext_emit_ternary_expr(GenContext *context, Expr *expr)
// Generate phi
gencontext_emit_block(context, phi_block);
LLVMValueRef phi = LLVMBuildPhi(context->builder, expr->type->backend_type, "val");
LLVMValueRef phi = LLVMBuildPhi(context->builder, llvm_type(expr->type), "val");
LLVMValueRef logicValues[2] = { lhs, rhs };
LLVMValueRef logic_values[2] = { lhs, rhs };
LLVMBasicBlockRef blocks[2] = { lhs_block, rhs_block };
LLVMAddIncoming(phi, logicValues, blocks, 2);
LLVMAddIncoming(phi, logic_values, blocks, 2);
return phi;
}
static LLVMValueRef gencontext_emit_identifier_expr(GenContext *context, Expr *expr)
{
return LLVMBuildLoad2(context->builder, expr->identifier_expr.decl->type->canonical->backend_type,
expr->identifier_expr.decl->var.backend_ref, expr->identifier_expr.decl->name);
}
LLVMValueRef gencontext_emit_const_expr(GenContext *context, Expr *expr)
{
@@ -696,8 +691,7 @@ LLVMValueRef gencontext_emit_const_expr(GenContext *context, Expr *expr)
return global_name;
}
case TYPE_ERROR:
// TODO emit as u128? u64?
TODO
return LLVMConstInt(llvm_type(type_error), expr->const_expr.error_constant->error_constant.value, false);
case TYPE_ENUM:
return gencontext_emit_expr(context, expr->const_expr.enum_constant->enum_constant.expr);
default:

View File

@@ -23,7 +23,7 @@ static LLVMValueRef gencontext_emit_decl(GenContext *context, Ast *ast)
{
Decl *decl = ast->declare_stmt;
decl->var.backend_ref = gencontext_emit_alloca(context, llvm_type(decl->type), decl->name);
decl->var.backend_ref = gencontext_emit_alloca(context, llvm_type(type_reduced(decl->type)), decl->name);
// TODO NRVO
// TODO debug info
/*

View File

@@ -155,18 +155,21 @@ LLVMTypeRef llvm_get_type(LLVMContextRef context, Type *type)
{
case TYPE_POISONED:
case TYPE_META_TYPE:
case TYPE_ENUM:
case TYPE_ERROR:
UNREACHABLE;
case TYPE_TYPEDEF:
return type->backend_type = llvm_get_type(context, type->canonical);
case TYPE_ERROR_UNION:
{
LLVMTypeRef types[2];
types[0] = llvm_get_type(context, type_typeid->canonical);
types[1] = llvm_get_type(context, type_error->canonical);
return type->backend_type = LLVMStructType(types, 2, false);
}
case TYPE_STRUCT:
case TYPE_UNION:
case TYPE_ERROR_UNION:
return type->backend_type = llvm_type_from_decl(context, type->decl);
case TYPE_ENUM:
return type->backend_type = llvm_get_type(context, type->decl->enums.type_info->type);
case TYPE_ERROR:
// TODO: u128? u64?
TODO
case TYPE_FUNC:
return type->backend_type = llvm_func_type(context, type);
case TYPE_VOID:

View File

@@ -31,7 +31,7 @@ static inline bool sema_analyse_error(Context *context __unused, Decl *decl)
break;
}
}
constant->error_constant.value = i;
constant->error_constant.value = i + 1;
constant->resolve_status = RESOLVE_DONE;
}
return success;

View File

@@ -144,7 +144,7 @@ static inline bool sema_expr_analyse_error_constant(Expr *expr, const char *name
expr->type = decl->type;
expr->expr_kind = EXPR_CONST;
expr->const_expr.kind = TYPE_ERROR;
expr->const_expr.error_constant = decl;
expr->const_expr.error_constant = error_constant;
return true;
}
}

View File

@@ -4,22 +4,29 @@
#include "compiler_internal.h"
Type *type_bool, *type_void, *type_string, *type_voidptr;
Type *type_float, *type_double;
static Type t_u0, t_str, t_u1, t_i8, t_i16, t_i32, t_i64, t_ixx;
static Type t_u8, t_u16, t_u32, t_u64;
static Type t_f32, t_f64, t_fxx;
static Type t_usz, t_isz;
static Type t_cus, t_cui, t_cul, t_cull;
static Type t_cs, t_ci, t_cl, t_cll;
static Type t_voidstar, t_typeid;
static Type t_err;
Type *type_bool = &t_u1;
Type *type_void = &t_u0;
Type *type_string = &t_str;
Type *type_voidptr = &t_voidstar;
Type *type_float = &t_f32;
Type *type_double = &t_f64;
Type *type_error = &t_err;
Type *type_typeid = &t_typeid;
Type *type_char, *type_short, *type_int, *type_long, *type_isize;
Type *type_byte, *type_ushort, *type_uint, *type_ulong, *type_usize;
Type *type_compint, *type_compfloat;
Type *type_c_short, *type_c_int, *type_c_long, *type_c_longlong;
Type *type_c_ushort, *type_c_uint, *type_c_ulong, *type_c_ulonglong;
Type t_u0, t_str;
Type t_u1, t_i8, t_i16, t_i32, t_i64, t_ixx;
Type t_u8, t_u16, t_u32, t_u64, t_uxx;
Type t_f32, t_f64, t_fxx;
Type t_usz, t_isz;
Type t_cus, t_cui, t_cul, t_cull;
Type t_cs, t_ci, t_cl, t_cll;
Type t_voidstar;
#define META_OFFSET 0
#define PTR_OFFSET 1
@@ -421,6 +428,9 @@ type_create(#_name, &_shortname, &type_ ## _name, _type, _bits, target->align_mi
type_create_alias("c_short", &t_cs, &type_c_short, type_signed_int_by_bitsize(target->width_c_short));
type_create_alias("c_int", &t_ci, &type_c_int, type_signed_int_by_bitsize(target->width_c_int));
// TODO fix error size
type_create_alias("error", &t_err, &type_error, type_signed_int_by_bitsize(target->width_c_int));
type_create_alias("typeid", &t_typeid, &type_typeid, type_signed_int_by_bitsize(target->width_pointer));
type_create_alias("c_long", &t_cl, &type_c_long, type_signed_int_by_bitsize(target->width_c_long));
type_create_alias("c_longlong", &t_cll, &type_c_longlong, type_signed_int_by_bitsize(target->width_c_long_long));