Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve C macro translation of R_CAST from Ruby #8062

Closed
jvns opened this issue Feb 25, 2021 · 4 comments
Closed

improve C macro translation of R_CAST from Ruby #8062

jvns opened this issue Feb 25, 2021 · 4 comments
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. translate-c C to Zig source translation feature (@cImport)
Milestone

Comments

@jvns
Copy link

jvns commented Feb 25, 2021

I was trying to import a bunch of header files from Ruby with zig as an experiment, and I ran into an error with this #define in one of MRI's header files:

#define R_CAST(st)   (struct st*)

When translating that line into Zig (using @cImport), I get this syntax error:

./zig-cache/o/7d35789486efb482f998dcafaae27e93/cimport.zig:375:25: error: expected token ';', found ','
    return [*c]struct_st,

Here's the full function that Zig generated for that #define, which does seem to have a syntax error:

pub fn R_CAST(st: anytype) callconv(.Inline) @TypeOf(
    [*c]struct_st,
) {
    return [*c]struct_st,
}

I think this is because this R_CAST #define is kind of weird and it's tripping up the C -> Zig translation code. I don't know if Zig is intended to support arbitrary C preprocessor directives like this but opening the issue anyway in case it's of interest.

I made a very small repo that reproduces this issue here: https://github.com/jvns/zig-include -- you should be able to repro just by cloning it and running zig build.

I also might have just made some beginner mistake, it's my first time trying zig :)

@andrewrk andrewrk added translate-c C to Zig source translation feature (@cImport) bug Observed behavior contradicts documented or intended behavior labels Feb 25, 2021
@andrewrk andrewrk modified the milestones: 0.9.0, 0.8.0 Feb 25, 2021
@andrewrk
Copy link
Member

Hi Julia! Thanks for taking the time to make an issue report and a nice small reproducer.

For the most part, zig's translate-c feature relies on Clang to do the heavy lifting; however we also have our own C tokenizer & parser to translate C macros to Zig in a heuristics-based, best-effort manner. Some C macros cannot be translated, however, they are supposed to fail gracefully, certainly not by emitting a syntax error into zig code!

I actually get a crash when I run a debug build of the compiler on your test case, so this is a great find:

[nix-shell:~/dev/zig/build]$ ./zig translate-c foo.h
thread 29109 panic: reached unreachable code
/home/andy/dev/zig/lib/std/debug.zig:223:14: 0xad3fa8 in std.debug.assert (zig1)
    if (!ok) unreachable; // assertion failure
             ^
/home/andy/dev/zig/lib/std/zig/render.zig:2366:23: 0x108b4d9 in std.zig.render.renderStatement (zig1)
                assert(tree.token_ids[semicolon_index] == .Semicolon);
                      ^
/home/andy/dev/zig/lib/std/zig/render.zig:402:40: 0xf4c984 in std.zig.render.renderExpression (zig1)
                    try renderStatement(allocator, ais, tree, statement);
                                       ^
/home/andy/dev/zig/lib/std/zig/render.zig:201:37: 0xe224ca in std.zig.render.renderContainerDecl (zig1)
                try renderExpression(allocator, ais, tree, body_node, space);
                                    ^
/home/andy/dev/zig/lib/std/zig/render.zig:189:28: 0xcfc51d in std.zig.render.renderTopLevelDecl (zig1)
    try renderContainerDecl(allocator, ais, tree, decl, .Newline);
                           ^
/home/andy/dev/zig/lib/std/zig/render.zig:156:31: 0xb98d99 in std.zig.render.renderRoot (zig1)
        try renderTopLevelDecl(allocator, ais, tree, decl);
                              ^
/home/andy/dev/zig/lib/std/zig/render.zig:29:19: 0xb5f80c in std.zig.render.render (zig1)
    try renderRoot(allocator, &auto_indenting_stream, tree);
                  ^
/home/andy/dev/zig/src/main.zig:2202:31: 0xbb7651 in main.cmdTranslateC (zig1)
        _ = try std.zig.render(comp.gpa, bw.writer(), tree);
                              ^
/home/andy/dev/zig/src/main.zig:1906:29: 0xb01a69 in main.buildOutputType (zig1)
        return cmdTranslateC(comp, arena, have_enable_cache);
                            ^
/home/andy/dev/zig/src/main.zig:184:31: 0xad8d8f in main.mainArgs (zig1)
        return buildOutputType(gpa, arena, args, .translate_c);
                              ^
/home/andy/dev/zig/src/stage1.zig:45:24: 0xad81de in main (zig1)
        stage2.mainArgs(gpa, arena, args) catch unreachable;
                       ^
Aborted (core dumped)

The good news is, you have excellent timing, because I am right about to merge this chonkster #7920 which thanks to @Vexu uses a more maintainable, less buggy way of emitting Zig code from C code. And I just checked, in this branch, the issue is at least partially solved. The macro is translated thusly:

pub fn R_CAST(st: anytype) callconv(.Inline) @TypeOf([*c]struct_st) {
    return [*c]struct_st;
}

No longer a syntax error, but I doubt that is going to be useful to use in Zig code. Perhaps if we have a look at how the C code uses this macro, we can improve the heuristics, or perhaps this is one of those macros that is not very translatable.

@andrewrk
Copy link
Member

With the merge of d7049fc, this is no longer a bug, but a proposal to look at this macro and determine whether it is feasible to improve the heuristics of C macro translation or not.

@andrewrk andrewrk added enhancement Solving this issue will likely involve adding new logic or components to the codebase. and removed bug Observed behavior contradicts documented or intended behavior labels Feb 25, 2021
@andrewrk andrewrk modified the milestones: 0.8.0, 1.1.0 Feb 25, 2021
@andrewrk andrewrk changed the title error translating a C #define into Zig improve C macro translation of R_CAST from Ruby Feb 25, 2021
@jvns
Copy link
Author

jvns commented Feb 26, 2021

I'm extremely impressed by how fast you fixed that :). I think the problem I had is fixed -- I didn't actually need to use that Ruby macro, I just needed there to not be a syntax error.

@andrewrk
Copy link
Member

Alrighty then, given that C macro translation is heuristics based, and there is no actual interest that we know of to actually use this macro, I'll close the issue for now. But if somebody thinks it is worth re-opening, let me know and I'll do that.

@andrewrk andrewrk modified the milestones: 1.1.0, 0.8.0 Feb 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. translate-c C to Zig source translation feature (@cImport)
Projects
None yet
Development

No branches or pull requests

2 participants