diff --git a/core/intrinsics/intrinsics.odin b/core/intrinsics/intrinsics.odin index c1d8b0d28..008e2ee5a 100644 --- a/core/intrinsics/intrinsics.odin +++ b/core/intrinsics/intrinsics.odin @@ -136,6 +136,7 @@ type_is_string :: proc($T: typeid) -> bool --- type_is_typeid :: proc($T: typeid) -> bool --- type_is_any :: proc($T: typeid) -> bool --- +type_is_endian_platform :: proc($T: typeid) -> bool --- type_is_endian_little :: proc($T: typeid) -> bool --- type_is_endian_big :: proc($T: typeid) -> bool --- type_is_unsigned :: proc($T: typeid) -> bool --- diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index e023076a1..f08a33fde 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -12,6 +12,7 @@ BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_boolean_end - is_type_string, is_type_typeid, is_type_any, + is_type_endian_platform, is_type_endian_little, is_type_endian_big, is_type_unsigned, @@ -2516,6 +2517,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case BuiltinProc_type_is_string: case BuiltinProc_type_is_typeid: case BuiltinProc_type_is_any: + case BuiltinProc_type_is_endian_platform: case BuiltinProc_type_is_endian_little: case BuiltinProc_type_is_endian_big: case BuiltinProc_type_is_unsigned: diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index 77805c5e9..aa93fbacd 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -166,6 +166,7 @@ BuiltinProc__type_simple_boolean_begin, BuiltinProc_type_is_typeid, BuiltinProc_type_is_any, + BuiltinProc_type_is_endian_platform, BuiltinProc_type_is_endian_little, BuiltinProc_type_is_endian_big, BuiltinProc_type_is_unsigned, @@ -396,6 +397,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("type_is_typeid"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_any"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_is_endian_platform"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_endian_little"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_endian_big"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_unsigned"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, diff --git a/src/types.cpp b/src/types.cpp index f36765641..7f22d0202 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1351,8 +1351,7 @@ bool is_type_union_maybe_pointer_original_alignment(Type *t) { - -bool is_type_integer_endian_big(Type *t) { +bool is_type_endian_big(Type *t) { t = core_type(t); if (t->kind == Type_Basic) { if (t->Basic.flags & BasicFlag_EndianBig) { @@ -1362,15 +1361,13 @@ bool is_type_integer_endian_big(Type *t) { } return build_context.endian_kind == TargetEndian_Big; } else if (t->kind == Type_BitSet) { - return is_type_integer_endian_big(bit_set_to_int(t)); + return is_type_endian_big(bit_set_to_int(t)); } else if (t->kind == Type_Pointer) { - return is_type_integer_endian_big(&basic_types[Basic_uintptr]); + return is_type_endian_big(&basic_types[Basic_uintptr]); } return build_context.endian_kind == TargetEndian_Big; } - - -bool is_type_integer_endian_little(Type *t) { +bool is_type_endian_little(Type *t) { t = core_type(t); if (t->kind == Type_Basic) { if (t->Basic.flags & BasicFlag_EndianLittle) { @@ -1380,17 +1377,23 @@ bool is_type_integer_endian_little(Type *t) { } return build_context.endian_kind == TargetEndian_Little; } else if (t->kind == Type_BitSet) { - return is_type_integer_endian_little(bit_set_to_int(t)); + return is_type_endian_little(bit_set_to_int(t)); } else if (t->kind == Type_Pointer) { - return is_type_integer_endian_little(&basic_types[Basic_uintptr]); + return is_type_endian_little(&basic_types[Basic_uintptr]); } return build_context.endian_kind == TargetEndian_Little; } -bool is_type_endian_big(Type *t) { - return is_type_integer_endian_big(t); -} -bool is_type_endian_little(Type *t) { - return is_type_integer_endian_little(t); + +bool is_type_endian_platform(Type *t) { + t = core_type(t); + if (t->kind == Type_Basic) { + return (t->Basic.flags & (BasicFlag_EndianLittle|BasicFlag_EndianBig)) == 0; + } else if (t->kind == Type_BitSet) { + return is_type_endian_platform(bit_set_to_int(t)); + } else if (t->kind == Type_Pointer) { + return is_type_endian_platform(&basic_types[Basic_uintptr]); + } + return false; } bool types_have_same_internal_endian(Type *a, Type *b) { @@ -1446,9 +1449,9 @@ bool is_type_dereferenceable(Type *t) { bool is_type_different_to_arch_endianness(Type *t) { switch (build_context.endian_kind) { case TargetEndian_Little: - return !is_type_integer_endian_little(t); + return !is_type_endian_little(t); case TargetEndian_Big: - return !is_type_integer_endian_big(t); + return !is_type_endian_big(t); } return false; }