From 334b66b311ea071d8ad4dec955f823e6caa7ff5d Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Sun, 17 Jan 2021 20:48:07 +0530 Subject: [PATCH] checker/cgen: add checks and fix cgen for [typedef] for C structs (#8169) --- vlib/math/big/big.v | 1 - vlib/v/checker/checker.v | 5 +++++ vlib/v/checker/tests/typedef_attr_v_struct_err.out | 6 ++++++ vlib/v/checker/tests/typedef_attr_v_struct_err.vv | 7 +++++++ vlib/v/gen/cgen.v | 10 +++++++++- 5 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 vlib/v/checker/tests/typedef_attr_v_struct_err.out create mode 100644 vlib/v/checker/tests/typedef_attr_v_struct_err.vv diff --git a/vlib/math/big/big.v b/vlib/math/big/big.v index 055dc14c28..24745223c4 100644 --- a/vlib/math/big/big.v +++ b/vlib/math/big/big.v @@ -4,7 +4,6 @@ module big #flag -I @VROOT/thirdparty/bignum #flag @VROOT/thirdparty/bignum/bn.o #include "bn.h" -[typedef] struct C.bn { mut: array [32]u32 diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 52e8fc3b90..8e980b0290 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -387,6 +387,11 @@ pub fn (mut c Checker) struct_decl(mut decl ast.StructDecl) { c.error('`$embed_sym.name` is not a struct', embed.pos) } } + for attr in decl.attrs { + if attr.name == 'typedef' && decl.language != .c { + c.error('`typedef` attribute can only be used with C structs', decl.pos) + } + } for i, field in decl.fields { if decl.language == .v { c.check_valid_snake_case(field.name, 'field name', field.pos) diff --git a/vlib/v/checker/tests/typedef_attr_v_struct_err.out b/vlib/v/checker/tests/typedef_attr_v_struct_err.out new file mode 100644 index 0000000000..0253fba138 --- /dev/null +++ b/vlib/v/checker/tests/typedef_attr_v_struct_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/typedef_attr_v_struct_err.vv:2:1: error: `typedef` attribute can only be used with C structs + 1 | [typedef] + 2 | struct Point{} + | ~~~~~~~~~~~~ + 3 | + 4 | fn main() { diff --git a/vlib/v/checker/tests/typedef_attr_v_struct_err.vv b/vlib/v/checker/tests/typedef_attr_v_struct_err.vv new file mode 100644 index 0000000000..421b635aaf --- /dev/null +++ b/vlib/v/checker/tests/typedef_attr_v_struct_err.vv @@ -0,0 +1,7 @@ +[typedef] +struct Point{} + +fn main() { + p := Point{} + println(p) +} diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index f88e32c259..300c5c9e6f 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -660,7 +660,15 @@ typedef struct { .alias { parent := unsafe { &g.table.types[typ.parent_idx] } is_c_parent := parent.name.len > 2 && parent.name[0] == `C` && parent.name[1] == `.` - parent_styp := if is_c_parent { 'struct ' + parent.cname[3..] } else { parent.cname } + mut is_typedef := false + if parent.info is table.Struct { + is_typedef = parent.info.is_typedef + } + parent_styp := if is_c_parent { + if !is_typedef { 'struct ' + parent.cname[3..] } else { parent.cname[3..] } + } else { + parent.cname + } g.type_definitions.writeln('typedef $parent_styp $typ.cname;') } .array {