mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-03 22:28:46 +00:00
Merge branch 'odin-lang:master' into master
This commit is contained in:
@@ -2453,6 +2453,9 @@ bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_type_float(src) && is_type_complex(dst)) {
|
||||
return true;
|
||||
}
|
||||
if (is_type_float(src) && is_type_quaternion(dst)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+42
-6
@@ -2603,11 +2603,18 @@ ExactValue check_decl_attribute_value(CheckerContext *c, Ast *value) {
|
||||
return ev;
|
||||
}
|
||||
|
||||
#define ATTRIBUTE_USER_TAG_NAME "tag"
|
||||
|
||||
|
||||
DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
|
||||
ExactValue ev = check_decl_attribute_value(c, value);
|
||||
|
||||
if (name == "default_calling_convention") {
|
||||
if (name == ATTRIBUTE_USER_TAG_NAME) {
|
||||
if (ev.kind != ExactValue_String) {
|
||||
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||
}
|
||||
return true;
|
||||
} else if (name == "default_calling_convention") {
|
||||
if (ev.kind == ExactValue_String) {
|
||||
auto cc = string_to_calling_convention(ev.value_string);
|
||||
if (cc == ProcCC_Invalid) {
|
||||
@@ -2655,7 +2662,13 @@ DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
|
||||
}
|
||||
|
||||
DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
|
||||
if (name == "test") {
|
||||
if (name == ATTRIBUTE_USER_TAG_NAME) {
|
||||
ExactValue ev = check_decl_attribute_value(c, value);
|
||||
if (ev.kind != ExactValue_String) {
|
||||
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||
}
|
||||
return true;
|
||||
} else if (name == "test") {
|
||||
if (value != nullptr) {
|
||||
error(value, "'%.*s' expects no parameter, or a string literal containing \"file\" or \"package\"", LIT(name));
|
||||
}
|
||||
@@ -2896,7 +2909,12 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
|
||||
DECL_ATTRIBUTE_PROC(var_decl_attribute) {
|
||||
ExactValue ev = check_decl_attribute_value(c, value);
|
||||
|
||||
if (name == "static") {
|
||||
if (name == ATTRIBUTE_USER_TAG_NAME) {
|
||||
if (ev.kind != ExactValue_String) {
|
||||
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||
}
|
||||
return true;
|
||||
} else if (name == "static") {
|
||||
if (value != nullptr) {
|
||||
error(elem, "'static' does not have any parameters");
|
||||
}
|
||||
@@ -3011,7 +3029,13 @@ DECL_ATTRIBUTE_PROC(var_decl_attribute) {
|
||||
}
|
||||
|
||||
DECL_ATTRIBUTE_PROC(const_decl_attribute) {
|
||||
if (name == "private") {
|
||||
if (name == ATTRIBUTE_USER_TAG_NAME) {
|
||||
ExactValue ev = check_decl_attribute_value(c, value);
|
||||
if (ev.kind != ExactValue_String) {
|
||||
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||
}
|
||||
return true;
|
||||
} else if (name == "private") {
|
||||
// NOTE(bill): Handled elsewhere `check_collect_value_decl`
|
||||
return true;
|
||||
}
|
||||
@@ -3019,7 +3043,13 @@ DECL_ATTRIBUTE_PROC(const_decl_attribute) {
|
||||
}
|
||||
|
||||
DECL_ATTRIBUTE_PROC(type_decl_attribute) {
|
||||
if (name == "private") {
|
||||
if (name == ATTRIBUTE_USER_TAG_NAME) {
|
||||
ExactValue ev = check_decl_attribute_value(c, value);
|
||||
if (ev.kind != ExactValue_String) {
|
||||
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||
}
|
||||
return true;
|
||||
} else if (name == "private") {
|
||||
// NOTE(bill): Handled elsewhere `check_collect_value_decl`
|
||||
return true;
|
||||
}
|
||||
@@ -4020,7 +4050,13 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) {
|
||||
}
|
||||
|
||||
DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) {
|
||||
if (name == "force" || name == "require") {
|
||||
if (name == ATTRIBUTE_USER_TAG_NAME) {
|
||||
ExactValue ev = check_decl_attribute_value(c, value);
|
||||
if (ev.kind != ExactValue_String) {
|
||||
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||
}
|
||||
return true;
|
||||
} else if (name == "force" || name == "require") {
|
||||
if (value != nullptr) {
|
||||
error(elem, "Expected no parameter for '%.*s'", LIT(name));
|
||||
} else if (name == "force") {
|
||||
|
||||
+3
-2
@@ -15,7 +15,7 @@ struct OdinDocVersionType {
|
||||
|
||||
#define OdinDocVersionType_Major 0
|
||||
#define OdinDocVersionType_Minor 2
|
||||
#define OdinDocVersionType_Patch 0
|
||||
#define OdinDocVersionType_Patch 1
|
||||
|
||||
struct OdinDocHeaderBase {
|
||||
u8 magic[8];
|
||||
@@ -175,7 +175,8 @@ enum OdinDocEntityFlag : u64 {
|
||||
|
||||
struct OdinDocEntity {
|
||||
OdinDocEntityKind kind;
|
||||
u32 flags;
|
||||
u32 reserved;
|
||||
u64 flags;
|
||||
OdinDocPosition pos;
|
||||
OdinDocString name;
|
||||
OdinDocTypeIndex type;
|
||||
|
||||
@@ -1369,7 +1369,7 @@ lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) {
|
||||
Type *rt = base_type(right.type);
|
||||
if (is_type_pointer(rt)) {
|
||||
right = lb_emit_load(p, right);
|
||||
rt = type_deref(rt);
|
||||
rt = base_type(type_deref(rt));
|
||||
}
|
||||
|
||||
switch (rt->kind) {
|
||||
@@ -1841,7 +1841,6 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
|
||||
return res;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (is_type_union(dst)) {
|
||||
for_array(i, dst->Union.variants) {
|
||||
Type *vt = dst->Union.variants[i];
|
||||
@@ -1852,7 +1851,6 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// NOTE(bill): This has to be done before 'Pointer <-> Pointer' as it's
|
||||
// subtype polymorphism casting
|
||||
|
||||
@@ -1142,7 +1142,7 @@ lbValue lb_emit_union_tag_ptr(lbProcedure *p, lbValue u) {
|
||||
|
||||
LLVMTypeRef uvt = LLVMGetElementType(LLVMTypeOf(u.value));
|
||||
unsigned element_count = LLVMCountStructElementTypes(uvt);
|
||||
GB_ASSERT_MSG(element_count == 2, "element_count=%u (%s) != (%s)", element_count, type_to_string(ut), LLVMPrintTypeToString(uvt));
|
||||
GB_ASSERT_MSG(element_count >= 2, "element_count=%u (%s) != (%s)", element_count, type_to_string(ut), LLVMPrintTypeToString(uvt));
|
||||
|
||||
lbValue tag_ptr = {};
|
||||
tag_ptr.value = LLVMBuildStructGEP(p->builder, u.value, 1, "");
|
||||
@@ -1795,7 +1795,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
|
||||
unsigned block_size = cast(unsigned)type->Union.variant_block_size;
|
||||
|
||||
auto fields = array_make<LLVMTypeRef>(temporary_allocator(), 0, 2);
|
||||
auto fields = array_make<LLVMTypeRef>(temporary_allocator(), 0, 3);
|
||||
if (is_type_union_maybe_pointer(type)) {
|
||||
LLVMTypeRef variant = lb_type(m, type->Union.variants[0]);
|
||||
array_add(&fields, variant);
|
||||
@@ -1804,7 +1804,12 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
LLVMTypeRef tag_type = lb_type(m, union_tag_type(type));
|
||||
array_add(&fields, block_type);
|
||||
array_add(&fields, tag_type);
|
||||
|
||||
i64 used_size = lb_sizeof(block_type) + lb_sizeof(tag_type);
|
||||
i64 padding = size - used_size;
|
||||
if (padding > 0) {
|
||||
LLVMTypeRef padding_type = lb_type_padding_filler(m, padding, align);
|
||||
array_add(&fields, padding_type);
|
||||
}
|
||||
}
|
||||
|
||||
return LLVMStructTypeInContext(ctx, fields.data, cast(unsigned)fields.count, false);
|
||||
|
||||
@@ -1485,7 +1485,14 @@ void lb_build_return_stmt_internal(lbProcedure *p, lbValue const &res) {
|
||||
|
||||
if (return_by_pointer) {
|
||||
if (res.value != nullptr) {
|
||||
LLVMBuildStore(p->builder, res.value, p->return_ptr.addr.value);
|
||||
LLVMValueRef res_val = res.value;
|
||||
i64 sz = type_size_of(res.type);
|
||||
if (LLVMIsALoadInst(res_val) && sz > build_context.word_size) {
|
||||
lbValue ptr = lb_address_from_load_or_generate_local(p, res);
|
||||
lb_mem_copy_non_overlapping(p, p->return_ptr.addr, ptr, lb_const_int(p->module, t_int, sz));
|
||||
} else {
|
||||
LLVMBuildStore(p->builder, res_val, p->return_ptr.addr.value);
|
||||
}
|
||||
} else {
|
||||
LLVMBuildStore(p->builder, LLVMConstNull(p->abi_function_type->ret.type), p->return_ptr.addr.value);
|
||||
}
|
||||
|
||||
@@ -179,32 +179,24 @@ lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t) {
|
||||
GB_ASSERT_MSG(sz == dz, "Invalid transmute conversion: '%s' to '%s'", type_to_string(src_type), type_to_string(t));
|
||||
|
||||
// NOTE(bill): Casting between an integer and a pointer cannot be done through a bitcast
|
||||
if (is_type_uintptr(src) && is_type_pointer(dst)) {
|
||||
if (is_type_uintptr(src) && is_type_internally_pointer_like(dst)) {
|
||||
res.value = LLVMBuildIntToPtr(p->builder, value.value, lb_type(m, t), "");
|
||||
return res;
|
||||
}
|
||||
if (is_type_pointer(src) && is_type_uintptr(dst)) {
|
||||
res.value = LLVMBuildPtrToInt(p->builder, value.value, lb_type(m, t), "");
|
||||
return res;
|
||||
}
|
||||
if (is_type_uintptr(src) && is_type_proc(dst)) {
|
||||
res.value = LLVMBuildIntToPtr(p->builder, value.value, lb_type(m, t), "");
|
||||
return res;
|
||||
}
|
||||
if (is_type_proc(src) && is_type_uintptr(dst)) {
|
||||
if (is_type_internally_pointer_like(src) && is_type_uintptr(dst)) {
|
||||
res.value = LLVMBuildPtrToInt(p->builder, value.value, lb_type(m, t), "");
|
||||
return res;
|
||||
}
|
||||
|
||||
if (is_type_integer(src) && (is_type_pointer(dst) || is_type_cstring(dst))) {
|
||||
if (is_type_integer(src) && is_type_internally_pointer_like(dst)) {
|
||||
res.value = LLVMBuildIntToPtr(p->builder, value.value, lb_type(m, t), "");
|
||||
return res;
|
||||
} else if ((is_type_pointer(src) || is_type_cstring(src)) && is_type_integer(dst)) {
|
||||
} else if (is_type_internally_pointer_like(src) && is_type_integer(dst)) {
|
||||
res.value = LLVMBuildPtrToInt(p->builder, value.value, lb_type(m, t), "");
|
||||
return res;
|
||||
}
|
||||
|
||||
if (is_type_pointer(src) && is_type_pointer(dst)) {
|
||||
if (is_type_internally_pointer_like(src) && is_type_internally_pointer_like(dst)) {
|
||||
res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(p->module, t), "");
|
||||
return res;
|
||||
}
|
||||
|
||||
+7
-5
@@ -28,11 +28,13 @@ struct PtrMap {
|
||||
|
||||
u32 ptr_map_hash_key(uintptr key) {
|
||||
#if defined(GB_ARCH_64_BIT)
|
||||
u64 x = (u64)key;
|
||||
u8 count = (u8)(x >> 59);
|
||||
x ^= x >> (5 + count);
|
||||
x *= 12605985483714917081ull;
|
||||
return (u32)(x ^ (x >> 43));
|
||||
key = (~key) + (key << 21);
|
||||
key = key ^ (key >> 24);
|
||||
key = (key + (key << 3)) + (key << 8);
|
||||
key = key ^ (key >> 14);
|
||||
key = (key + (key << 2)) + (key << 4);
|
||||
key = key ^ (key << 28);
|
||||
return cast(u32)key;
|
||||
#elif defined(GB_ARCH_32_BIT)
|
||||
u32 state = ((u32)key) * 747796405u + 2891336453u;
|
||||
u32 word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
|
||||
|
||||
+12
-1
@@ -697,6 +697,7 @@ Type * bit_set_to_int(Type *t);
|
||||
bool are_types_identical(Type *x, Type *y);
|
||||
|
||||
bool is_type_pointer(Type *t);
|
||||
bool is_type_proc(Type *t);
|
||||
bool is_type_slice(Type *t);
|
||||
bool is_type_integer(Type *t);
|
||||
bool type_set_offsets(Type *t);
|
||||
@@ -1284,6 +1285,10 @@ bool is_type_multi_pointer(Type *t) {
|
||||
t = base_type(t);
|
||||
return t->kind == Type_MultiPointer;
|
||||
}
|
||||
bool is_type_internally_pointer_like(Type *t) {
|
||||
return is_type_pointer(t) || is_type_multi_pointer(t) || is_type_cstring(t) || is_type_proc(t);
|
||||
}
|
||||
|
||||
bool is_type_tuple(Type *t) {
|
||||
t = base_type(t);
|
||||
return t->kind == Type_Tuple;
|
||||
@@ -4019,7 +4024,13 @@ gbString write_type_to_string(gbString str, Type *type) {
|
||||
|
||||
case Type_BitSet:
|
||||
str = gb_string_appendc(str, "bit_set[");
|
||||
str = write_type_to_string(str, type->BitSet.elem);
|
||||
if (is_type_enum(type->BitSet.elem)) {
|
||||
str = write_type_to_string(str, type->BitSet.elem);
|
||||
} else {
|
||||
str = gb_string_append_fmt(str, "%lld", type->BitSet.lower);
|
||||
str = gb_string_append_fmt(str, "..=");
|
||||
str = gb_string_append_fmt(str, "%lld", type->BitSet.upper);
|
||||
}
|
||||
if (type->BitSet.underlying != nullptr) {
|
||||
str = gb_string_appendc(str, "; ");
|
||||
str = write_type_to_string(str, type->BitSet.underlying);
|
||||
|
||||
Reference in New Issue
Block a user