Browse Source

Allow casting between a `bit_field` and its backing type

gingerBill 1 year ago
parent
commit
5f001f6d51
3 changed files with 26 additions and 0 deletions
  1. 1 0
      src/check_decl.cpp
  2. 7 0
      src/check_expr.cpp
  3. 18 0
      src/llvm_backend_expr.cpp

+ 1 - 0
src/check_decl.cpp

@@ -210,6 +210,7 @@ gb_internal bool is_type_distinct(Ast *node) {
 	case Ast_UnionType:
 	case Ast_EnumType:
 	case Ast_ProcType:
+	case Ast_BitFieldType:
 		return true;
 
 	case Ast_PointerType:

+ 7 - 0
src/check_expr.cpp

@@ -2908,6 +2908,13 @@ gb_internal bool check_is_castable_to(CheckerContext *c, Operand *operand, Type
 		}
 	}
 
+	if (is_type_bit_field(src)) {
+		return are_types_identical(core_type(src->BitField.backing_type), dst);
+	}
+	if (is_type_bit_field(dst)) {
+		return are_types_identical(src, core_type(dst->BitField.backing_type));
+	}
+
 	if (is_type_integer(src) && is_type_rune(dst)) {
 		return true;
 	}

+ 18 - 0
src/llvm_backend_expr.cpp

@@ -1946,6 +1946,24 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
 		}
 	}
 
+	// bit_field <-> backing type
+	if (is_type_bit_field(src)) {
+		if (are_types_identical(src->BitField.backing_type, dst)) {
+			lbValue res = {};
+			res.type = t;
+			res.value = value.value;
+			return res;
+		}
+	}
+	if (is_type_bit_field(dst)) {
+		if (are_types_identical(src, dst->BitField.backing_type)) {
+			lbValue res = {};
+			res.type = t;
+			res.value = value.value;
+			return res;
+		}
+	}
+
 
 	// Pointer <-> uintptr
 	if (is_type_pointer(src) && is_type_uintptr(dst)) {