Browse Source

Add `intrinsics.type_is_endian_platform`

gingerBill 4 years ago
parent
commit
abe728dbbb
4 changed files with 24 additions and 16 deletions
  1. 1 0
      core/intrinsics/intrinsics.odin
  2. 2 0
      src/check_builtin.cpp
  3. 2 0
      src/checker_builtin_procs.hpp
  4. 19 16
      src/types.cpp

+ 1 - 0
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 ---

+ 2 - 0
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:

+ 2 - 0
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},

+ 19 - 16
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;
 }