mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fix bug on runtime "nameof" with optional values. Fixed issues with integer to enum casts. 0.2.25. Added enum_by_name.
This commit is contained in:
@@ -9,6 +9,11 @@ fault IteratorResult
|
||||
NO_MORE_ELEMENT
|
||||
}
|
||||
|
||||
fault SearchResult
|
||||
{
|
||||
MISSING
|
||||
}
|
||||
|
||||
fault VarCastResult
|
||||
{
|
||||
TYPE_MISMATCH
|
||||
@@ -92,7 +97,19 @@ macro bitcast(expr, $Type) @builtin
|
||||
var $size = (usize)($sizeof(expr));
|
||||
$assert($size == $Type.sizeof, "Cannot bitcast between types of different size.");
|
||||
$Type x = void;
|
||||
memcpy(&x, &expr, $size, false, $alignof($Type), $alignof(expr));
|
||||
mem::memcpy(&x, &expr, $size, false, $alignof($Type), $alignof(expr));
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require $Type.kind == TypeKind.ENUM `Only enums may be used`
|
||||
**/
|
||||
macro enum_by_name($Type, char[] enum_name) @builtin
|
||||
{
|
||||
typeid x = $Type.typeid;
|
||||
foreach (i, name : x.names)
|
||||
{
|
||||
if (str::compare(name, enum_name)) return ($Type)i;
|
||||
}
|
||||
return SearchResult.MISSING!;
|
||||
}
|
||||
@@ -51,8 +51,6 @@ macro void memset(void* dst, char val, usize bytes, bool $is_volatile = false, u
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
enum AllocationKind
|
||||
{
|
||||
ALLOC,
|
||||
|
||||
@@ -48,6 +48,15 @@ fn ZString tcopy_zstring(char[] s)
|
||||
return (ZString)str;
|
||||
}
|
||||
|
||||
fn bool compare(char[] a, char[] b)
|
||||
{
|
||||
if (a.len != b.len) return false;
|
||||
foreach (i, c : a)
|
||||
{
|
||||
if (c != b[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
fault UnicodeResult
|
||||
{
|
||||
INVALID_UTF8,
|
||||
|
||||
@@ -5576,7 +5576,8 @@ static inline void llvm_emit_builtin_access(GenContext *c, BEValue *be_value, Ex
|
||||
return;
|
||||
case ACCESS_FAULTNAME:
|
||||
{
|
||||
assert(inner->type->canonical->type_kind == TYPE_FAULTTYPE || inner->type->canonical->type_kind == TYPE_ANYERR);
|
||||
Type *inner_type = type_no_fail(inner->type)->canonical;
|
||||
assert(inner_type->type_kind == TYPE_FAULTTYPE || inner_type->type_kind == TYPE_ANYERR);
|
||||
llvm_value_rvalue(c, be_value);
|
||||
LLVMValueRef val = llvm_emit_alloca_aligned(c, type_chars, "faultname_zero");
|
||||
BEValue zero;
|
||||
@@ -5606,12 +5607,13 @@ static inline void llvm_emit_builtin_access(GenContext *c, BEValue *be_value, Ex
|
||||
}
|
||||
case ACCESS_ENUMNAME:
|
||||
{
|
||||
assert(inner->type->canonical->type_kind == TYPE_ENUM);
|
||||
Type *inner_type = type_no_fail(inner->type)->canonical;
|
||||
assert(inner_type->canonical->type_kind == TYPE_ENUM);
|
||||
llvm_value_rvalue(c, be_value);
|
||||
LLVMTypeRef subarray = llvm_get_type(c, type_chars);
|
||||
|
||||
LLVMTypeRef backend = LLVMTypeOf(inner->type->canonical->backend_typeid);
|
||||
LLVMValueRef to_introspect = LLVMBuildIntToPtr(c->builder, inner->type->canonical->backend_typeid,
|
||||
LLVMTypeRef backend = LLVMTypeOf(inner_type->backend_typeid);
|
||||
LLVMValueRef to_introspect = LLVMBuildIntToPtr(c->builder, inner_type->backend_typeid,
|
||||
LLVMPointerType(c->introspect_type, 0), "");
|
||||
LLVMValueRef ptr = LLVMBuildStructGEP2(c->builder, c->introspect_type, to_introspect, INTROSPECT_INDEX_ADDITIONAL, "");
|
||||
LLVMValueRef ptr_to_first = llvm_emit_bitcast(c, ptr, type_get_ptr(type_chars));
|
||||
|
||||
@@ -229,10 +229,19 @@ static bool int_literal_to_int(Expr *expr, Type *canonical, Type *type)
|
||||
/**
|
||||
* Convert from compile time int to any enum
|
||||
*/
|
||||
bool lit_integer_to_enum(Expr *expr, Type *canonical, Type *type)
|
||||
bool integer_to_enum(Expr *expr, Type *canonical, Type *type)
|
||||
{
|
||||
assert(canonical->type_kind == TYPE_ENUM);
|
||||
unsigned max_enums = vec_size(canonical->decl->enums.values);
|
||||
Decl *enum_decl = canonical->decl;
|
||||
if (expr->expr_kind != EXPR_CONST)
|
||||
{
|
||||
REMINDER("Add check for runtime enum conversions");
|
||||
Type *underlying_type = enum_decl->enums.type_info->type->canonical;
|
||||
if (!cast(expr, underlying_type)) return false;
|
||||
expr->type = type;
|
||||
return true;
|
||||
}
|
||||
unsigned max_enums = vec_size(enum_decl->enums.values);
|
||||
Int to_convert = expr->const_expr.ixx;
|
||||
if (int_is_neg(to_convert))
|
||||
{
|
||||
@@ -245,7 +254,7 @@ bool lit_integer_to_enum(Expr *expr, Type *canonical, Type *type)
|
||||
SEMA_ERROR(expr, "This value exceeds the number of enums in %s.", canonical->decl->name);
|
||||
return false;
|
||||
}
|
||||
Decl *decl = canonical->decl->enums.values[to_convert.i.low];
|
||||
Decl *decl = enum_decl->enums.values[to_convert.i.low];
|
||||
expr->const_expr = (ExprConst) {
|
||||
.enum_val = decl,
|
||||
.const_kind = CONST_ENUM
|
||||
@@ -1288,7 +1297,7 @@ static bool cast_inner(Expr *expr, Type *from_type, Type *to, Type *to_type)
|
||||
if (type_is_float(to)) return int_to_float(expr, CAST_SIFP, to, to_type);
|
||||
if (to == type_bool) return integer_to_bool(expr, to_type);
|
||||
if (to->type_kind == TYPE_POINTER) return int_to_pointer(expr, to_type);
|
||||
if (to->type_kind == TYPE_ENUM) return lit_integer_to_enum(expr, to, to_type);
|
||||
if (to->type_kind == TYPE_ENUM) return integer_to_enum(expr, to, to_type);
|
||||
break;
|
||||
case ALL_UNSIGNED_INTS:
|
||||
if (type_is_integer_unsigned(to)) return int_conversion(expr, CAST_UIUI, to, to_type);
|
||||
@@ -1296,7 +1305,7 @@ static bool cast_inner(Expr *expr, Type *from_type, Type *to, Type *to_type)
|
||||
if (type_is_float(to)) return int_to_float(expr, CAST_UIFP, to, to_type);
|
||||
if (to == type_bool) return integer_to_bool(expr, to_type);
|
||||
if (to->type_kind == TYPE_POINTER) return int_to_pointer(expr, to_type);
|
||||
if (to->type_kind == TYPE_ENUM) return lit_integer_to_enum(expr, to, to_type);
|
||||
if (to->type_kind == TYPE_ENUM) return integer_to_enum(expr, to, to_type);
|
||||
break;
|
||||
case ALL_FLOATS:
|
||||
if (type_is_integer(to)) return float_to_integer(expr, to, to_type);
|
||||
|
||||
@@ -65,7 +65,7 @@ void expr_rewrite_to_builtin_access(SemaContext *context, Expr *expr, Expr *pare
|
||||
expr->expr_kind = EXPR_BUILTIN_ACCESS;
|
||||
expr->builtin_access_expr.kind = kind;
|
||||
expr->builtin_access_expr.inner = exprid(parent);
|
||||
expr->type = type;
|
||||
expr->type = type_get_opt_fail(type, IS_FAILABLE(parent));
|
||||
expr->resolve_status = RESOLVE_DONE;
|
||||
}
|
||||
|
||||
@@ -3683,7 +3683,7 @@ CHECK_DEEPER:
|
||||
if (flat_type->type_kind == TYPE_TYPEID)
|
||||
{
|
||||
if (sema_expr_apply_typeid_property(context, expr, parent, kw)) return true;
|
||||
SEMA_ERROR(identifier, "'%s' is not a valid proprty for typeid.", kw);
|
||||
SEMA_ERROR(identifier, "'%s' is not a valid property for typeid.", kw);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.2.24"
|
||||
#define COMPILER_VERSION "0.2.25"
|
||||
Reference in New Issue
Block a user