Browse Source

Allow string literals for `[N]byte`

gingerBill 4 years ago
parent
commit
6416a6f39c
6 changed files with 34 additions and 7 deletions
  1. 6 0
      src/check_expr.cpp
  2. 3 1
      src/ir.cpp
  3. 7 3
      src/ir_print.cpp
  4. 9 1
      src/llvm_backend.cpp
  5. 2 2
      src/parser.hpp
  6. 7 0
      src/types.cpp

+ 6 - 0
src/check_expr.cpp

@@ -2955,6 +2955,12 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) {
 		if (check_is_assignable_to(c, operand, elem)) {
 			operand->mode = Addressing_Value;
 		} else {
+			if (operand->value.kind == ExactValue_String && is_type_u8_array(t)) {
+				String s = operand->value.value_string;
+				if (s.len == t->Array.count) {
+					break;
+				}
+			}
 			operand->mode = Addressing_Invalid;
 			convert_untyped_error(c, operand, target_type);
 			return;

+ 3 - 1
src/ir.cpp

@@ -7801,7 +7801,9 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
 
 	if (tv.value.kind != ExactValue_Invalid) {
 		// NOTE(bill): Edge case
-		if (tv.value.kind != ExactValue_Compound &&
+	    	if (is_type_u8_array(tv.type) && tv.value.kind == ExactValue_String) {
+	    		return ir_add_module_constant(proc->module, tv.type, tv.value);
+	    	} else if (tv.value.kind != ExactValue_Compound &&
 		    is_type_array(tv.type)) {
 			Type *elem = core_array_type(tv.type);
 			ExactValue value = convert_exact_value_for_type(tv.value, elem);

+ 7 - 3
src/ir_print.cpp

@@ -745,7 +745,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
 
 		ir_write_byte(f, ']');
 		return;
-	} else if (is_type_array(type) &&
+	}  else if (is_type_array(type) &&
 	    value.kind != ExactValue_Invalid &&
 	    value.kind != ExactValue_String &&
 	    value.kind != ExactValue_Compound) {
@@ -796,7 +796,11 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
 			GB_ASSERT(is_type_array(type));
 			ir_write_str_lit(f, "c\"");
 			ir_print_escape_string(f, str, false, false);
-			ir_write_str_lit(f, "\\00\"");
+			if (type->Array.count == str.len) {
+				ir_write_str_lit(f, "\"");
+			} else {
+				ir_write_str_lit(f, "\\00\"");
+			}
 		} else if (is_type_cstring(t)) {
 			// HACK NOTE(bill): This is a hack but it works because strings are created at the very end
 			// of the .ll file
@@ -810,7 +814,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
 			ir_write_str_lit(f, ", ");
 			ir_print_type(f, m, t_i32);
 			ir_write_str_lit(f, " 0, i32 0)");
-		}else {
+		} else {
 			// HACK NOTE(bill): This is a hack but it works because strings are created at the very end
 			// of the .ll file
 			irValue *str_array = ir_add_global_string_array(m, str);

+ 9 - 1
src/llvm_backend.cpp

@@ -5126,7 +5126,15 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
 		LLVMValueRef data = LLVMConstStringInContext(ctx,
 			cast(char const *)value.value_string.text,
 			cast(unsigned)value.value_string.len,
-			false);
+			false /*DontNullTerminate*/);
+		res.value = data;
+		return res;
+	} else if (is_type_u8_array(type) && value.kind == ExactValue_String) {
+		GB_ASSERT(type->Array.count == value.value_string.len);
+		LLVMValueRef data = LLVMConstStringInContext(ctx,
+			cast(char const *)value.value_string.text,
+			cast(unsigned)value.value_string.len,
+			true /*DontNullTerminate*/);
 		res.value = data;
 		return res;
 	} else if (is_type_array(type) &&

+ 2 - 2
src/parser.hpp

@@ -646,7 +646,7 @@ struct AstCommonStuff {
 	u16          viral_state_flags;
 	AstFile *    file;
 	Scope *      scope;
-	TypeAndValue tav;
+	TypeAndValue tav; // TODO(bill): Make this a pointer to minimize pointer size
 };
 
 struct Ast {
@@ -655,7 +655,7 @@ struct Ast {
 	u16          viral_state_flags;
 	AstFile *    file;
 	Scope *      scope;
-	TypeAndValue tav;
+	TypeAndValue tav; // TODO(bill): Make this a pointer to minimize pointer size
 
 	// IMPORTANT NOTE(bill): This must be at the end since the AST is allocated to be size of the variant
 	union {

+ 7 - 0
src/types.cpp

@@ -1221,6 +1221,13 @@ bool is_type_u8_slice(Type *t) {
 	}
 	return false;
 }
+bool is_type_u8_array(Type *t) {
+	t = base_type(t);
+	if (t->kind == Type_Array) {
+		return is_type_u8(t->Array.elem);
+	}
+	return false;
+}
 bool is_type_u8_ptr(Type *t) {
 	t = base_type(t);
 	if (t->kind == Type_Pointer) {