mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Codegen of enum and error
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
/*
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user