Commit 73016212a3

Vexu <git@vexu.eu>
2020-12-10 10:33:52
translate-c: support referencing c containers in macros
1 parent 23c1b7f
Changed files (3)
src/translate_c.zig
@@ -5847,6 +5847,22 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*
         } else {
             return transCreateNodeIdentifierUnchecked(c, "c_int");
         },
+        .Keyword_enum, .Keyword_struct, .Keyword_union => {
+            // struct Foo will be declared as struct_Foo by transRecordDecl
+            const next_id = m.next().?;
+            if (next_id != .Identifier) {
+                try m.fail(c, "unable to translate C expr: expected Identifier instead got: {}", .{@tagName(next_id)});
+                return error.ParseError;
+            }
+
+            const ident_token = try appendTokenFmt(c, .Identifier, "{}_{}", .{slice, m.slice()});
+            const identifier = try c.arena.create(ast.Node.OneToken);
+            identifier.* = .{
+                .base = .{ .tag = .Identifier },
+                .token = ident_token,
+            };
+            return &identifier.base;
+        },
         .Identifier => {
             const mangled_name = scope.getAlias(slice);
             return transCreateNodeIdentifier(c, checkForBuiltinTypedef(mangled_name) orelse mangled_name);
@@ -5856,7 +5872,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*
 
             const next_id = m.next().?;
             if (next_id != .RParen) {
-                try m.fail(c, "unable to translate C expr: expected ')'' instead got: {}", .{@tagName(next_id)});
+                try m.fail(c, "unable to translate C expr: expected ')' instead got: {}", .{@tagName(next_id)});
                 return error.ParseError;
             }
             var saw_l_paren = false;
@@ -5886,7 +5902,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*
             const node_to_cast = try parseCExpr(c, m, scope);
 
             if (saw_l_paren and m.next().? != .RParen) {
-                try m.fail(c, "unable to translate C expr: expected ')''", .{});
+                try m.fail(c, "unable to translate C expr: expected ')'", .{});
                 return error.ParseError;
             }
 
test/stage1/behavior/translate_c_macros.h
@@ -10,3 +10,9 @@ typedef struct Color {
 
 #define MY_SIZEOF(x) ((int)sizeof(x))
 #define MY_SIZEOF2(x) ((int)sizeof x)
+
+struct Foo {
+    int a;
+};
+
+#define SIZE_OF_FOO sizeof(struct Foo)
test/stage1/behavior/translate_c_macros.zig
@@ -16,3 +16,7 @@ test "sizeof in macros" {
     expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32));
     expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32));
 }
+
+test "reference to a struct type" {
+    expectEqual(@sizeOf(h.struct_Foo), h.SIZE_OF_FOO);
+}