diff --git a/resources/testfragments/super_simple.c3 b/resources/testfragments/super_simple.c3 index 0cab6ecba..a6055f864 100644 --- a/resources/testfragments/super_simple.c3 +++ b/resources/testfragments/super_simple.c3 @@ -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; diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index ce522c013..76c17a881 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -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; } diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index f638cfc17..aa22ae8d2 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -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); diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 866b95d37..f07715644 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -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: diff --git a/src/compiler/llvm_codegen_stmt.c b/src/compiler/llvm_codegen_stmt.c index 92bcc8310..428e1dde6 100644 --- a/src/compiler/llvm_codegen_stmt.c +++ b/src/compiler/llvm_codegen_stmt.c @@ -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 /* diff --git a/src/compiler/llvm_codegen_type.c b/src/compiler/llvm_codegen_type.c index bab92199c..896d6c0c2 100644 --- a/src/compiler/llvm_codegen_type.c +++ b/src/compiler/llvm_codegen_type.c @@ -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: diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 78450603c..f0f96ec59 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -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; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 0473133b7..fdf5541de 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -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; } } diff --git a/src/compiler/types.c b/src/compiler/types.c index c5cf89e77..97477ec91 100644 --- a/src/compiler/types.c +++ b/src/compiler/types.c @@ -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));