authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-12-10 11:33:52+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-12-10 14:45:48+02:00
log73016212a3ec48724e7012c4470b4c735d1f211b
tree7db094482811571867224fbc4943da30d268f21c
parent23c1b7faee13f95bce6ba48051b9ac1a1fab9576

translate-c: support referencing c containers in macros


3 files changed, 28 insertions(+), 2 deletions(-)

src/translate_c.zig+18-2
...@@ -5847,6 +5847,22 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*...@@ -5847,6 +5847,22 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*
5847 } else {5847 } else {
5848 return transCreateNodeIdentifierUnchecked(c, "c_int");5848 return transCreateNodeIdentifierUnchecked(c, "c_int");
5849 },5849 },
5850 .Keyword_enum, .Keyword_struct, .Keyword_union => {
5851 // struct Foo will be declared as struct_Foo by transRecordDecl
5852 const next_id = m.next().?;
5853 if (next_id != .Identifier) {
5854 try m.fail(c, "unable to translate C expr: expected Identifier instead got: {}", .{@tagName(next_id)});
5855 return error.ParseError;
5856 }
5857
5858 const ident_token = try appendTokenFmt(c, .Identifier, "{}_{}", .{slice, m.slice()});
5859 const identifier = try c.arena.create(ast.Node.OneToken);
5860 identifier.* = .{
5861 .base = .{ .tag = .Identifier },
5862 .token = ident_token,
5863 };
5864 return &identifier.base;
5865 },
5850 .Identifier => {5866 .Identifier => {
5851 const mangled_name = scope.getAlias(slice);5867 const mangled_name = scope.getAlias(slice);
5852 return transCreateNodeIdentifier(c, checkForBuiltinTypedef(mangled_name) orelse mangled_name);5868 return transCreateNodeIdentifier(c, checkForBuiltinTypedef(mangled_name) orelse mangled_name);
...@@ -5856,7 +5872,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*...@@ -5856,7 +5872,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*
58565872
5857 const next_id = m.next().?;5873 const next_id = m.next().?;
5858 if (next_id != .RParen) {5874 if (next_id != .RParen) {
5859 try m.fail(c, "unable to translate C expr: expected ')'' instead got: {}", .{@tagName(next_id)});5875 try m.fail(c, "unable to translate C expr: expected ')' instead got: {}", .{@tagName(next_id)});
5860 return error.ParseError;5876 return error.ParseError;
5861 }5877 }
5862 var saw_l_paren = false;5878 var saw_l_paren = false;
...@@ -5886,7 +5902,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*...@@ -5886,7 +5902,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*
5886 const node_to_cast = try parseCExpr(c, m, scope);5902 const node_to_cast = try parseCExpr(c, m, scope);
58875903
5888 if (saw_l_paren and m.next().? != .RParen) {5904 if (saw_l_paren and m.next().? != .RParen) {
5889 try m.fail(c, "unable to translate C expr: expected ')''", .{});5905 try m.fail(c, "unable to translate C expr: expected ')'", .{});
5890 return error.ParseError;5906 return error.ParseError;
5891 }5907 }
58925908
test/stage1/behavior/translate_c_macros.h+6
...@@ -10,3 +10,9 @@ typedef struct Color {...@@ -10,3 +10,9 @@ typedef struct Color {
1010
11#define MY_SIZEOF(x) ((int)sizeof(x))11#define MY_SIZEOF(x) ((int)sizeof(x))
12#define MY_SIZEOF2(x) ((int)sizeof x)12#define MY_SIZEOF2(x) ((int)sizeof x)
13
14struct Foo {
15 int a;
16};
17
18#define SIZE_OF_FOO sizeof(struct Foo)
test/stage1/behavior/translate_c_macros.zig+4
...@@ -16,3 +16,7 @@ test "sizeof in macros" {...@@ -16,3 +16,7 @@ test "sizeof in macros" {
16 expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32));16 expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32));
17 expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32));17 expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32));
18}18}
19
20test "reference to a struct type" {
21 expectEqual(@sizeOf(h.struct_Foo), h.SIZE_OF_FOO);
22}