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

Added support for exporting of C field expressions #627

Merged
merged 2 commits into from Nov 28, 2017

Conversation

dimenus
Copy link
Contributor

@dimenus dimenus commented Nov 27, 2017

This closes #619

@thejoshwolfe
Copy link
Sponsor Contributor

I don't understand what this PR is adding. This is my guess after reading the test included in this PR:

#define foo a.b

@dimenus
Copy link
Contributor Author

dimenus commented Nov 27, 2017

@thejoshwolfe Sorry, for the lack of detail. It creates support for c macros whose targets are fields of unions / structs. Right now the classic OpenGL function loader (e.g. gl3w) doesn't work.

this:

typedef unsigned int GLbitfield;
typedef void (*PFNGLCLEARPROC) (GLbitfield mask);

typedef void(*OpenGLProc)(void);
union OpenGLProcs {
    OpenGLProc ptr[1];
    struct {
        PFNGLCLEARPROC Clear;
    } gl;
};

extern union OpenGLProcs glProcs;
#define glClearUnion glProcs.gl.Clear
#define glClearPFN PFNGLCLEARPROC

Now generates:

pub const GLbitfield = c_uint;
pub const PFNGLCLEARPROC = ?extern fn(GLbitfield);
pub const OpenGLProc = ?extern fn();
pub const union_OpenGLProcs = extern union {
    ptr: [1]OpenGLProc,
    gl: extern struct {
        Clear: PFNGLCLEARPROC,
    },
};
pub extern var glProcs: union_OpenGLProcs;
pub const glClearPFN = PFNGLCLEARPROC;
pub const glClearUnion = glProcs.gl.Clear;
pub const OpenGLProcs = union_OpenGLProcs;

Before the 'glClearUnion' identifier would not get created.

@andrewrk
Copy link
Member

andrewrk commented Nov 27, 2017

Let's try to get this integrated with the inline-function generator like we have for this test case:

    cases.add("generate inline func for #define global extern fn",
        \\extern void (*fn_ptr)(void);
        \\#define foo fn_ptr
        \\
        \\extern char (*fn_ptr2)(int, float);
        \\#define bar fn_ptr2
    ,
        \\pub extern var fn_ptr: ?extern fn();
    ,
        \\pub inline fn foo() {
        \\    (??fn_ptr)()
        \\}
    ,
        \\pub extern var fn_ptr2: ?extern fn(c_int, f32) -> u8;
    ,
        \\pub inline fn bar(arg0: c_int, arg1: f32) -> u8 {
        \\    (??fn_ptr2)(arg0, arg1)
        \\}
    );

So I think we should try to get this to work, instead of outputting:

pub const glClearUnion = glProcs.gl.Clear;

we should output:

pub inline fn glClearUnion(arg0: GLbitfield) {
    (??glProcs.gl.Clear)(arg0)
}

I think it's reasonable to assume that if you #define foo bar.fn_ptr then you intend to call foo as a function, which asserts that bar.fn_ptr is non-null. Indeed this is how the OpenGL API works.

Unrelated, appveyor build failed:

C:/projects/zig-d3l86/src/c_tokenizer.cpp: In function 'void begin_token(CTokenize*, CTokId)':
C:/projects/zig-d3l86/src/c_tokenizer.cpp:104:12: error: enumeration value 'CTokIdDot' not handled in switch [-Werror=switch]
     switch (id) {
            ^
cc1plus.exe: all warnings being treated as errors
make[2]: *** [CMakeFiles/zig.dir/build.make:183: CMakeFiles/zig.dir/src/c_tokenizer.cpp.obj] Error 1

@andrewrk andrewrk merged commit 57049b9 into ziglang:master Nov 28, 2017
@andrewrk
Copy link
Member

@dimenus your intuition about macro_symbols and macro_table not needing to be separate was correct.

@dimenus dimenus deleted the c-field-expr branch July 17, 2019 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

parsec doesn't generate a symbol when the target of a macro is a field within a union.
4 participants