diff --git a/src/bindgen/ir/ty.rs b/src/bindgen/ir/ty.rs index fb3c3bd..512900f 100644 --- a/src/bindgen/ir/ty.rs +++ b/src/bindgen/ir/ty.rs @@ -336,14 +336,18 @@ impl ConstExpr { pub fn load(expr: &syn::Expr) -> Result { match *expr { + syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Bool(syn::LitBool { value, .. }), + .. + }) => Ok(ConstExpr::Value(value.to_string())), syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(ref len), .. }) => Ok(ConstExpr::Value(len.base10_digits().to_string())), syn::Expr::Lit(syn::ExprLit { - lit: syn::Lit::Bool(syn::LitBool { value, .. }), + lit: syn::Lit::Byte(ref byte), .. - }) => Ok(ConstExpr::Value(value.to_string())), + }) => Ok(ConstExpr::Value(u8::to_string(&byte.value()))), syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Char(ref ch), .. diff --git a/tests/expectations/const_generics_byte.both.c b/tests/expectations/const_generics_byte.both.c new file mode 100644 index 0000000..ccfcebc --- /dev/null +++ b/tests/expectations/const_generics_byte.both.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +typedef struct Parser_40__41 { + uint8_t *buf; + uintptr_t len; +} Parser_40__41; + +typedef struct Parser_123__125 { + uint8_t *buf; + uintptr_t len; +} Parser_123__125; + +void init_parens_parser(struct Parser_40__41 *p, uint8_t *buf, uintptr_t len); + +void destroy_parens_parser(struct Parser_40__41 *p); + +void init_braces_parser(struct Parser_123__125 *p, uint8_t *buf, uintptr_t len); diff --git a/tests/expectations/const_generics_byte.both.compat.c b/tests/expectations/const_generics_byte.both.compat.c new file mode 100644 index 0000000..4d15803 --- /dev/null +++ b/tests/expectations/const_generics_byte.both.compat.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +typedef struct Parser_40__41 { + uint8_t *buf; + uintptr_t len; +} Parser_40__41; + +typedef struct Parser_123__125 { + uint8_t *buf; + uintptr_t len; +} Parser_123__125; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void init_parens_parser(struct Parser_40__41 *p, uint8_t *buf, uintptr_t len); + +void destroy_parens_parser(struct Parser_40__41 *p); + +void init_braces_parser(struct Parser_123__125 *p, uint8_t *buf, uintptr_t len); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/const_generics_byte.c b/tests/expectations/const_generics_byte.c new file mode 100644 index 0000000..fc5d5ef --- /dev/null +++ b/tests/expectations/const_generics_byte.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +typedef struct { + uint8_t *buf; + uintptr_t len; +} Parser_40__41; + +typedef struct { + uint8_t *buf; + uintptr_t len; +} Parser_123__125; + +void init_parens_parser(Parser_40__41 *p, uint8_t *buf, uintptr_t len); + +void destroy_parens_parser(Parser_40__41 *p); + +void init_braces_parser(Parser_123__125 *p, uint8_t *buf, uintptr_t len); diff --git a/tests/expectations/const_generics_byte.compat.c b/tests/expectations/const_generics_byte.compat.c new file mode 100644 index 0000000..6cf6102 --- /dev/null +++ b/tests/expectations/const_generics_byte.compat.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +typedef struct { + uint8_t *buf; + uintptr_t len; +} Parser_40__41; + +typedef struct { + uint8_t *buf; + uintptr_t len; +} Parser_123__125; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void init_parens_parser(Parser_40__41 *p, uint8_t *buf, uintptr_t len); + +void destroy_parens_parser(Parser_40__41 *p); + +void init_braces_parser(Parser_123__125 *p, uint8_t *buf, uintptr_t len); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/const_generics_byte.cpp b/tests/expectations/const_generics_byte.cpp new file mode 100644 index 0000000..118dc98 --- /dev/null +++ b/tests/expectations/const_generics_byte.cpp @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include + +template +struct Parser { + uint8_t *buf; + uintptr_t len; +}; + +extern "C" { + +void init_parens_parser(Parser<40, 41> *p, uint8_t *buf, uintptr_t len); + +void destroy_parens_parser(Parser<40, 41> *p); + +void init_braces_parser(Parser<123, 125> *p, uint8_t *buf, uintptr_t len); + +} // extern "C" diff --git a/tests/expectations/const_generics_byte.pyx b/tests/expectations/const_generics_byte.pyx new file mode 100644 index 0000000..a6099f2 --- /dev/null +++ b/tests/expectations/const_generics_byte.pyx @@ -0,0 +1,21 @@ +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 *: + + ctypedef struct Parser_40__41: + uint8_t *buf; + uintptr_t len; + + ctypedef struct Parser_123__125: + uint8_t *buf; + uintptr_t len; + + void init_parens_parser(Parser_40__41 *p, uint8_t *buf, uintptr_t len); + + void destroy_parens_parser(Parser_40__41 *p); + + void init_braces_parser(Parser_123__125 *p, uint8_t *buf, uintptr_t len); diff --git a/tests/expectations/const_generics_byte.tag.c b/tests/expectations/const_generics_byte.tag.c new file mode 100644 index 0000000..4d2d5f8 --- /dev/null +++ b/tests/expectations/const_generics_byte.tag.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +struct Parser_40__41 { + uint8_t *buf; + uintptr_t len; +}; + +struct Parser_123__125 { + uint8_t *buf; + uintptr_t len; +}; + +void init_parens_parser(struct Parser_40__41 *p, uint8_t *buf, uintptr_t len); + +void destroy_parens_parser(struct Parser_40__41 *p); + +void init_braces_parser(struct Parser_123__125 *p, uint8_t *buf, uintptr_t len); diff --git a/tests/expectations/const_generics_byte.tag.compat.c b/tests/expectations/const_generics_byte.tag.compat.c new file mode 100644 index 0000000..85172fd --- /dev/null +++ b/tests/expectations/const_generics_byte.tag.compat.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +struct Parser_40__41 { + uint8_t *buf; + uintptr_t len; +}; + +struct Parser_123__125 { + uint8_t *buf; + uintptr_t len; +}; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void init_parens_parser(struct Parser_40__41 *p, uint8_t *buf, uintptr_t len); + +void destroy_parens_parser(struct Parser_40__41 *p); + +void init_braces_parser(struct Parser_123__125 *p, uint8_t *buf, uintptr_t len); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/const_generics_byte.tag.pyx b/tests/expectations/const_generics_byte.tag.pyx new file mode 100644 index 0000000..6b91ced --- /dev/null +++ b/tests/expectations/const_generics_byte.tag.pyx @@ -0,0 +1,21 @@ +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 struct Parser_40__41: + uint8_t *buf; + uintptr_t len; + + cdef struct Parser_123__125: + uint8_t *buf; + uintptr_t len; + + void init_parens_parser(Parser_40__41 *p, uint8_t *buf, uintptr_t len); + + void destroy_parens_parser(Parser_40__41 *p); + + void init_braces_parser(Parser_123__125 *p, uint8_t *buf, uintptr_t len); diff --git a/tests/rust/const_generics_byte.rs b/tests/rust/const_generics_byte.rs new file mode 100644 index 0000000..e150567 --- /dev/null +++ b/tests/rust/const_generics_byte.rs @@ -0,0 +1,29 @@ +// Name mangling can cope with char-like byte literals. + +#[repr(C)] +pub struct Parser { + pub buf: *mut u8, + pub len: usize, +} + +#[no_mangle] +pub unsafe extern "C" fn init_parens_parser(p: *mut Parser, buf: *mut u8, len: usize) { + unsafe { + *p = Parser { buf, len }; + } +} + +// The same type as above, because `b'(' == 40 && b')' == 41`. And it happens +// to mangle to the same C identifier. It doesn't always work out that way! +#[no_mangle] +pub unsafe extern "C" fn destroy_parens_parser(p: *mut Parser<40, 41>) { + // nothing to do +} + + +#[no_mangle] +pub unsafe extern "C" fn init_braces_parser(p: *mut Parser, buf: *mut u8, len: usize) { + unsafe { + *p = Parser { buf, len }; + } +}