Add support for an optional attribute on pointers whose nullability can be inferred from the Rust type.

This commit is contained in:
Nick Wilcox
2020-08-02 17:34:29 +10:00
committed by Emilio Cobos Álvarez
parent 3527e0f1e3
commit 41b7866c14
14 changed files with 549 additions and 14 deletions
+4
View File
@@ -476,6 +476,10 @@ tab_width = 3
# default: "auto"
documentation_style = "doxy"
# An optional string that, if present, will decorate all pointers that are
# required to be non null. Nullability is inferred from the Rust type: `&T`,
# `&mut T` and `NonNull<T>` are all require a valid pointer value.
non_null_attribute = "_Nonnull"
+22 -8
View File
@@ -14,7 +14,7 @@ use crate::bindgen::{Config, Language};
// http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
enum CDeclarator {
Ptr(bool),
Ptr(bool, bool),
Ref,
Array(String),
Func(Vec<(Option<String>, CDecl)>, bool),
@@ -115,13 +115,21 @@ impl CDecl {
}
Type::ConstPtr(ref t) => {
self.declarators.push(CDeclarator::Ptr(is_const));
self.declarators.push(CDeclarator::Ptr(is_const, false));
self.build_type(t, true);
}
Type::Ptr(ref t) => {
self.declarators.push(CDeclarator::Ptr(is_const));
self.declarators.push(CDeclarator::Ptr(is_const, false));
self.build_type(t, false);
}
Type::NonNullPtr(ref t) => {
self.declarators.push(CDeclarator::Ptr(is_const, true));
self.build_type(t, false);
}
Type::ConstNonNullPtr(ref t) => {
self.declarators.push(CDeclarator::Ptr(is_const, true));
self.build_type(t, true);
}
Type::Ref(ref t) => {
self.declarators.push(CDeclarator::Ref);
self.build_type(t, true);
@@ -140,7 +148,7 @@ impl CDecl {
.iter()
.map(|(ref name, ref ty)| (name.clone(), CDecl::from_type(ty)))
.collect();
self.declarators.push(CDeclarator::Ptr(false));
self.declarators.push(CDeclarator::Ptr(false, false));
self.declarators.push(CDeclarator::Func(args, false));
self.build_type(ret, false);
}
@@ -178,11 +186,17 @@ impl CDecl {
let next_is_pointer = iter_rev.peek().map_or(false, |x| x.is_ptr());
match *declarator {
CDeclarator::Ptr(ref is_const) => {
if *is_const {
out.write("*const ");
CDeclarator::Ptr(ref is_const, ref is_nonnull) => {
let non_null_attribute = if *is_nonnull {
config.non_null_attribute.as_ref()
} else {
out.write("*");
None
};
match (non_null_attribute, is_const) {
(None, true) => out.write("*const "),
(None, false) => out.write("*"),
(Some(attr), true) => write!(out, "*const {} ", attr),
(Some(attr), false) => write!(out, "* {} ", attr),
}
}
CDeclarator::Ref => {
+3
View File
@@ -765,6 +765,8 @@ pub struct Config {
pub documentation: bool,
/// How documentation comments should be styled.
pub documentation_style: DocumentationStyle,
/// Optional attribute to apply to pointers that are required to not be null
pub non_null_attribute: Option<String>,
}
impl Default for Config {
@@ -800,6 +802,7 @@ impl Default for Config {
defines: HashMap::new(),
documentation: true,
documentation_style: DocumentationStyle::Auto,
non_null_attribute: None,
}
}
}
+61 -4
View File
@@ -211,6 +211,8 @@ impl ArrayLength {
pub enum Type {
ConstPtr(Box<Type>),
Ptr(Box<Type>),
ConstNonNullPtr(Box<Type>),
NonNullPtr(Box<Type>),
Ref(Box<Type>),
MutRef(Box<Type>),
Path(GenericPath),
@@ -235,8 +237,8 @@ impl Type {
};
match reference.mutability {
Some(_) => Type::Ptr(Box::new(converted)),
None => Type::ConstPtr(Box::new(converted)),
Some(_) => Type::NonNullPtr(Box::new(converted)),
None => Type::ConstNonNullPtr(Box::new(converted)),
}
}
syn::Type::Ptr(ref pointer) => {
@@ -369,12 +371,25 @@ impl Type {
pub fn is_repr_ptr(&self) -> bool {
match *self {
Type::Ptr(..) => true,
Type::NonNullPtr(..) => true,
Type::ConstPtr(..) => true,
Type::ConstNonNullPtr(..) => true,
Type::FuncPtr(..) => true,
_ => false,
}
}
pub fn make_nullable(&self) -> Option<Self> {
match self.clone() {
Type::Ptr(x) => Some(Type::Ptr(x)),
Type::NonNullPtr(x) => Some(Type::Ptr(x)),
Type::ConstPtr(x) => Some(Type::ConstPtr(x)),
Type::ConstNonNullPtr(x) => Some(Type::ConstPtr(x)),
Type::FuncPtr(x, y) => Some(Type::FuncPtr(x, y)),
_ => None,
}
}
fn simplified_type(&self) -> Option<Self> {
let path = match *self {
Type::Path(ref p) => p,
@@ -390,8 +405,8 @@ impl Type {
match path.name() {
// FIXME(#223): This is not quite correct.
"Option" if generic.is_repr_ptr() => Some(generic),
"NonNull" => Some(Type::Ptr(Box::new(generic))),
"Option" if generic.is_repr_ptr() => generic.make_nullable(),
"NonNull" => Some(Type::NonNullPtr(Box::new(generic))),
"Cell" => Some(generic),
_ => None,
}
@@ -409,6 +424,8 @@ impl Type {
| Type::MutRef(ref mut ty)
| Type::Ref(ref mut ty)
| Type::Ptr(ref mut ty)
| Type::NonNullPtr(ref mut ty)
| Type::ConstNonNullPtr(ref mut ty)
| Type::ConstPtr(ref mut ty) => ty.replace_self_with(self_ty),
Type::Path(ref mut generic_path) => {
generic_path.replace_self_with(self_ty);
@@ -429,6 +446,8 @@ impl Type {
match *current {
Type::ConstPtr(ref ty) => current = ty,
Type::Ptr(ref ty) => current = ty,
Type::NonNullPtr(ref ty) => current = ty,
Type::ConstNonNullPtr(ref ty) => current = ty,
Type::Ref(ref ty) => current = ty,
Type::MutRef(ref ty) => current = ty,
Type::Path(ref generic) => {
@@ -451,6 +470,10 @@ impl Type {
match *self {
Type::ConstPtr(ref ty) => Type::ConstPtr(Box::new(ty.specialize(mappings))),
Type::Ptr(ref ty) => Type::Ptr(Box::new(ty.specialize(mappings))),
Type::NonNullPtr(ref ty) => Type::NonNullPtr(Box::new(ty.specialize(mappings))),
Type::ConstNonNullPtr(ref ty) => {
Type::ConstNonNullPtr(Box::new(ty.specialize(mappings)))
}
Type::Ref(ref ty) => Type::Ref(Box::new(ty.specialize(mappings))),
Type::MutRef(ref ty) => Type::MutRef(Box::new(ty.specialize(mappings))),
Type::Path(ref generic_path) => {
@@ -497,6 +520,12 @@ impl Type {
Type::Ptr(ref ty) => {
ty.add_dependencies_ignoring_generics(generic_params, library, out);
}
Type::NonNullPtr(ref ty) => {
ty.add_dependencies_ignoring_generics(generic_params, library, out);
}
Type::ConstNonNullPtr(ref ty) => {
ty.add_dependencies_ignoring_generics(generic_params, library, out);
}
Type::Ref(ref ty) | Type::MutRef(ref ty) => {
ty.add_dependencies_ignoring_generics(generic_params, library, out);
}
@@ -551,6 +580,12 @@ impl Type {
Type::Ptr(ref ty) => {
ty.add_monomorphs(library, out);
}
Type::NonNullPtr(ref ty) => {
ty.add_monomorphs(library, out);
}
Type::ConstNonNullPtr(ref ty) => {
ty.add_monomorphs(library, out);
}
Type::Ref(ref ty) | Type::MutRef(ref ty) => {
ty.add_monomorphs(library, out);
}
@@ -587,6 +622,12 @@ impl Type {
Type::Ptr(ref mut ty) => {
ty.rename_for_config(config, generic_params);
}
Type::NonNullPtr(ref mut ty) => {
ty.rename_for_config(config, generic_params);
}
Type::ConstNonNullPtr(ref mut ty) => {
ty.rename_for_config(config, generic_params);
}
Type::Ref(ref mut ty) | Type::MutRef(ref mut ty) => {
ty.rename_for_config(config, generic_params);
}
@@ -615,6 +656,12 @@ impl Type {
Type::Ptr(ref mut ty) => {
ty.resolve_declaration_types(resolver);
}
Type::NonNullPtr(ref mut ty) => {
ty.resolve_declaration_types(resolver);
}
Type::ConstNonNullPtr(ref mut ty) => {
ty.resolve_declaration_types(resolver);
}
Type::Ref(ref mut ty) | Type::MutRef(ref mut ty) => {
ty.resolve_declaration_types(resolver);
}
@@ -642,6 +689,12 @@ impl Type {
Type::Ptr(ref mut ty) => {
ty.mangle_paths(monomorphs);
}
Type::NonNullPtr(ref mut ty) => {
ty.mangle_paths(monomorphs);
}
Type::ConstNonNullPtr(ref mut ty) => {
ty.mangle_paths(monomorphs);
}
Type::Ref(ref mut ty) | Type::MutRef(ref mut ty) => {
ty.mangle_paths(monomorphs);
}
@@ -677,6 +730,8 @@ impl Type {
match *self {
Type::ConstPtr(..) => true,
Type::Ptr(..) => true,
Type::NonNullPtr(..) => true,
Type::ConstNonNullPtr(..) => true,
Type::Ref(..) | Type::MutRef(..) => false,
Type::Path(..) => true,
Type::Primitive(ref p) => p.can_cmp_order(),
@@ -689,6 +744,8 @@ impl Type {
match *self {
Type::ConstPtr(..) => true,
Type::Ptr(..) => true,
Type::NonNullPtr(..) => true,
Type::ConstNonNullPtr(..) => true,
Type::Ref(..) | Type::MutRef(..) => false,
Type::Path(..) => true,
Type::Primitive(ref p) => p.can_cmp_eq(),
+2 -2
View File
@@ -58,11 +58,11 @@ impl<'a> Mangler<'a> {
Type::Primitive(ref primitive) => {
self.output.push_str(primitive.to_repr_rust());
}
Type::Ptr(ref ty) | Type::MutRef(ref ty) => {
Type::Ptr(ref ty) | Type::MutRef(ref ty) | Type::NonNullPtr(ref ty) => {
self.push(Separator::BeginMutPtr);
self.append_mangled_type(&**ty, last);
}
Type::ConstPtr(ref ty) | Type::Ref(ref ty) => {
Type::ConstPtr(ref ty) | Type::Ref(ref ty) | Type::ConstNonNullPtr(ref ty) => {
self.push(Separator::BeginConstPtr);
self.append_mangled_type(&**ty, last);
}
@@ -0,0 +1,52 @@
#ifdef __clang__
#define CBINDGEN_NONNULL _Nonnull
#else
#define CBINDGEN_NONNULL
#endif
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct Opaque Opaque;
typedef struct Pointers_u64 {
float * CBINDGEN_NONNULL a;
uint64_t * CBINDGEN_NONNULL b;
Opaque * CBINDGEN_NONNULL c;
uint64_t * CBINDGEN_NONNULL * CBINDGEN_NONNULL d;
float * CBINDGEN_NONNULL * CBINDGEN_NONNULL e;
Opaque * CBINDGEN_NONNULL * CBINDGEN_NONNULL f;
uint64_t *g;
int32_t *h;
int32_t * CBINDGEN_NONNULL *i;
const uint64_t *j;
uint64_t *k;
} Pointers_u64;
typedef struct References {
const Opaque * CBINDGEN_NONNULL a;
Opaque * CBINDGEN_NONNULL b;
const Opaque *c;
Opaque *d;
} References;
void mut_ref_arg(const Pointers_u64 * CBINDGEN_NONNULL arg);
void mutltiple_args(int32_t * CBINDGEN_NONNULL arg,
Pointers_u64 *foo,
Opaque * CBINDGEN_NONNULL * CBINDGEN_NONNULL d);
void nullable_const_ptr(const Pointers_u64 *arg);
void nullable_mut_ptr(Pointers_u64 *arg);
void optional_mut_ref_arg(const Pointers_u64 *arg);
void optional_ref_arg(Pointers_u64 *arg);
void ref_arg(Pointers_u64 * CBINDGEN_NONNULL arg);
void value_arg(References arg);
@@ -0,0 +1,60 @@
#ifdef __clang__
#define CBINDGEN_NONNULL _Nonnull
#else
#define CBINDGEN_NONNULL
#endif
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct Opaque Opaque;
typedef struct Pointers_u64 {
float * CBINDGEN_NONNULL a;
uint64_t * CBINDGEN_NONNULL b;
Opaque * CBINDGEN_NONNULL c;
uint64_t * CBINDGEN_NONNULL * CBINDGEN_NONNULL d;
float * CBINDGEN_NONNULL * CBINDGEN_NONNULL e;
Opaque * CBINDGEN_NONNULL * CBINDGEN_NONNULL f;
uint64_t *g;
int32_t *h;
int32_t * CBINDGEN_NONNULL *i;
const uint64_t *j;
uint64_t *k;
} Pointers_u64;
typedef struct References {
const Opaque * CBINDGEN_NONNULL a;
Opaque * CBINDGEN_NONNULL b;
const Opaque *c;
Opaque *d;
} References;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void mut_ref_arg(const Pointers_u64 * CBINDGEN_NONNULL arg);
void mutltiple_args(int32_t * CBINDGEN_NONNULL arg,
Pointers_u64 *foo,
Opaque * CBINDGEN_NONNULL * CBINDGEN_NONNULL d);
void nullable_const_ptr(const Pointers_u64 *arg);
void nullable_mut_ptr(Pointers_u64 *arg);
void optional_mut_ref_arg(const Pointers_u64 *arg);
void optional_ref_arg(Pointers_u64 *arg);
void ref_arg(Pointers_u64 * CBINDGEN_NONNULL arg);
void value_arg(References arg);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+52
View File
@@ -0,0 +1,52 @@
#ifdef __clang__
#define CBINDGEN_NONNULL _Nonnull
#else
#define CBINDGEN_NONNULL
#endif
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct Opaque Opaque;
typedef struct {
float * CBINDGEN_NONNULL a;
uint64_t * CBINDGEN_NONNULL b;
Opaque * CBINDGEN_NONNULL c;
uint64_t * CBINDGEN_NONNULL * CBINDGEN_NONNULL d;
float * CBINDGEN_NONNULL * CBINDGEN_NONNULL e;
Opaque * CBINDGEN_NONNULL * CBINDGEN_NONNULL f;
uint64_t *g;
int32_t *h;
int32_t * CBINDGEN_NONNULL *i;
const uint64_t *j;
uint64_t *k;
} Pointers_u64;
typedef struct {
const Opaque * CBINDGEN_NONNULL a;
Opaque * CBINDGEN_NONNULL b;
const Opaque *c;
Opaque *d;
} References;
void mut_ref_arg(const Pointers_u64 * CBINDGEN_NONNULL arg);
void mutltiple_args(int32_t * CBINDGEN_NONNULL arg,
Pointers_u64 *foo,
Opaque * CBINDGEN_NONNULL * CBINDGEN_NONNULL d);
void nullable_const_ptr(const Pointers_u64 *arg);
void nullable_mut_ptr(Pointers_u64 *arg);
void optional_mut_ref_arg(const Pointers_u64 *arg);
void optional_ref_arg(Pointers_u64 *arg);
void ref_arg(Pointers_u64 * CBINDGEN_NONNULL arg);
void value_arg(References arg);
@@ -0,0 +1,60 @@
#ifdef __clang__
#define CBINDGEN_NONNULL _Nonnull
#else
#define CBINDGEN_NONNULL
#endif
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct Opaque Opaque;
typedef struct {
float * CBINDGEN_NONNULL a;
uint64_t * CBINDGEN_NONNULL b;
Opaque * CBINDGEN_NONNULL c;
uint64_t * CBINDGEN_NONNULL * CBINDGEN_NONNULL d;
float * CBINDGEN_NONNULL * CBINDGEN_NONNULL e;
Opaque * CBINDGEN_NONNULL * CBINDGEN_NONNULL f;
uint64_t *g;
int32_t *h;
int32_t * CBINDGEN_NONNULL *i;
const uint64_t *j;
uint64_t *k;
} Pointers_u64;
typedef struct {
const Opaque * CBINDGEN_NONNULL a;
Opaque * CBINDGEN_NONNULL b;
const Opaque *c;
Opaque *d;
} References;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void mut_ref_arg(const Pointers_u64 * CBINDGEN_NONNULL arg);
void mutltiple_args(int32_t * CBINDGEN_NONNULL arg,
Pointers_u64 *foo,
Opaque * CBINDGEN_NONNULL * CBINDGEN_NONNULL d);
void nullable_const_ptr(const Pointers_u64 *arg);
void nullable_mut_ptr(Pointers_u64 *arg);
void optional_mut_ref_arg(const Pointers_u64 *arg);
void optional_ref_arg(Pointers_u64 *arg);
void ref_arg(Pointers_u64 * CBINDGEN_NONNULL arg);
void value_arg(References arg);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+57
View File
@@ -0,0 +1,57 @@
#ifdef __clang__
#define CBINDGEN_NONNULL _Nonnull
#else
#define CBINDGEN_NONNULL
#endif
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <new>
struct Opaque;
template<typename T>
struct Pointers {
float * CBINDGEN_NONNULL a;
T * CBINDGEN_NONNULL b;
Opaque * CBINDGEN_NONNULL c;
T * CBINDGEN_NONNULL * CBINDGEN_NONNULL d;
float * CBINDGEN_NONNULL * CBINDGEN_NONNULL e;
Opaque * CBINDGEN_NONNULL * CBINDGEN_NONNULL f;
T *g;
int32_t *h;
int32_t * CBINDGEN_NONNULL *i;
const T *j;
T *k;
};
struct References {
const Opaque * CBINDGEN_NONNULL a;
Opaque * CBINDGEN_NONNULL b;
const Opaque *c;
Opaque *d;
};
extern "C" {
void mut_ref_arg(const Pointers<uint64_t> * CBINDGEN_NONNULL arg);
void mutltiple_args(int32_t * CBINDGEN_NONNULL arg,
Pointers<uint64_t> *foo,
Opaque * CBINDGEN_NONNULL * CBINDGEN_NONNULL d);
void nullable_const_ptr(const Pointers<uint64_t> *arg);
void nullable_mut_ptr(Pointers<uint64_t> *arg);
void optional_mut_ref_arg(const Pointers<uint64_t> *arg);
void optional_ref_arg(Pointers<uint64_t> *arg);
void ref_arg(Pointers<uint64_t> * CBINDGEN_NONNULL arg);
void value_arg(References arg);
} // extern "C"
@@ -0,0 +1,52 @@
#ifdef __clang__
#define CBINDGEN_NONNULL _Nonnull
#else
#define CBINDGEN_NONNULL
#endif
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
struct Opaque;
struct Pointers_u64 {
float * CBINDGEN_NONNULL a;
uint64_t * CBINDGEN_NONNULL b;
struct Opaque * CBINDGEN_NONNULL c;
uint64_t * CBINDGEN_NONNULL * CBINDGEN_NONNULL d;
float * CBINDGEN_NONNULL * CBINDGEN_NONNULL e;
struct Opaque * CBINDGEN_NONNULL * CBINDGEN_NONNULL f;
uint64_t *g;
int32_t *h;
int32_t * CBINDGEN_NONNULL *i;
const uint64_t *j;
uint64_t *k;
};
struct References {
const struct Opaque * CBINDGEN_NONNULL a;
struct Opaque * CBINDGEN_NONNULL b;
const struct Opaque *c;
struct Opaque *d;
};
void mut_ref_arg(const struct Pointers_u64 * CBINDGEN_NONNULL arg);
void mutltiple_args(int32_t * CBINDGEN_NONNULL arg,
struct Pointers_u64 *foo,
struct Opaque * CBINDGEN_NONNULL * CBINDGEN_NONNULL d);
void nullable_const_ptr(const struct Pointers_u64 *arg);
void nullable_mut_ptr(struct Pointers_u64 *arg);
void optional_mut_ref_arg(const struct Pointers_u64 *arg);
void optional_ref_arg(struct Pointers_u64 *arg);
void ref_arg(struct Pointers_u64 * CBINDGEN_NONNULL arg);
void value_arg(struct References arg);
@@ -0,0 +1,60 @@
#ifdef __clang__
#define CBINDGEN_NONNULL _Nonnull
#else
#define CBINDGEN_NONNULL
#endif
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
struct Opaque;
struct Pointers_u64 {
float * CBINDGEN_NONNULL a;
uint64_t * CBINDGEN_NONNULL b;
struct Opaque * CBINDGEN_NONNULL c;
uint64_t * CBINDGEN_NONNULL * CBINDGEN_NONNULL d;
float * CBINDGEN_NONNULL * CBINDGEN_NONNULL e;
struct Opaque * CBINDGEN_NONNULL * CBINDGEN_NONNULL f;
uint64_t *g;
int32_t *h;
int32_t * CBINDGEN_NONNULL *i;
const uint64_t *j;
uint64_t *k;
};
struct References {
const struct Opaque * CBINDGEN_NONNULL a;
struct Opaque * CBINDGEN_NONNULL b;
const struct Opaque *c;
struct Opaque *d;
};
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void mut_ref_arg(const struct Pointers_u64 * CBINDGEN_NONNULL arg);
void mutltiple_args(int32_t * CBINDGEN_NONNULL arg,
struct Pointers_u64 *foo,
struct Opaque * CBINDGEN_NONNULL * CBINDGEN_NONNULL d);
void nullable_const_ptr(const struct Pointers_u64 *arg);
void nullable_mut_ptr(struct Pointers_u64 *arg);
void optional_mut_ref_arg(const struct Pointers_u64 *arg);
void optional_ref_arg(struct Pointers_u64 *arg);
void ref_arg(struct Pointers_u64 * CBINDGEN_NONNULL arg);
void value_arg(struct References arg);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+55
View File
@@ -0,0 +1,55 @@
use std::ptr::NonNull;
struct Opaque;
#[repr(C)]
pub struct Pointers<T> {
a: NonNull<f32>,
b: NonNull<T>,
c: NonNull<Opaque>,
d: NonNull<NonNull<T>>,
e: NonNull<NonNull<f32>>,
f: NonNull<NonNull<Opaque>>,
g: Option<NonNull<T>>,
h: Option<NonNull<i32>>,
i: Option<NonNull<NonNull<i32>>>,
j: *const T,
k: *mut T,
}
#[repr(C)]
pub struct References<'a> {
a: &'a Opaque,
b: &'a mut Opaque,
c: Option<&'a Opaque>,
d: Option<&'a mut Opaque>,
}
#[no_mangle]
pub extern "C" fn value_arg(arg: References<'static>) {}
#[no_mangle]
pub extern "C" fn mutltiple_args(
arg: NonNull<i32>,
foo: *mut Pointers<u64>,
d: NonNull<NonNull<Opaque>>,
) {
}
#[no_mangle]
pub extern "C" fn mut_ref_arg(arg: &Pointers<u64>) {}
#[no_mangle]
pub extern "C" fn ref_arg(arg: &mut Pointers<u64>) {}
#[no_mangle]
pub extern "C" fn optional_mut_ref_arg(arg: Option<&Pointers<u64>>) {}
#[no_mangle]
pub extern "C" fn optional_ref_arg(arg: Option<&mut Pointers<u64>>) {}
#[no_mangle]
pub extern "C" fn nullable_const_ptr(arg: *const Pointers<u64>) {}
#[no_mangle]
pub extern "C" fn nullable_mut_ptr(arg: *mut Pointers<u64>) {}
+9
View File
@@ -0,0 +1,9 @@
header = """
#ifdef __clang__
#define CBINDGEN_NONNULL _Nonnull
#else
#define CBINDGEN_NONNULL
#endif
"""
non_null_attribute = "CBINDGEN_NONNULL"