aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_utility.cpp
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2025-08-06 16:09:18 +0100
committerGitHub <noreply@github.com>2025-08-06 16:09:18 +0100
commit09a1e170bc92a0ea48a8ee67599c2936e924fe4d (patch)
tree92b44b34a1f2f0c4a8c96a49ab61bb5177432ed7 /src/llvm_backend_utility.cpp
parentec7509430369eb5d57a081507792dc03b1c05bab (diff)
parentaf3184adc96cef59fff986ea6400caa6dbdb56ae (diff)
Merge pull request #5530 from odin-lang/bill/utf16-strings
UTF-16 string types: `string16` & `cstring16`
Diffstat (limited to 'src/llvm_backend_utility.cpp')
-rw-r--r--src/llvm_backend_utility.cpp48
1 files changed, 47 insertions, 1 deletions
diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp
index 521553147..dcb95a9a2 100644
--- a/src/llvm_backend_utility.cpp
+++ b/src/llvm_backend_utility.cpp
@@ -6,6 +6,7 @@ gb_internal bool lb_is_type_aggregate(Type *t) {
case Type_Basic:
switch (t->Basic.kind) {
case Basic_string:
+ case Basic_string16:
case Basic_any:
return true;
@@ -190,6 +191,23 @@ gb_internal lbValue lb_emit_clamp(lbProcedure *p, Type *t, lbValue x, lbValue mi
return z;
}
+gb_internal lbValue lb_emit_string16(lbProcedure *p, lbValue str_elem, lbValue str_len) {
+ if (false && lb_is_const(str_elem) && lb_is_const(str_len)) {
+ LLVMValueRef values[2] = {
+ str_elem.value,
+ str_len.value,
+ };
+ lbValue res = {};
+ res.type = t_string16;
+ res.value = llvm_const_named_struct(p->module, t_string16, values, gb_count_of(values));
+ return res;
+ } else {
+ lbAddr res = lb_add_local_generated(p, t_string16, false);
+ lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 0), str_elem);
+ lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 1), str_len);
+ return lb_addr_load(p, res);
+ }
+}
gb_internal lbValue lb_emit_string(lbProcedure *p, lbValue str_elem, lbValue str_len) {
@@ -981,7 +999,8 @@ gb_internal i32 lb_convert_struct_index(lbModule *m, Type *t, i32 index) {
} else if (build_context.ptr_size != build_context.int_size) {
switch (t->kind) {
case Type_Basic:
- if (t->Basic.kind != Basic_string) {
+ if (t->Basic.kind != Basic_string &&
+ t->Basic.kind != Basic_string16) {
break;
}
/*fallthrough*/
@@ -1160,6 +1179,11 @@ gb_internal lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
case 0: result_type = alloc_type_pointer(t->Slice.elem); break;
case 1: result_type = t_int; break;
}
+ } else if (is_type_string16(t)) {
+ switch (index) {
+ case 0: result_type = t_u16_ptr; break;
+ case 1: result_type = t_int; break;
+ }
} else if (is_type_string(t)) {
switch (index) {
case 0: result_type = t_u8_ptr; break;
@@ -1273,6 +1297,12 @@ gb_internal lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) {
switch (t->kind) {
case Type_Basic:
switch (t->Basic.kind) {
+ case Basic_string16:
+ switch (index) {
+ case 0: result_type = t_u16_ptr; break;
+ case 1: result_type = t_int; break;
+ }
+ break;
case Basic_string:
switch (index) {
case 0: result_type = t_u8_ptr; break;
@@ -1440,6 +1470,10 @@ gb_internal lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection
e = lb_emit_struct_ep(p, e, index);
break;
+ case Basic_string16:
+ e = lb_emit_struct_ep(p, e, index);
+ break;
+
default:
GB_PANIC("un-gep-able type %s", type_to_string(type));
break;
@@ -1626,11 +1660,17 @@ gb_internal void lb_fill_string(lbProcedure *p, lbAddr const &string, lbValue ba
gb_internal lbValue lb_string_elem(lbProcedure *p, lbValue string) {
Type *t = base_type(string.type);
+ if (t->kind == Type_Basic && t->Basic.kind == Basic_string16) {
+ return lb_emit_struct_ev(p, string, 0);
+ }
GB_ASSERT(t->kind == Type_Basic && t->Basic.kind == Basic_string);
return lb_emit_struct_ev(p, string, 0);
}
gb_internal lbValue lb_string_len(lbProcedure *p, lbValue string) {
Type *t = base_type(string.type);
+ if (t->kind == Type_Basic && t->Basic.kind == Basic_string16) {
+ return lb_emit_struct_ev(p, string, 1);
+ }
GB_ASSERT_MSG(t->kind == Type_Basic && t->Basic.kind == Basic_string, "%s", type_to_string(t));
return lb_emit_struct_ev(p, string, 1);
}
@@ -1641,6 +1681,12 @@ gb_internal lbValue lb_cstring_len(lbProcedure *p, lbValue value) {
args[0] = lb_emit_conv(p, value, t_cstring);
return lb_emit_runtime_call(p, "cstring_len", args);
}
+gb_internal lbValue lb_cstring16_len(lbProcedure *p, lbValue value) {
+ GB_ASSERT(is_type_cstring16(value.type));
+ auto args = array_make<lbValue>(permanent_allocator(), 1);
+ args[0] = lb_emit_conv(p, value, t_cstring16);
+ return lb_emit_runtime_call(p, "cstring16_len", args);
+}
gb_internal lbValue lb_array_elem(lbProcedure *p, lbValue array_ptr) {