ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.68k stars 2.53k forks source link

`unable to translate C expr: unexpected token 'volatile'` in C macro #17778

Open LaXiS96 opened 1 year ago

LaXiS96 commented 1 year ago

Zig Version

0.12.0-dev.1342+13c7aa5fe

Steps to Reproduce and Observed Behavior

Trying to @cImport https://github.com/libopencm3/libopencm3

const cm3 = @cImport({
    @cDefine("__ARM_ARCH_7M__", {});
    @cInclude("libopencm3/cm3/common.h");
    @cInclude("libopencm3/cm3/memorymap.h");
    @cInclude("libopencm3/cm3/scs.h");
});

Compilation result:

E:\stm32\project\zig-cache\o\da3c43b49cbd4fd592fd0c53e769ebad\cimport.zig:95:20: error: unable to translate C expr: unexpected token 'volatile'
pub const MMIO32 = @compileError("unable to translate C expr: unexpected token 'volatile'"); // E:\stm32\project\libopencm3\include/libopencm3/cm3/common.h:69:9
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
    SCS_DEMCR: E:\stm32\project\zig-cache\o\da3c43b49cbd4fd592fd0c53e769ebad\cimport.zig:683:23
    init: src\trace.zig:10:8

Line 69 of libopencm3/cm3/common.h:

#define MMIO32(addr)        (*(volatile uint32_t *)(addr))

Expected Behavior

Import of C header to not fail

LaXiS96 commented 12 months ago

Is there any workaround to this issue? Can I override the C header declaration in my Zig code, somehow ignoring the translation error?

Also I have no idea what the actual cause is, is the volatile keyword not supported by the translation backend?

Vexu commented 12 months ago

Is there any workaround to this issue?

You can manually translate the macro that is causing the issue:

#define MMIO32(addr)        (*(volatile uint32_t *)(addr))
#define SCS_DEMCR       MMIO32(SCS_BASE + 0xDFC)
const SCS_DEMCR_ptr: *volatile uint32_t = @ptrFromInt(SCS_BASE + 0xDFC);
// replace uses of SCS_DEMCR with
SCS_DEMCR_ptr.*

Also I have no idea what the actual cause is, is the volatile keyword not supported by the translation backend?

parseCTypeName does not support volatile and const qualifiers and even if it did it would also need to detect that that macro is supposed to be expanded into the function body and convert it into an inline function.

It's not exactly an easy fix which is why I put it in that milestone.

LaXiS96 commented 11 months ago

Thank you @Vexu, that workaround works as expected! I guess this just proves the point that preprocessor macros were never a great idea :)