From 73016212a3ec48724e7012c4470b4c735d1f211b Mon Sep 17 00:00:00 2001 From: Vexu Date: Thu, 10 Dec 2020 11:33:52 +0200 Subject: [PATCH] translate-c: support referencing c containers in macros --- src/translate_c.zig | 20 ++++++++++++++++++-- test/stage1/behavior/translate_c_macros.h | 6 ++++++ test/stage1/behavior/translate_c_macros.zig | 4 ++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/translate_c.zig b/src/translate_c.zig index cfd656f5ec..424691513a 100644 --- a/src/translate_c.zig +++ b/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; } diff --git a/test/stage1/behavior/translate_c_macros.h b/test/stage1/behavior/translate_c_macros.h index 49806a524e..d3a6ac1ea5 100644 --- a/test/stage1/behavior/translate_c_macros.h +++ b/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) diff --git a/test/stage1/behavior/translate_c_macros.zig b/test/stage1/behavior/translate_c_macros.zig index 2cfb2331fa..640f1c8c86 100644 --- a/test/stage1/behavior/translate_c_macros.zig +++ b/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); +}