aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2020-11-20 16:01:59 +0000
committergingerBill <bill@gingerbill.org>2020-11-20 16:01:59 +0000
commit6416a6f39cce4c65c80e29bb4ff4b93a3e463947 (patch)
tree2bf6668068ab0516998fb6bde144a3d4a69bac9e /src
parent87956676f52a56db98e263d1074b490b71141f0b (diff)
Allow string literals for `[N]byte`
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.cpp6
-rw-r--r--src/ir.cpp4
-rw-r--r--src/ir_print.cpp10
-rw-r--r--src/llvm_backend.cpp10
-rw-r--r--src/parser.hpp4
-rw-r--r--src/types.cpp7
6 files changed, 34 insertions, 7 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index aa3d67dae..f258253f5 100644
--- a/src/check_expr.cpp
+++ b/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;
diff --git a/src/ir.cpp b/src/ir.cpp
index 819442030..e8378bb97 100644
--- a/src/ir.cpp
+++ b/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);
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index 0605058ee..3ca9954ef 100644
--- a/src/ir_print.cpp
+++ b/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);
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index ea5081be4..d47c45401 100644
--- a/src/llvm_backend.cpp
+++ b/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) &&
diff --git a/src/parser.hpp b/src/parser.hpp
index aa288304e..cd0d59a48 100644
--- a/src/parser.hpp
+++ b/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 {
diff --git a/src/types.cpp b/src/types.cpp
index 1147beb33..8c39b9979 100644
--- a/src/types.cpp
+++ b/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) {