Add support for #[deprecated].

Closes .
Closes .
Closes .
This commit is contained in:
sevenc-nanashi 2023-07-23 07:31:55 +09:00 committed by Emilio Cobos Álvarez
parent d8355da466
commit 0fb5d07ae4
No known key found for this signature in database
GPG Key ID: E1152D0994E4BF8A
21 changed files with 769 additions and 2 deletions

51
docs.md

@ -680,6 +680,23 @@ args = "horizontal"
# default: nothing is emitted for must_use functions
must_use = "MUST_USE_FUNC"
# An optional string that should prefix function declarations which have 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_FUNC"
# default: nothing is emitted for deprecated functions
deprecated = "DEPRECATED_FUNC"
# An optional string that should prefix function declarations which have 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_FUNC_WITH_NOTE(note)"
# default: nothing is emitted for deprecated functions
deprecated_with_notes = "DEPRECATED_FUNC_WITH_NOTE"
# An optional string that will be used in the attribute position for functions
# that don't return (that return `!` in Rust).
#
@ -752,6 +769,23 @@ rename_fields = "PascalCase"
# default: nothing is emitted for must_use structs
must_use = "MUST_USE_STRUCT"
# An optional string that should come before the name of any struct 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_STRUCT"
# default: nothing is emitted for deprecated structs
deprecated = "DEPRECATED_STRUCT"
# An optional string that should come before the name of any struct 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_STRUCT_WITH_NOTE(note)"
# default: nothing is emitted for deprecated structs
deprecated_with_notes = "DEPRECATED_STRUCT_WITH_NOTE"
# Whether a Rust type with associated consts should emit those consts inside the
# type's body. Otherwise they will be emitted trailing and with the type's name
# prefixed. This does nothing if the target is C, or if
@ -865,6 +899,23 @@ cast_assert_name = "MOZ_RELEASE_ASSERT"
# default: nothing is emitted for must_use enums
must_use = "MUST_USE_ENUM"
# An optional string that should come before the name of any enum 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"
# default: nothing is emitted for deprecated enums
deprecated = "DEPRECATED_ENUM"
# An optional string that should come before the name of any enum 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 enums
deprecated_with_notes = "DEPRECATED_ENUM_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

@ -40,6 +40,7 @@ struct CDecl {
type_generic_args: Vec<GenericArgument>,
declarators: Vec<CDeclarator>,
type_ctype: Option<DeclarationType>,
deprecated: Option<String>,
}
impl CDecl {
@ -50,6 +51,7 @@ impl CDecl {
type_generic_args: Vec::new(),
declarators: Vec::new(),
type_ctype: None,
deprecated: None,
}
}
@ -99,6 +101,7 @@ impl CDecl {
layout,
never_return: f.never_return,
});
self.deprecated = f.annotations.deprecated.clone();
self.build_type(&f.ret, false, config);
}

@ -425,6 +425,10 @@ pub struct FunctionConfig {
pub postfix: Option<String>,
/// The way to annotation this function as #[must_use]
pub must_use: Option<String>,
/// The way to annotation this function as #[deprecated] without notes
pub deprecated: Option<String>,
/// The way to annotation this function as #[deprecated] with notes
pub deprecated_with_note: Option<String>,
/// The style to layout the args
pub args: Layout,
/// The rename rule to apply to function args
@ -443,6 +447,8 @@ impl Default for FunctionConfig {
prefix: None,
postfix: None,
must_use: None,
deprecated: None,
deprecated_with_note: None,
args: Layout::Auto,
rename_args: RenameRule::None,
swift_name_macro: None,
@ -498,6 +504,10 @@ pub struct StructConfig {
pub associated_constants_in_body: bool,
/// The way to annotate this struct as #[must_use].
pub must_use: Option<String>,
/// The way to annotation this function as #[deprecated] without notes
pub deprecated: Option<String>,
/// The way to annotation this function as #[deprecated] with notes
pub deprecated_with_note: Option<String>,
}
impl StructConfig {
@ -581,6 +591,10 @@ pub struct EnumConfig {
pub cast_assert_name: Option<String>,
/// The way to annotation this enum as #[must_use].
pub must_use: Option<String>,
/// The way to annotation this function as #[deprecated] without notes
pub deprecated: Option<String>,
/// The way to annotation this function as #[deprecated] with notes
pub deprecated_with_note: Option<String>,
/// Whether to generate destructors of tagged enums.
pub derive_tagged_enum_destructor: bool,
/// Whether to generate copy-constructors of tagged enums.
@ -612,6 +626,8 @@ impl Default for EnumConfig {
derive_mut_casts: false,
cast_assert_name: None,
must_use: None,
deprecated: None,
deprecated_with_note: None,
derive_tagged_enum_destructor: false,
derive_tagged_enum_copy_constructor: false,
derive_tagged_enum_copy_assignment: false,

@ -35,6 +35,7 @@ pub enum AnnotationValue {
pub struct AnnotationSet {
annotations: HashMap<String, AnnotationValue>,
pub must_use: bool,
pub deprecated: Option<String>,
}
impl AnnotationSet {
@ -42,6 +43,7 @@ impl AnnotationSet {
AnnotationSet {
annotations: HashMap::new(),
must_use: false,
deprecated: None,
}
}
@ -53,6 +55,27 @@ impl AnnotationSet {
self.must_use && config.language != Language::Cython
}
pub(crate) fn deprecated_note(&self, config: &Config) -> Option<&str> {
if config.language == Language::Cython {
return None;
}
self.deprecated.as_deref()
}
pub(crate) fn format_deprecated_note(
&self,
format_without_note: Option<&str>,
format_with_note: Option<&str>,
note: &str,
) -> Option<String> {
if note.is_empty() {
return format_without_note.map(|x| x.to_string());
}
format_with_note
.map(|format_with_note| format_with_note.replace("{}", format!("{:?}", note).as_str()))
}
pub fn load(attrs: &[syn::Attribute]) -> Result<AnnotationSet, String> {
let lines = attrs.get_comment_lines();
let lines: Vec<&str> = lines
@ -68,7 +91,7 @@ impl AnnotationSet {
.collect();
let must_use = attrs.has_attr_word("must_use");
let deprecated = attrs.find_deprecated_note();
let mut annotations = HashMap::new();
// Look at each line for an annotation
@ -118,6 +141,7 @@ impl AnnotationSet {
Ok(AnnotationSet {
annotations,
must_use,
deprecated,
})
}

@ -753,7 +753,17 @@ impl Enum {
if let Some(prim) = size {
// If we need to specify size, then we have no choice but to create a typedef,
// so `config.style` is not respected.
write!(out, "enum {}", tag_name);
write!(out, "enum");
if let Some(note) = self.annotations.deprecated_note(config) {
if let Some(note) = self.annotations.format_deprecated_note(
config.enumeration.deprecated.as_deref(),
config.enumeration.deprecated_with_note.as_deref(),
note,
) {
write!(out, " {}", note);
}
}
write!(out, " {}", tag_name);
if config.cpp_compatible_c() {
out.new_line();
@ -769,6 +779,15 @@ impl Enum {
out.write("typedef ");
}
out.write("enum");
if let Some(note) = self.annotations.deprecated_note(config) {
if let Some(note) = self.annotations.format_deprecated_note(
config.enumeration.deprecated.as_deref(),
config.enumeration.deprecated_with_note.as_deref(),
note,
) {
write!(out, " {}", note);
}
}
if config.style.generate_tag() {
write!(out, " {}", tag_name);
}
@ -787,6 +806,16 @@ impl Enum {
}
}
if let Some(note) = self.annotations.deprecated_note(config) {
if let Some(note) = self.annotations.format_deprecated_note(
config.structure.deprecated.as_deref(),
config.structure.deprecated_with_note.as_deref(),
note,
) {
write!(out, " {}", note);
}
}
write!(out, " {}", tag_name);
if let Some(prim) = size {
write!(out, " : {}", prim);
@ -865,6 +894,16 @@ impl Enum {
}
}
if let Some(note) = self.annotations.deprecated_note(config) {
if let Some(note) = self.annotations.format_deprecated_note(
config.enumeration.deprecated.as_deref(),
config.enumeration.deprecated_with_note.as_deref(),
note,
) {
write!(out, " {} ", note);
}
}
if config.language != Language::C || config.style.generate_tag() {
write!(out, " {}", self.export_name());
}

@ -241,6 +241,15 @@ impl Source for Function {
write!(out, "{} ", anno);
}
}
if let Some(note) = func.annotations.deprecated_note(config) {
if let Some(note) = func.annotations.format_deprecated_note(
config.function.deprecated.as_deref(),
config.function.deprecated_with_note.as_deref(),
note,
) {
write!(out, "{} ", note);
}
}
}
cdecl::write_func(out, func, Layout::Horizontal, config);
@ -284,6 +293,16 @@ impl Source for Function {
out.new_line();
}
}
if let Some(note) = func.annotations.deprecated_note(config) {
if let Some(note) = func.annotations.format_deprecated_note(
config.function.deprecated.as_deref(),
config.function.deprecated_with_note.as_deref(),
note,
) {
write!(out, "{}", note);
out.new_line();
}
}
}
cdecl::write_func(out, func, Layout::Vertical, config);
if !func.extern_decl {

@ -455,6 +455,15 @@ impl Source for Struct {
write!(out, " {}", anno);
}
}
if let Some(note) = self.annotations.deprecated_note(config) {
if let Some(note) = self.annotations.format_deprecated_note(
config.structure.deprecated.as_deref(),
config.structure.deprecated_with_note.as_deref(),
note,
) {
write!(out, " {}", note);
}
}
if config.language != Language::C || config.style.generate_tag() {
write!(out, " {}", self.export_name());

@ -130,6 +130,58 @@ pub trait SynAttributeHelpers {
})
}
fn find_deprecated_note(&self) -> Option<String> {
let attrs = self.attrs();
// #[deprecated = ""]
if let Some(note) = attrs.attr_name_value_lookup("deprecated") {
return Some(note);
}
// #[deprecated]
if attrs.has_attr_word("deprecated") {
return Some("".to_string());
}
// #[deprecated(note = "")]
if let Some(attr) = attrs.iter().find(|attr| {
if let Ok(syn::Meta::List(list)) = attr.parse_meta() {
list.path.is_ident("deprecated")
} else {
false
}
}) {
let args: syn::punctuated::Punctuated<syn::MetaNameValue, Token![,]> =
match attr.parse_args_with(syn::punctuated::Punctuated::parse_terminated) {
Ok(args) => args,
Err(_) => {
warn!("couldn't parse deprecated attribute");
return None;
}
};
let lit = match args
.iter()
.find(|arg| arg.path.is_ident("note"))
.map(|arg| &arg.lit)
{
Some(lit) => lit,
None => {
warn!("couldn't parse deprecated attribute: no `note` field");
return None;
}
};
return if let syn::Lit::Str(lit) = lit {
Some(lit.value())
} else {
warn!("deprecated attribute must be a string");
None
};
}
None
}
fn is_no_mangle(&self) -> bool {
self.has_attr_word("no_mangle")
}

@ -78,6 +78,8 @@ renaming_overrides_prefixing = false
[fn]
rename_args = "None"
# must_use = "MUST_USE_FUNC"
# deprecated = "DEPRECATED_FUNC"
# deprecated_with_note = "DEPRECATED_FUNC_WITH_NOTE"
# no_return = "NO_RETURN"
# prefix = "START_FUNC"
# postfix = "END_FUNC"
@ -90,6 +92,8 @@ sort_by = "Name"
[struct]
rename_fields = "None"
# must_use = "MUST_USE_STRUCT"
# deprecated = "DEPRECATED_STRUCT"
# deprecated_with_note = "DEPRECATED_STRUCT_WITH_NOTE"
derive_constructor = false
derive_eq = false
derive_neq = false
@ -104,6 +108,8 @@ derive_gte = false
[enum]
rename_variants = "None"
# must_use = "MUST_USE_ENUM"
# deprecated = "DEPRECATED_ENUM"
# deprecated_with_note = "DEPRECATED_ENUM_WITH_NOTE"
add_sentinel = false
prefix_with_name = false
derive_helper_methods = false

@ -0,0 +1,46 @@
#define DEPRECATED_FUNC __attribute__((deprecated))
#define DEPRECATED_STRUCT __attribute__((deprecated))
#define DEPRECATED_ENUM __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__)))
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
enum DEPRECATED_ENUM DeprecatedEnum {
A = 0,
};
typedef int32_t DeprecatedEnum;
enum DEPRECATED_ENUM_WITH_NOTE("This is a note") DeprecatedEnumWithNote {
B = 0,
};
typedef int32_t DeprecatedEnumWithNote;
typedef struct DEPRECATED_STRUCT {
int32_t a;
} DeprecatedStruct;
typedef struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") {
int32_t a;
} DeprecatedStructWithNote;
DEPRECATED_FUNC void deprecated_without_note(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_without_bracket(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_with_note(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_with_note_and_since(void);
DEPRECATED_FUNC_WITH_NOTE("This quote \" requires to be quoted, and this [\n] requires to be escaped")
void deprecated_with_note_which_requires_to_be_escaped(void);
void dummy(DeprecatedEnum a,
DeprecatedEnumWithNote b,
DeprecatedStruct c,
DeprecatedStructWithNote d);

@ -0,0 +1,66 @@
#define DEPRECATED_FUNC __attribute__((deprecated))
#define DEPRECATED_STRUCT __attribute__((deprecated))
#define DEPRECATED_ENUM __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__)))
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
enum DEPRECATED_ENUM DeprecatedEnum
#ifdef __cplusplus
: int32_t
#endif // __cplusplus
{
A = 0,
};
#ifndef __cplusplus
typedef int32_t DeprecatedEnum;
#endif // __cplusplus
enum DEPRECATED_ENUM_WITH_NOTE("This is a note") DeprecatedEnumWithNote
#ifdef __cplusplus
: int32_t
#endif // __cplusplus
{
B = 0,
};
#ifndef __cplusplus
typedef int32_t DeprecatedEnumWithNote;
#endif // __cplusplus
typedef struct DEPRECATED_STRUCT {
int32_t a;
} DeprecatedStruct;
typedef struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") {
int32_t a;
} DeprecatedStructWithNote;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
DEPRECATED_FUNC void deprecated_without_note(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_without_bracket(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_with_note(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_with_note_and_since(void);
DEPRECATED_FUNC_WITH_NOTE("This quote \" requires to be quoted, and this [\n] requires to be escaped")
void deprecated_with_note_which_requires_to_be_escaped(void);
void dummy(DeprecatedEnum a,
DeprecatedEnumWithNote b,
DeprecatedStruct c,
DeprecatedStructWithNote d);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

@ -0,0 +1,49 @@
#define DEPRECATED_FUNC __attribute__((deprecated))
#define DEPRECATED_STRUCT __attribute__((deprecated))
#define DEPRECATED_ENUM __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__)))
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>
enum class DEPRECATED_ENUM DeprecatedEnum : int32_t {
A = 0,
};
enum class DEPRECATED_ENUM_WITH_NOTE("This is a note") DeprecatedEnumWithNote : int32_t {
B = 0,
};
struct DEPRECATED_STRUCT DeprecatedStruct {
int32_t a;
};
struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") DeprecatedStructWithNote {
int32_t a;
};
extern "C" {
DEPRECATED_FUNC void deprecated_without_note();
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_without_bracket();
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_with_note();
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_with_note_and_since();
DEPRECATED_FUNC_WITH_NOTE("This quote \" requires to be quoted, and this [\n] requires to be escaped")
void deprecated_with_note_which_requires_to_be_escaped();
void dummy(DeprecatedEnum a,
DeprecatedEnumWithNote b,
DeprecatedStruct c,
DeprecatedStructWithNote d);
} // extern "C"

@ -0,0 +1,44 @@
#define DEPRECATED_FUNC __attribute__((deprecated))
#define DEPRECATED_STRUCT __attribute__((deprecated))
#define DEPRECATED_ENUM __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__)))
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
cdef extern from *:
ctypedef bint bool
ctypedef struct va_list
cdef extern from *:
cdef enum:
A # = 0,
ctypedef int32_t DeprecatedEnum;
cdef enum:
B # = 0,
ctypedef int32_t DeprecatedEnumWithNote;
ctypedef struct DeprecatedStruct:
int32_t a;
ctypedef struct DeprecatedStructWithNote:
int32_t a;
void deprecated_without_note();
void deprecated_without_bracket();
void deprecated_with_note();
void deprecated_with_note_and_since();
void deprecated_with_note_which_requires_to_be_escaped();
void dummy(DeprecatedEnum a,
DeprecatedEnumWithNote b,
DeprecatedStruct c,
DeprecatedStructWithNote d);

@ -0,0 +1,46 @@
#define DEPRECATED_FUNC __attribute__((deprecated))
#define DEPRECATED_STRUCT __attribute__((deprecated))
#define DEPRECATED_ENUM __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__)))
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
enum DEPRECATED_ENUM DeprecatedEnum {
A = 0,
};
typedef int32_t DeprecatedEnum;
enum DEPRECATED_ENUM_WITH_NOTE("This is a note") DeprecatedEnumWithNote {
B = 0,
};
typedef int32_t DeprecatedEnumWithNote;
typedef struct DEPRECATED_STRUCT DeprecatedStruct {
int32_t a;
} DeprecatedStruct;
typedef struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") DeprecatedStructWithNote {
int32_t a;
} DeprecatedStructWithNote;
DEPRECATED_FUNC void deprecated_without_note(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_without_bracket(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_with_note(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_with_note_and_since(void);
DEPRECATED_FUNC_WITH_NOTE("This quote \" requires to be quoted, and this [\n] requires to be escaped")
void deprecated_with_note_which_requires_to_be_escaped(void);
void dummy(DeprecatedEnum a,
DeprecatedEnumWithNote b,
struct DeprecatedStruct c,
struct DeprecatedStructWithNote d);

@ -0,0 +1,66 @@
#define DEPRECATED_FUNC __attribute__((deprecated))
#define DEPRECATED_STRUCT __attribute__((deprecated))
#define DEPRECATED_ENUM __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__)))
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
enum DEPRECATED_ENUM DeprecatedEnum
#ifdef __cplusplus
: int32_t
#endif // __cplusplus
{
A = 0,
};
#ifndef __cplusplus
typedef int32_t DeprecatedEnum;
#endif // __cplusplus
enum DEPRECATED_ENUM_WITH_NOTE("This is a note") DeprecatedEnumWithNote
#ifdef __cplusplus
: int32_t
#endif // __cplusplus
{
B = 0,
};
#ifndef __cplusplus
typedef int32_t DeprecatedEnumWithNote;
#endif // __cplusplus
typedef struct DEPRECATED_STRUCT DeprecatedStruct {
int32_t a;
} DeprecatedStruct;
typedef struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") DeprecatedStructWithNote {
int32_t a;
} DeprecatedStructWithNote;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
DEPRECATED_FUNC void deprecated_without_note(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_without_bracket(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_with_note(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_with_note_and_since(void);
DEPRECATED_FUNC_WITH_NOTE("This quote \" requires to be quoted, and this [\n] requires to be escaped")
void deprecated_with_note_which_requires_to_be_escaped(void);
void dummy(DeprecatedEnum a,
DeprecatedEnumWithNote b,
struct DeprecatedStruct c,
struct DeprecatedStructWithNote d);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

@ -0,0 +1,46 @@
#define DEPRECATED_FUNC __attribute__((deprecated))
#define DEPRECATED_STRUCT __attribute__((deprecated))
#define DEPRECATED_ENUM __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__)))
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
enum DEPRECATED_ENUM DeprecatedEnum {
A = 0,
};
typedef int32_t DeprecatedEnum;
enum DEPRECATED_ENUM_WITH_NOTE("This is a note") DeprecatedEnumWithNote {
B = 0,
};
typedef int32_t DeprecatedEnumWithNote;
struct DEPRECATED_STRUCT DeprecatedStruct {
int32_t a;
};
struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") DeprecatedStructWithNote {
int32_t a;
};
DEPRECATED_FUNC void deprecated_without_note(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_without_bracket(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_with_note(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_with_note_and_since(void);
DEPRECATED_FUNC_WITH_NOTE("This quote \" requires to be quoted, and this [\n] requires to be escaped")
void deprecated_with_note_which_requires_to_be_escaped(void);
void dummy(DeprecatedEnum a,
DeprecatedEnumWithNote b,
struct DeprecatedStruct c,
struct DeprecatedStructWithNote d);

@ -0,0 +1,66 @@
#define DEPRECATED_FUNC __attribute__((deprecated))
#define DEPRECATED_STRUCT __attribute__((deprecated))
#define DEPRECATED_ENUM __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__)))
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
enum DEPRECATED_ENUM DeprecatedEnum
#ifdef __cplusplus
: int32_t
#endif // __cplusplus
{
A = 0,
};
#ifndef __cplusplus
typedef int32_t DeprecatedEnum;
#endif // __cplusplus
enum DEPRECATED_ENUM_WITH_NOTE("This is a note") DeprecatedEnumWithNote
#ifdef __cplusplus
: int32_t
#endif // __cplusplus
{
B = 0,
};
#ifndef __cplusplus
typedef int32_t DeprecatedEnumWithNote;
#endif // __cplusplus
struct DEPRECATED_STRUCT DeprecatedStruct {
int32_t a;
};
struct DEPRECATED_STRUCT_WITH_NOTE("This is a note") DeprecatedStructWithNote {
int32_t a;
};
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
DEPRECATED_FUNC void deprecated_without_note(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_without_bracket(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_with_note(void);
DEPRECATED_FUNC_WITH_NOTE("This is a note") void deprecated_with_note_and_since(void);
DEPRECATED_FUNC_WITH_NOTE("This quote \" requires to be quoted, and this [\n] requires to be escaped")
void deprecated_with_note_which_requires_to_be_escaped(void);
void dummy(DeprecatedEnum a,
DeprecatedEnumWithNote b,
struct DeprecatedStruct c,
struct DeprecatedStructWithNote d);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

@ -0,0 +1,44 @@
#define DEPRECATED_FUNC __attribute__((deprecated))
#define DEPRECATED_STRUCT __attribute__((deprecated))
#define DEPRECATED_ENUM __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__)))
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
cdef extern from *:
ctypedef bint bool
ctypedef struct va_list
cdef extern from *:
cdef enum:
A # = 0,
ctypedef int32_t DeprecatedEnum;
cdef enum:
B # = 0,
ctypedef int32_t DeprecatedEnumWithNote;
cdef struct DeprecatedStruct:
int32_t a;
cdef struct DeprecatedStructWithNote:
int32_t a;
void deprecated_without_note();
void deprecated_without_bracket();
void deprecated_with_note();
void deprecated_with_note_and_since();
void deprecated_with_note_which_requires_to_be_escaped();
void dummy(DeprecatedEnum a,
DeprecatedEnumWithNote b,
DeprecatedStruct c,
DeprecatedStructWithNote d);

52
tests/rust/deprecated.rs Normal file

@ -0,0 +1,52 @@
#[no_mangle]
#[deprecated]
pub extern "C" fn deprecated_without_note() {}
#[no_mangle]
#[deprecated = "This is a note"]
pub extern "C" fn deprecated_without_bracket() {}
#[no_mangle]
#[deprecated(note = "This is a note")]
pub extern "C" fn deprecated_with_note() {}
#[no_mangle]
#[deprecated(note = "This is a note", since = "1.0.0")]
pub extern "C" fn deprecated_with_note_and_since() {}
#[no_mangle]
#[deprecated(note = "This quote \" requires to be quoted, and this [\n] requires to be escaped")]
pub extern "C" fn deprecated_with_note_which_requires_to_be_escaped() {}
#[repr(i32)]
#[deprecated]
pub enum DeprecatedEnum {
A = 0,
}
#[repr(i32)]
#[deprecated(note = "This is a note")]
pub enum DeprecatedEnumWithNote {
B = 0,
}
#[repr(C)]
#[deprecated]
pub struct DeprecatedStruct {
pub a: i32,
}
#[repr(C)]
#[deprecated(note = "This is a note")]
pub struct DeprecatedStructWithNote {
pub a: i32,
}
#[no_mangle]
pub extern "C" fn dummy(
a: DeprecatedEnum,
b: DeprecatedEnumWithNote,
c: DeprecatedStruct,
d: DeprecatedStructWithNote,
) -> void {
}

@ -0,0 +1,20 @@
header = """
#define DEPRECATED_FUNC __attribute__((deprecated))
#define DEPRECATED_STRUCT __attribute__((deprecated))
#define DEPRECATED_ENUM __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__)))
"""
[fn]
deprecated = "DEPRECATED_FUNC"
deprecated_with_note = "DEPRECATED_FUNC_WITH_NOTE({})"
[struct]
deprecated = "DEPRECATED_STRUCT"
deprecated_with_note = "DEPRECATED_STRUCT_WITH_NOTE({})"
[enum]
deprecated = "DEPRECATED_ENUM"
deprecated_with_note = "DEPRECATED_ENUM_WITH_NOTE({})"

@ -140,6 +140,9 @@ fn compile(
// clang also warns about returning non-instantiated templates (they could
// be specialized, but they're not so it's fine).
command.arg("-Wno-return-type-c-linkage");
// deprecated warnings should not be errors as it's intended
command.arg("-Wno-deprecated-declarations");
if let Language::Cxx = language {
// enum class is a c++11 extension which makes g++ on macos 10.14 error out
// inline variables are are a c++17 extension