From 94f0f6d93b6de115f748c151ea2e7c2ee1abe2b0 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Wed, 26 Feb 2025 11:05:11 +0200 Subject: [PATCH] cgen,checker: allow for `pub type C.HINSTANCE = voidptr`, being used in `@[export: "wWinMain"] fn mymain(x C.HINSTANCE, xprev C.HINSTANCE, lpcmdline &C.WCHAR, cmdshow int) int {` in `module no_main` programs (#23812) --- vlib/v/checker/checker.v | 6 ++- vlib/v/gen/c/cgen.v | 6 +++ .../gen/c/testdata/multiple_c_cources/file3.c | 1 + .../builtin_arrays/array_fixed_c_test.c.v | 39 +++++++++++++++++++ .../tests/builtin_arrays/array_fixed_c_test.v | 9 ----- 5 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 vlib/v/gen/c/testdata/multiple_c_cources/file3.c create mode 100644 vlib/v/tests/builtin_arrays/array_fixed_c_test.c.v delete mode 100644 vlib/v/tests/builtin_arrays/array_fixed_c_test.v diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 56283b67ca..4b9f08edc2 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -550,8 +550,10 @@ fn (mut c Checker) alias_type_decl(mut node ast.AliasTypeDecl) { } .alias { orig_sym := c.table.sym((parent_typ_sym.info as ast.Alias).parent_type) - c.error('type `${parent_typ_sym.str()}` is an alias, use the original alias type `${orig_sym.name}` instead', - node.type_pos) + if !node.name.starts_with('C.') { + c.error('type `${parent_typ_sym.str()}` is an alias, use the original alias type `${orig_sym.name}` instead', + node.type_pos) + } } .chan { c.error('aliases of `chan` types are not allowed', node.type_pos) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index db208129da..0a2bcd15fe 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1815,6 +1815,12 @@ pub fn (mut g Gen) write_alias_typesymbol_declaration(sym ast.TypeSymbol) { // TODO: remove this check; it is here just to fix V rebuilding in -cstrict mode with clang-12 return } + if sym.name.starts_with('C.') { + // `pub type C.HINSTANCE = voidptr` means that `HINSTANCE` should be treated as a voidptr by V. + // The C type itself however already exists on the C side, so just treat C__HINSTANCE as a macro for it: + g.type_definitions.writeln('#define ${sym.cname} ${sym.cname#[3..]}') + return + } if is_fixed_array_of_non_builtin && levels == 0 { g.alias_definitions.writeln('typedef ${parent_styp} ${sym.cname};') } else { diff --git a/vlib/v/gen/c/testdata/multiple_c_cources/file3.c b/vlib/v/gen/c/testdata/multiple_c_cources/file3.c new file mode 100644 index 0000000000..c26d5b60be --- /dev/null +++ b/vlib/v/gen/c/testdata/multiple_c_cources/file3.c @@ -0,0 +1 @@ +typedef struct { int i; float f; char c; } CStruct, *PCStruct; diff --git a/vlib/v/tests/builtin_arrays/array_fixed_c_test.c.v b/vlib/v/tests/builtin_arrays/array_fixed_c_test.c.v new file mode 100644 index 0000000000..6592d98a20 --- /dev/null +++ b/vlib/v/tests/builtin_arrays/array_fixed_c_test.c.v @@ -0,0 +1,39 @@ +#include "@VMODROOT/vlib/v/gen/c/testdata/multiple_c_cources/file3.c" + +@[typedef] +struct C.CStruct { +mut: + c char + i int + f f32 +} + +type C.PCStruct = &C.CStruct + +struct WrapperStruct { +mut: + arr_fixed_c_type [2]C.PCStruct +} + +fn test_main() { + s1 := &C.CStruct{ + c: char(`A`) + f: 3.14 + i: 42 + } + s2 := &C.CStruct{ + c: char(`B`) + f: 1.4142 + i: 2 + } + mut w := WrapperStruct{} + w.arr_fixed_c_type[0] = s1 + w.arr_fixed_c_type[1] = s2 + dump(w) + assert w.arr_fixed_c_type[0].c == char(`A`) + assert w.arr_fixed_c_type[1].c == char(`B`) + assert w.arr_fixed_c_type[0].f == 3.14 + assert w.arr_fixed_c_type[1].f == 1.4142 + assert w.arr_fixed_c_type[0].i == 42 + assert w.arr_fixed_c_type[1].i == 2 +} diff --git a/vlib/v/tests/builtin_arrays/array_fixed_c_test.v b/vlib/v/tests/builtin_arrays/array_fixed_c_test.v deleted file mode 100644 index ab9213cf07..0000000000 --- a/vlib/v/tests/builtin_arrays/array_fixed_c_test.v +++ /dev/null @@ -1,9 +0,0 @@ -type C.ArrFixedCTestType = voidptr - -struct WrapperStruct { -mut: - arr_fixed_c_type [1]C.ArrFixedCTestType -} - -fn test_main() { -}