aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-05-24 00:10:56 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-05-24 01:01:24 -0700
commit818fbd9c567b907031c44961e4299ce1f9059be6 (patch)
treedb185db14c188c6226824b2f865023d9ef7b25e8 /src/codegen/llvm.zig
parent8171972cbb477672ee1a99d953df4aaecb744a0c (diff)
downloadzig-818fbd9c567b907031c44961e4299ce1f9059be6.tar.gz
zig-818fbd9c567b907031c44961e4299ce1f9059be6.zip
stage2: string literal interning
This is a temporary addition to stage2 in order to match stage1 behavior, however the end-game once the lang spec is settled will be to use a global InternPool for comptime memoized objects, making this behavior consistent across all types, not only string literals. Or, we might decide to not guarantee string literals to have equal comptime pointers, in which case this commit can be reverted.
Diffstat (limited to 'src/codegen/llvm.zig')
-rw-r--r--src/codegen/llvm.zig32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 6de001e5fd..ef33f39f55 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -2936,9 +2936,39 @@ pub const DeclGen = struct {
return dg.context.constString(
bytes.ptr,
@intCast(c_uint, tv.ty.arrayLenIncludingSentinel()),
- .True, // don't null terminate. bytes has the sentinel, if any.
+ .True, // Don't null terminate. Bytes has the sentinel, if any.
);
},
+ .str_lit => {
+ const str_lit = tv.val.castTag(.str_lit).?.data;
+ const bytes = dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
+ if (tv.ty.sentinel()) |sent_val| {
+ const byte = @intCast(u8, sent_val.toUnsignedInt(target));
+ if (byte == 0 and bytes.len > 0) {
+ return dg.context.constString(
+ bytes.ptr,
+ @intCast(c_uint, bytes.len),
+ .False, // Yes, null terminate.
+ );
+ }
+ var array = std.ArrayList(u8).init(dg.gpa);
+ defer array.deinit();
+ try array.ensureUnusedCapacity(bytes.len + 1);
+ array.appendSliceAssumeCapacity(bytes);
+ array.appendAssumeCapacity(byte);
+ return dg.context.constString(
+ array.items.ptr,
+ @intCast(c_uint, array.items.len),
+ .True, // Don't null terminate.
+ );
+ } else {
+ return dg.context.constString(
+ bytes.ptr,
+ @intCast(c_uint, bytes.len),
+ .True, // Don't null terminate. `bytes` has the sentinel, if any.
+ );
+ }
+ },
.aggregate => {
const elem_vals = tv.val.castTag(.aggregate).?.data;
const elem_ty = tv.ty.elemType();