mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
cgen: fix generated str method for enums that have C values (use ifs, instead of switch) (fix #25135) (#25157)
This commit is contained in:
parent
a40e86ad7c
commit
83385a8bf8
4 changed files with 57 additions and 0 deletions
|
@ -378,6 +378,13 @@ fn (mut g Gen) gen_str_for_enum(info ast.Enum, styp string, str_fn_name string)
|
||||||
}
|
}
|
||||||
g.auto_str_funcs.writeln('\tret = string__plus(ret, _S("}"));')
|
g.auto_str_funcs.writeln('\tret = string__plus(ret, _S("}"));')
|
||||||
g.auto_str_funcs.writeln('\treturn ret;')
|
g.auto_str_funcs.writeln('\treturn ret;')
|
||||||
|
} else if info.uses_exprs {
|
||||||
|
// The enum values could be C macros, expanded later to duplicate values, and we do not know if that is the case, so we can not use a switch here.
|
||||||
|
// Instead we generate multiple if statements, which is slower, but is guaranteed to work in the presence of duplicates.
|
||||||
|
for val in info.vals {
|
||||||
|
g.auto_str_funcs.writeln('\t\tif(it == ${s}__${val}){ return _S("${val}"); }')
|
||||||
|
}
|
||||||
|
g.auto_str_funcs.writeln('\t\treturn _S("unknown enum value");')
|
||||||
} else {
|
} else {
|
||||||
g.auto_str_funcs.writeln('\tswitch(it) {')
|
g.auto_str_funcs.writeln('\tswitch(it) {')
|
||||||
// Only use the first multi value on the lookup
|
// Only use the first multi value on the lookup
|
||||||
|
|
|
@ -6,3 +6,16 @@ fn test_using_c_code_in_the_same_module_works() {
|
||||||
modc.destroy_vtype(x)
|
modc.destroy_vtype(x)
|
||||||
assert true
|
assert true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_enum_with_dups_on_the_cside() {
|
||||||
|
for e in [modc.MyEnum.unknown, .name1, .name2, .name3, .name4, .name5, .name6, .common_name1,
|
||||||
|
.common_name2, .common_name3] {
|
||||||
|
println('>>> e: ${e} | int(e): ${int(e)}')
|
||||||
|
}
|
||||||
|
assert modc.MyEnum.name1 == modc.MyEnum.common_name1
|
||||||
|
assert modc.MyEnum.name2 == modc.MyEnum.common_name2
|
||||||
|
assert modc.MyEnum.name3 == modc.MyEnum.common_name3
|
||||||
|
assert modc.MyEnum.name4 != modc.MyEnum.common_name1
|
||||||
|
assert modc.MyEnum.name5 != modc.MyEnum.common_name2
|
||||||
|
assert modc.MyEnum.name6 != modc.MyEnum.common_name3
|
||||||
|
}
|
||||||
|
|
|
@ -15,5 +15,29 @@ void handle_array2(void *p, int n);
|
||||||
void destroy_atype(void *p);
|
void destroy_atype(void *p);
|
||||||
|
|
||||||
|
|
||||||
|
// The following emulates the structure of the SDL3 header SDL_pixels.h, and the enum SDL_PixelFormat.
|
||||||
|
// See also https://github.com/vlang/v/issues/25135 .
|
||||||
|
#define ABC 1
|
||||||
|
#define XYZ 1
|
||||||
|
|
||||||
|
typedef enum EnumWithDuplicates {
|
||||||
|
UNKNOWN = 0,
|
||||||
|
NAME1 = 0x1u,
|
||||||
|
NAME2 = 0x2u,
|
||||||
|
NAME3 = 0x3u,
|
||||||
|
NAME4 = 0x4u,
|
||||||
|
NAME5 = 0x5u,
|
||||||
|
NAME6 = 0x6u,
|
||||||
|
#if ABC == XYZ
|
||||||
|
COMMON_NAME1 = NAME1,
|
||||||
|
COMMON_NAME2 = NAME2,
|
||||||
|
COMMON_NAME3 = NAME3
|
||||||
|
#else
|
||||||
|
COMMON_NAME1 = NAME4,
|
||||||
|
COMMON_NAME2 = NAME5,
|
||||||
|
COMMON_NAME3 = NAME6
|
||||||
|
#endif
|
||||||
|
} EnumWithDuplicates;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -51,3 +51,16 @@ pub fn call_with_array_param(arr []Vtype) {
|
||||||
pub fn destroy_vtype(t Vtype) {
|
pub fn destroy_vtype(t Vtype) {
|
||||||
C.destroy_atype(t.p)
|
C.destroy_atype(t.p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum MyEnum {
|
||||||
|
unknown = C.UNKNOWN
|
||||||
|
name1 = C.NAME1
|
||||||
|
name2 = C.NAME2
|
||||||
|
name3 = C.NAME3
|
||||||
|
name4 = C.NAME4
|
||||||
|
name5 = C.NAME5
|
||||||
|
name6 = C.NAME6
|
||||||
|
common_name1 = C.COMMON_NAME1
|
||||||
|
common_name2 = C.COMMON_NAME2
|
||||||
|
common_name3 = C.COMMON_NAME3
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue