From bfe9d4403357259501efbf7e18fdc410a2bd58d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20K=C3=A4stner?= Date: Tue, 19 Mar 2024 22:08:21 +0100 Subject: [PATCH] feat: support #[deprecated] on enum variants While the #[deprecated] attribute was already read on structs, fns and enums, it was not implemented for enum variants. The information about enum variants is already available via `variant.body.annotations`, so the support for the #[deprecated] attribute on enum-variant level is more or less only another pair of entries within the `EnumConfig`. This commit adds two new options within the `[enum]` settings: - deprecated_variant, and - deprecated_variant_with_notes Both get active only on #[deprecated] variants, e.g., #[repr(u8)] enum ApiLevel { #[deprecated(note = "Legacy Support until 2025")] L1 = 1, #[deprecated] L2 = 2, L3 = 3, L4 = 4, } For enums with struct variants, the current struct deprecation methods are already working good enough (see tests/expecations/deprecated*). --- docs.md | 17 ++++++ src/bindgen/config.rs | 6 +++ src/bindgen/ir/annotation.rs | 5 ++ src/bindgen/ir/enumeration.rs | 9 ++++ tests/expectations/deprecated.c | 45 +++++++++++++++- tests/expectations/deprecated.compat.c | 57 ++++++++++++++++++++- tests/expectations/deprecated.cpp | 47 ++++++++++++++++- tests/expectations/deprecated.pyx | 37 ++++++++++++- tests/expectations/deprecated_both.c | 45 +++++++++++++++- tests/expectations/deprecated_both.compat.c | 57 ++++++++++++++++++++- tests/expectations/deprecated_tag.c | 45 +++++++++++++++- tests/expectations/deprecated_tag.compat.c | 57 ++++++++++++++++++++- tests/expectations/deprecated_tag.pyx | 37 ++++++++++++- tests/rust/deprecated.rs | 26 +++++++++- tests/rust/deprecated.toml | 4 ++ 15 files changed, 474 insertions(+), 20 deletions(-) diff --git a/docs.md b/docs.md index d8c863171..e5347bf36 100644 --- a/docs.md +++ b/docs.md @@ -933,6 +933,23 @@ deprecated = "DEPRECATED_ENUM" # default: nothing is emitted for deprecated enums deprecated_with_notes = "DEPRECATED_ENUM_WITH_NOTE" +# An optional string that should come after the name of any enum variant which has been +# marked as `#[deprecated]` without note. For instance, "__attribute__((deprecated))" +# would be a reasonable value if targeting gcc/clang. A more portable solution would +# involve emitting the name of a macro which you define in a platform-specific +# way. e.g. "DEPRECATED_ENUM_VARIANT" +# default: nothing is emitted for deprecated enum variants +deprecated_variant = "DEPRECATED_ENUM_VARIANT" + +# An optional string that should come after the name of any enum variant which has been +# marked as `#[deprecated(note = "reason")]`. `{}` will be replaced with the +# double-quoted string. For instance, "__attribute__((deprecated({})))" would be a +# reasonable value if targeting gcc/clang. A more portable solution would involve +# emitting the name of a macro which you define in a platform-specific +# way. e.g. "DEPRECATED_ENUM_WITH_NOTE(note)" +# default: nothing is emitted for deprecated enum variants +deprecated_variant_with_notes = "DEPRECATED_ENUM_VARIANT_WITH_NOTE({})" + # Whether enums with fields should generate destructors. This exists so that generic # enums can be properly instantiated with payloads that are C++ types with # destructors. This isn't necessary for structs because C++ has rules to diff --git a/src/bindgen/config.rs b/src/bindgen/config.rs index a976d1d26..9c1a3ccec 100644 --- a/src/bindgen/config.rs +++ b/src/bindgen/config.rs @@ -586,6 +586,10 @@ pub struct EnumConfig { pub deprecated: Option, /// The way to annotation this function as #[deprecated] with notes pub deprecated_with_note: Option, + /// The way to annotate this enum variant as #[deprecated] without notes + pub deprecated_variant: Option, + /// The way to annotate this enum variant as #[deprecated] with notes + pub deprecated_variant_with_note: Option, /// Whether to generate destructors of tagged enums. pub derive_tagged_enum_destructor: bool, /// Whether to generate copy-constructors of tagged enums. @@ -619,6 +623,8 @@ impl Default for EnumConfig { must_use: None, deprecated: None, deprecated_with_note: None, + deprecated_variant: None, + deprecated_variant_with_note: None, derive_tagged_enum_destructor: false, derive_tagged_enum_copy_constructor: false, derive_tagged_enum_copy_assignment: false, diff --git a/src/bindgen/ir/annotation.rs b/src/bindgen/ir/annotation.rs index 48e3e4bcb..5e66cc528 100644 --- a/src/bindgen/ir/annotation.rs +++ b/src/bindgen/ir/annotation.rs @@ -43,6 +43,7 @@ pub enum DeprecatedNoteKind { Function, Struct, Enum, + EnumVariant, } impl AnnotationSet { @@ -76,6 +77,9 @@ impl AnnotationSet { if note.is_empty() { return Some(Cow::Borrowed(match kind { DeprecatedNoteKind::Enum => config.enumeration.deprecated.as_deref()?, + DeprecatedNoteKind::EnumVariant => { + config.enumeration.deprecated_variant.as_deref()? + } DeprecatedNoteKind::Function => config.function.deprecated.as_deref()?, DeprecatedNoteKind::Struct => config.structure.deprecated.as_deref()?, })); @@ -83,6 +87,7 @@ impl AnnotationSet { let format = match kind { DeprecatedNoteKind::Enum => &config.enumeration.deprecated_with_note, + DeprecatedNoteKind::EnumVariant => &config.enumeration.deprecated_variant_with_note, DeprecatedNoteKind::Function => &config.function.deprecated_with_note, DeprecatedNoteKind::Struct => &config.structure.deprecated_with_note, } diff --git a/src/bindgen/ir/enumeration.rs b/src/bindgen/ir/enumeration.rs index a456b761a..11139a0fb 100644 --- a/src/bindgen/ir/enumeration.rs +++ b/src/bindgen/ir/enumeration.rs @@ -301,6 +301,15 @@ impl Source for EnumVariant { } self.documentation.write(config, out); write!(out, "{}", self.export_name); + + if let Some(note) = self + .body + .annotations() + .deprecated_note(config, DeprecatedNoteKind::EnumVariant) + { + write!(out, " {}", note); + } + if let Some(discriminant) = &self.discriminant { if config.language == Language::Cython { // For extern Cython declarations the enumerator value is ignored, diff --git a/tests/expectations/deprecated.c b/tests/expectations/deprecated.c index 4d290c279..48f5574d8 100644 --- a/tests/expectations/deprecated.c +++ b/tests/expectations/deprecated.c @@ -1,9 +1,11 @@ #define DEPRECATED_FUNC __attribute__((deprecated)) #define DEPRECATED_STRUCT __attribute__((deprecated)) #define DEPRECATED_ENUM __attribute__((deprecated)) +#define DEPRECATED_ENUM_VARIANT __attribute__((deprecated)) #define DEPRECATED_FUNC_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_STRUCT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_ENUM_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) +#define DEPRECATED_ENUM_VARIANT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #include @@ -21,6 +23,14 @@ enum DEPRECATED_ENUM_WITH_NOTE("This is a note") DeprecatedEnumWithNote { }; typedef int32_t DeprecatedEnumWithNote; +enum EnumWithDeprecatedVariants { + C = 0, + D DEPRECATED_ENUM_VARIANT = 1, + E DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note") = 2, + F DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note") = 3, +}; +typedef int32_t EnumWithDeprecatedVariants; + typedef struct DEPRECATED_STRUCT { int32_t a; } DeprecatedStruct; @@ -29,6 +39,35 @@ typedef struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") { int32_t a; } DeprecatedStructWithNote; +enum EnumWithDeprecatedStructVariants_Tag { + Foo, + Bar DEPRECATED_ENUM_VARIANT, + Baz DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note"), +}; +typedef uint8_t EnumWithDeprecatedStructVariants_Tag; + +typedef struct DEPRECATED_STRUCT { + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + int16_t y; +} Bar_Body; + +typedef struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") { + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + uint8_t y; +} Baz_Body; + +typedef union { + EnumWithDeprecatedStructVariants_Tag tag; + struct { + EnumWithDeprecatedStructVariants_Tag foo_tag; + int16_t foo; + }; + Bar_Body bar; + Baz_Body baz; +} EnumWithDeprecatedStructVariants; + DEPRECATED_FUNC void deprecated_without_note(void); DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_without_bracket(void); @@ -42,5 +81,7 @@ void deprecated_with_note_which_requires_to_be_escaped(void); void dummy(DeprecatedEnum a, DeprecatedEnumWithNote b, - DeprecatedStruct c, - DeprecatedStructWithNote d); + EnumWithDeprecatedVariants c, + DeprecatedStruct d, + DeprecatedStructWithNote e, + EnumWithDeprecatedStructVariants f); diff --git a/tests/expectations/deprecated.compat.c b/tests/expectations/deprecated.compat.c index 5db75be5d..13ba81b65 100644 --- a/tests/expectations/deprecated.compat.c +++ b/tests/expectations/deprecated.compat.c @@ -1,9 +1,11 @@ #define DEPRECATED_FUNC __attribute__((deprecated)) #define DEPRECATED_STRUCT __attribute__((deprecated)) #define DEPRECATED_ENUM __attribute__((deprecated)) +#define DEPRECATED_ENUM_VARIANT __attribute__((deprecated)) #define DEPRECATED_FUNC_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_STRUCT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_ENUM_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) +#define DEPRECATED_ENUM_VARIANT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #include @@ -33,6 +35,20 @@ enum DEPRECATED_ENUM_WITH_NOTE("This is a note") DeprecatedEnumWithNote typedef int32_t DeprecatedEnumWithNote; #endif // __cplusplus +enum EnumWithDeprecatedVariants +#ifdef __cplusplus + : int32_t +#endif // __cplusplus + { + C = 0, + D DEPRECATED_ENUM_VARIANT = 1, + E DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note") = 2, + F DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note") = 3, +}; +#ifndef __cplusplus +typedef int32_t EnumWithDeprecatedVariants; +#endif // __cplusplus + typedef struct DEPRECATED_STRUCT { int32_t a; } DeprecatedStruct; @@ -41,6 +57,41 @@ typedef struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") { int32_t a; } DeprecatedStructWithNote; +enum EnumWithDeprecatedStructVariants_Tag +#ifdef __cplusplus + : uint8_t +#endif // __cplusplus + { + Foo, + Bar DEPRECATED_ENUM_VARIANT, + Baz DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note"), +}; +#ifndef __cplusplus +typedef uint8_t EnumWithDeprecatedStructVariants_Tag; +#endif // __cplusplus + +typedef struct DEPRECATED_STRUCT { + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + int16_t y; +} Bar_Body; + +typedef struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") { + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + uint8_t y; +} Baz_Body; + +typedef union { + EnumWithDeprecatedStructVariants_Tag tag; + struct { + EnumWithDeprecatedStructVariants_Tag foo_tag; + int16_t foo; + }; + Bar_Body bar; + Baz_Body baz; +} EnumWithDeprecatedStructVariants; + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -58,8 +109,10 @@ void deprecated_with_note_which_requires_to_be_escaped(void); void dummy(DeprecatedEnum a, DeprecatedEnumWithNote b, - DeprecatedStruct c, - DeprecatedStructWithNote d); + EnumWithDeprecatedVariants c, + DeprecatedStruct d, + DeprecatedStructWithNote e, + EnumWithDeprecatedStructVariants f); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/deprecated.cpp b/tests/expectations/deprecated.cpp index eac7bf4eb..8bb2b8792 100644 --- a/tests/expectations/deprecated.cpp +++ b/tests/expectations/deprecated.cpp @@ -1,9 +1,11 @@ #define DEPRECATED_FUNC __attribute__((deprecated)) #define DEPRECATED_STRUCT __attribute__((deprecated)) #define DEPRECATED_ENUM __attribute__((deprecated)) +#define DEPRECATED_ENUM_VARIANT __attribute__((deprecated)) #define DEPRECATED_FUNC_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_STRUCT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_ENUM_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) +#define DEPRECATED_ENUM_VARIANT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #include @@ -20,6 +22,13 @@ enum class DEPRECATED_ENUM_WITH_NOTE("This is a note") DeprecatedEnumWithNote : B = 0, }; +enum class EnumWithDeprecatedVariants : int32_t { + C = 0, + D DEPRECATED_ENUM_VARIANT = 1, + E DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note") = 2, + F DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note") = 3, +}; + struct DEPRECATED_STRUCT DeprecatedStruct { int32_t a; }; @@ -28,6 +37,38 @@ struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") DeprecatedStructWithNote { int32_t a; }; +union EnumWithDeprecatedStructVariants { + enum class Tag : uint8_t { + Foo, + Bar DEPRECATED_ENUM_VARIANT, + Baz DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note"), + }; + + struct Foo_Body { + Tag tag; + int16_t _0; + }; + + struct DEPRECATED_STRUCT Bar_Body { + Tag tag; + uint8_t x; + int16_t y; + }; + + struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") Baz_Body { + Tag tag; + uint8_t x; + uint8_t y; + }; + + struct { + Tag tag; + }; + Foo_Body foo; + Bar_Body bar; + Baz_Body baz; +}; + extern "C" { DEPRECATED_FUNC void deprecated_without_note(); @@ -43,7 +84,9 @@ void deprecated_with_note_which_requires_to_be_escaped(); void dummy(DeprecatedEnum a, DeprecatedEnumWithNote b, - DeprecatedStruct c, - DeprecatedStructWithNote d); + EnumWithDeprecatedVariants c, + DeprecatedStruct d, + DeprecatedStructWithNote e, + EnumWithDeprecatedStructVariants f); } // extern "C" diff --git a/tests/expectations/deprecated.pyx b/tests/expectations/deprecated.pyx index a9a791055..6f362ae7d 100644 --- a/tests/expectations/deprecated.pyx +++ b/tests/expectations/deprecated.pyx @@ -1,9 +1,11 @@ #define DEPRECATED_FUNC __attribute__((deprecated)) #define DEPRECATED_STRUCT __attribute__((deprecated)) #define DEPRECATED_ENUM __attribute__((deprecated)) +#define DEPRECATED_ENUM_VARIANT __attribute__((deprecated)) #define DEPRECATED_FUNC_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_STRUCT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_ENUM_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) +#define DEPRECATED_ENUM_VARIANT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t @@ -22,12 +24,41 @@ cdef extern from *: B # = 0, ctypedef int32_t DeprecatedEnumWithNote; + cdef enum: + C # = 0, + D # = 1, + E # = 2, + F # = 3, + ctypedef int32_t EnumWithDeprecatedVariants; + ctypedef struct DeprecatedStruct: int32_t a; ctypedef struct DeprecatedStructWithNote: int32_t a; + cdef enum: + Foo, + Bar, + Baz, + ctypedef uint8_t EnumWithDeprecatedStructVariants_Tag; + + ctypedef struct Bar_Body: + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + int16_t y; + + ctypedef struct Baz_Body: + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + uint8_t y; + + ctypedef union EnumWithDeprecatedStructVariants: + EnumWithDeprecatedStructVariants_Tag tag; + int16_t foo; + Bar_Body bar; + Baz_Body baz; + void deprecated_without_note(); void deprecated_without_bracket(); @@ -40,5 +71,7 @@ cdef extern from *: void dummy(DeprecatedEnum a, DeprecatedEnumWithNote b, - DeprecatedStruct c, - DeprecatedStructWithNote d); + EnumWithDeprecatedVariants c, + DeprecatedStruct d, + DeprecatedStructWithNote e, + EnumWithDeprecatedStructVariants f); diff --git a/tests/expectations/deprecated_both.c b/tests/expectations/deprecated_both.c index b7cb96c8a..e2713c4d1 100644 --- a/tests/expectations/deprecated_both.c +++ b/tests/expectations/deprecated_both.c @@ -1,9 +1,11 @@ #define DEPRECATED_FUNC __attribute__((deprecated)) #define DEPRECATED_STRUCT __attribute__((deprecated)) #define DEPRECATED_ENUM __attribute__((deprecated)) +#define DEPRECATED_ENUM_VARIANT __attribute__((deprecated)) #define DEPRECATED_FUNC_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_STRUCT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_ENUM_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) +#define DEPRECATED_ENUM_VARIANT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #include @@ -21,6 +23,14 @@ enum DEPRECATED_ENUM_WITH_NOTE("This is a note") DeprecatedEnumWithNote { }; typedef int32_t DeprecatedEnumWithNote; +enum EnumWithDeprecatedVariants { + C = 0, + D DEPRECATED_ENUM_VARIANT = 1, + E DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note") = 2, + F DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note") = 3, +}; +typedef int32_t EnumWithDeprecatedVariants; + typedef struct DEPRECATED_STRUCT DeprecatedStruct { int32_t a; } DeprecatedStruct; @@ -29,6 +39,35 @@ typedef struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") DeprecatedStructWit int32_t a; } DeprecatedStructWithNote; +enum EnumWithDeprecatedStructVariants_Tag { + Foo, + Bar DEPRECATED_ENUM_VARIANT, + Baz DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note"), +}; +typedef uint8_t EnumWithDeprecatedStructVariants_Tag; + +typedef struct DEPRECATED_STRUCT Bar_Body { + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + int16_t y; +} Bar_Body; + +typedef struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") Baz_Body { + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + uint8_t y; +} Baz_Body; + +typedef union EnumWithDeprecatedStructVariants { + EnumWithDeprecatedStructVariants_Tag tag; + struct { + EnumWithDeprecatedStructVariants_Tag foo_tag; + int16_t foo; + }; + Bar_Body bar; + Baz_Body baz; +} EnumWithDeprecatedStructVariants; + DEPRECATED_FUNC void deprecated_without_note(void); DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_without_bracket(void); @@ -42,5 +81,7 @@ void deprecated_with_note_which_requires_to_be_escaped(void); void dummy(DeprecatedEnum a, DeprecatedEnumWithNote b, - struct DeprecatedStruct c, - struct DeprecatedStructWithNote d); + EnumWithDeprecatedVariants c, + struct DeprecatedStruct d, + struct DeprecatedStructWithNote e, + union EnumWithDeprecatedStructVariants f); diff --git a/tests/expectations/deprecated_both.compat.c b/tests/expectations/deprecated_both.compat.c index b59cf2562..162041ca3 100644 --- a/tests/expectations/deprecated_both.compat.c +++ b/tests/expectations/deprecated_both.compat.c @@ -1,9 +1,11 @@ #define DEPRECATED_FUNC __attribute__((deprecated)) #define DEPRECATED_STRUCT __attribute__((deprecated)) #define DEPRECATED_ENUM __attribute__((deprecated)) +#define DEPRECATED_ENUM_VARIANT __attribute__((deprecated)) #define DEPRECATED_FUNC_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_STRUCT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_ENUM_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) +#define DEPRECATED_ENUM_VARIANT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #include @@ -33,6 +35,20 @@ enum DEPRECATED_ENUM_WITH_NOTE("This is a note") DeprecatedEnumWithNote typedef int32_t DeprecatedEnumWithNote; #endif // __cplusplus +enum EnumWithDeprecatedVariants +#ifdef __cplusplus + : int32_t +#endif // __cplusplus + { + C = 0, + D DEPRECATED_ENUM_VARIANT = 1, + E DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note") = 2, + F DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note") = 3, +}; +#ifndef __cplusplus +typedef int32_t EnumWithDeprecatedVariants; +#endif // __cplusplus + typedef struct DEPRECATED_STRUCT DeprecatedStruct { int32_t a; } DeprecatedStruct; @@ -41,6 +57,41 @@ typedef struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") DeprecatedStructWit int32_t a; } DeprecatedStructWithNote; +enum EnumWithDeprecatedStructVariants_Tag +#ifdef __cplusplus + : uint8_t +#endif // __cplusplus + { + Foo, + Bar DEPRECATED_ENUM_VARIANT, + Baz DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note"), +}; +#ifndef __cplusplus +typedef uint8_t EnumWithDeprecatedStructVariants_Tag; +#endif // __cplusplus + +typedef struct DEPRECATED_STRUCT Bar_Body { + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + int16_t y; +} Bar_Body; + +typedef struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") Baz_Body { + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + uint8_t y; +} Baz_Body; + +typedef union EnumWithDeprecatedStructVariants { + EnumWithDeprecatedStructVariants_Tag tag; + struct { + EnumWithDeprecatedStructVariants_Tag foo_tag; + int16_t foo; + }; + Bar_Body bar; + Baz_Body baz; +} EnumWithDeprecatedStructVariants; + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -58,8 +109,10 @@ void deprecated_with_note_which_requires_to_be_escaped(void); void dummy(DeprecatedEnum a, DeprecatedEnumWithNote b, - struct DeprecatedStruct c, - struct DeprecatedStructWithNote d); + EnumWithDeprecatedVariants c, + struct DeprecatedStruct d, + struct DeprecatedStructWithNote e, + union EnumWithDeprecatedStructVariants f); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/deprecated_tag.c b/tests/expectations/deprecated_tag.c index e05550b70..982cdc555 100644 --- a/tests/expectations/deprecated_tag.c +++ b/tests/expectations/deprecated_tag.c @@ -1,9 +1,11 @@ #define DEPRECATED_FUNC __attribute__((deprecated)) #define DEPRECATED_STRUCT __attribute__((deprecated)) #define DEPRECATED_ENUM __attribute__((deprecated)) +#define DEPRECATED_ENUM_VARIANT __attribute__((deprecated)) #define DEPRECATED_FUNC_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_STRUCT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_ENUM_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) +#define DEPRECATED_ENUM_VARIANT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #include @@ -21,6 +23,14 @@ enum DEPRECATED_ENUM_WITH_NOTE("This is a note") DeprecatedEnumWithNote { }; typedef int32_t DeprecatedEnumWithNote; +enum EnumWithDeprecatedVariants { + C = 0, + D DEPRECATED_ENUM_VARIANT = 1, + E DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note") = 2, + F DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note") = 3, +}; +typedef int32_t EnumWithDeprecatedVariants; + struct DEPRECATED_STRUCT DeprecatedStruct { int32_t a; }; @@ -29,6 +39,35 @@ struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") DeprecatedStructWithNote { int32_t a; }; +enum EnumWithDeprecatedStructVariants_Tag { + Foo, + Bar DEPRECATED_ENUM_VARIANT, + Baz DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note"), +}; +typedef uint8_t EnumWithDeprecatedStructVariants_Tag; + +struct DEPRECATED_STRUCT Bar_Body { + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + int16_t y; +}; + +struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") Baz_Body { + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + uint8_t y; +}; + +union EnumWithDeprecatedStructVariants { + EnumWithDeprecatedStructVariants_Tag tag; + struct { + EnumWithDeprecatedStructVariants_Tag foo_tag; + int16_t foo; + }; + struct Bar_Body bar; + struct Baz_Body baz; +}; + DEPRECATED_FUNC void deprecated_without_note(void); DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_without_bracket(void); @@ -42,5 +81,7 @@ void deprecated_with_note_which_requires_to_be_escaped(void); void dummy(DeprecatedEnum a, DeprecatedEnumWithNote b, - struct DeprecatedStruct c, - struct DeprecatedStructWithNote d); + EnumWithDeprecatedVariants c, + struct DeprecatedStruct d, + struct DeprecatedStructWithNote e, + union EnumWithDeprecatedStructVariants f); diff --git a/tests/expectations/deprecated_tag.compat.c b/tests/expectations/deprecated_tag.compat.c index 6dd9a51e2..e56327ab0 100644 --- a/tests/expectations/deprecated_tag.compat.c +++ b/tests/expectations/deprecated_tag.compat.c @@ -1,9 +1,11 @@ #define DEPRECATED_FUNC __attribute__((deprecated)) #define DEPRECATED_STRUCT __attribute__((deprecated)) #define DEPRECATED_ENUM __attribute__((deprecated)) +#define DEPRECATED_ENUM_VARIANT __attribute__((deprecated)) #define DEPRECATED_FUNC_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_STRUCT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_ENUM_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) +#define DEPRECATED_ENUM_VARIANT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #include @@ -33,6 +35,20 @@ enum DEPRECATED_ENUM_WITH_NOTE("This is a note") DeprecatedEnumWithNote typedef int32_t DeprecatedEnumWithNote; #endif // __cplusplus +enum EnumWithDeprecatedVariants +#ifdef __cplusplus + : int32_t +#endif // __cplusplus + { + C = 0, + D DEPRECATED_ENUM_VARIANT = 1, + E DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note") = 2, + F DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note") = 3, +}; +#ifndef __cplusplus +typedef int32_t EnumWithDeprecatedVariants; +#endif // __cplusplus + struct DEPRECATED_STRUCT DeprecatedStruct { int32_t a; }; @@ -41,6 +57,41 @@ struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") DeprecatedStructWithNote { int32_t a; }; +enum EnumWithDeprecatedStructVariants_Tag +#ifdef __cplusplus + : uint8_t +#endif // __cplusplus + { + Foo, + Bar DEPRECATED_ENUM_VARIANT, + Baz DEPRECATED_ENUM_VARIANT_WITH_NOTE("This is a note"), +}; +#ifndef __cplusplus +typedef uint8_t EnumWithDeprecatedStructVariants_Tag; +#endif // __cplusplus + +struct DEPRECATED_STRUCT Bar_Body { + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + int16_t y; +}; + +struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") Baz_Body { + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + uint8_t y; +}; + +union EnumWithDeprecatedStructVariants { + EnumWithDeprecatedStructVariants_Tag tag; + struct { + EnumWithDeprecatedStructVariants_Tag foo_tag; + int16_t foo; + }; + struct Bar_Body bar; + struct Baz_Body baz; +}; + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -58,8 +109,10 @@ void deprecated_with_note_which_requires_to_be_escaped(void); void dummy(DeprecatedEnum a, DeprecatedEnumWithNote b, - struct DeprecatedStruct c, - struct DeprecatedStructWithNote d); + EnumWithDeprecatedVariants c, + struct DeprecatedStruct d, + struct DeprecatedStructWithNote e, + union EnumWithDeprecatedStructVariants f); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/deprecated_tag.pyx b/tests/expectations/deprecated_tag.pyx index 70fe12262..767da9566 100644 --- a/tests/expectations/deprecated_tag.pyx +++ b/tests/expectations/deprecated_tag.pyx @@ -1,9 +1,11 @@ #define DEPRECATED_FUNC __attribute__((deprecated)) #define DEPRECATED_STRUCT __attribute__((deprecated)) #define DEPRECATED_ENUM __attribute__((deprecated)) +#define DEPRECATED_ENUM_VARIANT __attribute__((deprecated)) #define DEPRECATED_FUNC_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_STRUCT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_ENUM_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) +#define DEPRECATED_ENUM_VARIANT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t @@ -22,12 +24,41 @@ cdef extern from *: B # = 0, ctypedef int32_t DeprecatedEnumWithNote; + cdef enum: + C # = 0, + D # = 1, + E # = 2, + F # = 3, + ctypedef int32_t EnumWithDeprecatedVariants; + cdef struct DeprecatedStruct: int32_t a; cdef struct DeprecatedStructWithNote: int32_t a; + cdef enum: + Foo, + Bar, + Baz, + ctypedef uint8_t EnumWithDeprecatedStructVariants_Tag; + + cdef struct Bar_Body: + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + int16_t y; + + cdef struct Baz_Body: + EnumWithDeprecatedStructVariants_Tag tag; + uint8_t x; + uint8_t y; + + cdef union EnumWithDeprecatedStructVariants: + EnumWithDeprecatedStructVariants_Tag tag; + int16_t foo; + Bar_Body bar; + Baz_Body baz; + void deprecated_without_note(); void deprecated_without_bracket(); @@ -40,5 +71,7 @@ cdef extern from *: void dummy(DeprecatedEnum a, DeprecatedEnumWithNote b, - DeprecatedStruct c, - DeprecatedStructWithNote d); + EnumWithDeprecatedVariants c, + DeprecatedStruct d, + DeprecatedStructWithNote e, + EnumWithDeprecatedStructVariants f); diff --git a/tests/rust/deprecated.rs b/tests/rust/deprecated.rs index 3abf65a92..0098b856e 100644 --- a/tests/rust/deprecated.rs +++ b/tests/rust/deprecated.rs @@ -30,6 +30,26 @@ pub enum DeprecatedEnumWithNote { B = 0, } +#[repr(i32)] +pub enum EnumWithDeprecatedVariants { + C = 0, + #[deprecated] + D = 1, + #[deprecated(note = "This is a note")] + E = 2, + #[deprecated(note = "This is a note", since = "1.0.0")] + F = 3, +} + +#[repr(u8)] +enum EnumWithDeprecatedStructVariants { + Foo(i16), + #[deprecated] + Bar { x: u8, y: i16 }, + #[deprecated(note = "This is a note")] + Baz { x: u8, y: u8 }, +} + #[repr(C)] #[deprecated] pub struct DeprecatedStruct { @@ -46,7 +66,9 @@ pub struct DeprecatedStructWithNote { pub extern "C" fn dummy( a: DeprecatedEnum, b: DeprecatedEnumWithNote, - c: DeprecatedStruct, - d: DeprecatedStructWithNote, + c: EnumWithDeprecatedVariants, + d: DeprecatedStruct, + e: DeprecatedStructWithNote, + f: EnumWithDeprecatedStructVariants, ) -> void { } diff --git a/tests/rust/deprecated.toml b/tests/rust/deprecated.toml index 4a2bad553..95f7f3d23 100644 --- a/tests/rust/deprecated.toml +++ b/tests/rust/deprecated.toml @@ -2,9 +2,11 @@ header = """ #define DEPRECATED_FUNC __attribute__((deprecated)) #define DEPRECATED_STRUCT __attribute__((deprecated)) #define DEPRECATED_ENUM __attribute__((deprecated)) +#define DEPRECATED_ENUM_VARIANT __attribute__((deprecated)) #define DEPRECATED_FUNC_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_STRUCT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) #define DEPRECATED_ENUM_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) +#define DEPRECATED_ENUM_VARIANT_WITH_NOTE(...) __attribute__((deprecated(__VA_ARGS__))) """ [fn] @@ -18,3 +20,5 @@ deprecated_with_note = "DEPRECATED_STRUCT_WITH_NOTE({})" [enum] deprecated = "DEPRECATED_ENUM" deprecated_with_note = "DEPRECATED_ENUM_WITH_NOTE({})" +deprecated_variant = "DEPRECATED_ENUM_VARIANT" +deprecated_variant_with_note = "DEPRECATED_ENUM_VARIANT_WITH_NOTE({})"