Commit 724995e892

Veikka Tuominen <git@vexu.eu>
2021-08-20 14:33:56
translate-c: avoid repeating string in type when making it mutable
1 parent 3b25205
Changed files (2)
src
src/translate_c/ast.zig
@@ -62,6 +62,8 @@ pub const Node = extern union {
         var_decl,
         /// const name = struct { init }
         static_local_var,
+        /// var name = init.*
+        mut_str,
         func,
         warning,
         @"struct",
@@ -361,7 +363,7 @@ pub const Node = extern union {
                 .array_type, .null_sentinel_array_type => Payload.Array,
                 .arg_redecl, .alias, .fail_decl => Payload.ArgRedecl,
                 .log2_int_type => Payload.Log2IntType,
-                .var_simple, .pub_var_simple, .static_local_var => Payload.SimpleVarDecl,
+                .var_simple, .pub_var_simple, .static_local_var, .mut_str => Payload.SimpleVarDecl,
                 .enum_constant => Payload.EnumConstant,
                 .array_filler => Payload.ArrayFiller,
                 .pub_inline_fn => Payload.PubInlineFn,
@@ -1230,6 +1232,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
                 },
             });
             _ = try c.addToken(.r_brace, "}");
+            _ = try c.addToken(.semicolon, ";");
 
             return c.addNode(.{
                 .tag = .simple_var_decl,
@@ -1240,6 +1243,29 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
                 },
             });
         },
+        .mut_str => {
+            const payload = node.castTag(.mut_str).?.data;
+
+            const var_tok = try c.addToken(.keyword_var, "var");
+            _ = try c.addIdentifier(payload.name);
+            _ = try c.addToken(.equal, "=");
+
+            const deref = try c.addNode(.{
+                .tag = .deref,
+                .data = .{
+                    .lhs = try renderNodeGrouped(c, payload.init),
+                    .rhs = undefined,
+                },
+                .main_token = try c.addToken(.period_asterisk, ".*"),
+            });
+            _ = try c.addToken(.semicolon, ";");
+
+            return c.addNode(.{
+                .tag = .simple_var_decl,
+                .main_token = var_tok,
+                .data = .{ .lhs = 0, .rhs = deref },
+            });
+        },
         .var_decl => return renderVar(c, node),
         .arg_redecl, .alias => {
             const payload = @fieldParentPtr(Payload.ArgRedecl, "base", node.ptr_otherwise).data;
@@ -2145,7 +2171,7 @@ fn renderNullSentinelArrayType(c: *Context, len: usize, elem_type: Node) !NodeIn
 fn addSemicolonIfNeeded(c: *Context, node: Node) !void {
     switch (node.tag()) {
         .warning => unreachable,
-        .var_decl, .var_simple, .arg_redecl, .alias, .block, .empty_block, .block_single, .@"switch" => {},
+        .var_decl, .var_simple, .arg_redecl, .alias, .block, .empty_block, .block_single, .@"switch", .static_local_var, .mut_str => {},
         .while_true => {
             const payload = node.castTag(.while_true).?.data;
             return addSemicolonIfNotBlock(c, payload);
@@ -2240,6 +2266,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
         .offset_of,
         .shuffle,
         .static_local_var,
+        .mut_str,
         => {
             // no grouping needed
             return renderNode(c, node);
src/translate_c.zig
@@ -721,27 +721,13 @@ fn transQualTypeMaybeInitialized(c: *Context, scope: *Scope, qt: clang.QualType,
 
 /// This is used in global scope to convert a string literal `S` to [*c]u8:
 /// &(struct {
-///     var static: @TypeOf(S.*) = S.*;
+///     var static = S.*;
 /// }).static;
 fn stringLiteralToCharStar(c: *Context, str: Node) Error!Node {
     const var_name = Scope.Block.StaticInnerName;
 
-    const derefed = try Tag.deref.create(c.arena, str);
-    const var_type = try Tag.typeof.create(c.arena, derefed);
-
     const variables = try c.arena.alloc(Node, 1);
-    variables[0] = try Tag.var_decl.create(c.arena, .{
-        .is_pub = false,
-        .is_const = false,
-        .is_extern = false,
-        .is_export = false,
-        .is_threadlocal = false,
-        .linksection_string = null,
-        .alignment = null,
-        .name = var_name,
-        .type = var_type,
-        .init = derefed,
-    });
+    variables[0] = try Tag.mut_str.create(c.arena, .{ .name = var_name, .init = str });
 
     const anon_struct = try Tag.@"struct".create(c.arena, .{
         .layout = .none,