Skip to content

Commit

Permalink
raw_const addition to #[ffi_export]-ed consts for SWIG compat (#…
Browse files Browse the repository at this point in the history
…230)

`raw_const` addition to `#[ffi_export]`-ed `const`s for SWIG compat

Co-Authored-By: Sinh Pham <phamansinh@gmail.com>

* Use dedicated `Args` type for `const`s, and rename `raw_const` as `untyped`
  • Loading branch information
danielhenrymantilla authored Jul 25, 2024
1 parent 88fef50 commit 2e844e0
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 6 deletions.
4 changes: 4 additions & 0 deletions ffi_tests/generated.cffi
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ typedef struct next_generation {
void * (*cb)(bool);
} next_generation_t;

typedef ... Opaque__str_t;

#define SOME_NAME ...

typedef enum triforce {
TRIFORCE_DIN,
TRIFORCE_FARORE,
Expand Down
9 changes: 9 additions & 0 deletions ffi_tests/generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ public unsafe struct next_generation_t {
public void_ptr_bool_fptr cb;
}

/// <summary>
/// The layout of <c>&str</c> is opaque/subject to changes.
/// </summary>
public struct Opaque__str_t {
#pragma warning disable 0169
private byte OPAQUE;
#pragma warning restore 0169
}

/// <summary>
/// Hello, <c>World</c>!
/// </summary>
Expand Down
8 changes: 8 additions & 0 deletions ffi_tests/generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ typedef struct next_generation {
void * (*cb)(bool);
} next_generation_t;

/** \brief
* The layout of `&str` is opaque/subject to changes.
*/
typedef struct Opaque__str Opaque__str_t;

/** <No documentation available> */
#define SOME_NAME "hello there"

/** \brief
* Hello, `World`!
*/
Expand Down
3 changes: 3 additions & 0 deletions ffi_tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ async fn async_get_ft ()
#[ffi_export]
pub const FOO: i32 = 42;

#[ffi_export(untyped)]
pub const SOME_NAME: &str = "hello there";

#[ffi_export]
fn _some_opaque_std_lib_type() -> repr_c::Box<String> {
Box::new(String::from("…")).into()
Expand Down
15 changes: 11 additions & 4 deletions src/headers/languages/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,17 +245,24 @@ impl HeaderLanguage for C {
docs: Docs<'_>,
name: &'_ str,
ty: &'_ dyn PhantomCType,
skip_type: bool,
value: &'_ dyn ::core::fmt::Debug,
) -> io::Result<()>
{
let ref indent = Indentation::new(4 /* ctx.indent_width() */);
mk_out!(indent, ctx.out());

self.emit_docs(ctx, docs, indent)?;
let ty = ty.name(self);
out!((
"#define {name} (({ty}) {value:?})"
));
if skip_type {
out!((
"#define {name} {value:?}"
));
} else {
let ty = ty.name(self);
out!((
"#define {name} (({ty}) {value:?})"
));
}

out!("\n");
Ok(())
Expand Down
6 changes: 6 additions & 0 deletions src/headers/languages/csharp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,15 @@ impl HeaderLanguage for CSharp {
docs: Docs<'_>,
name: &'_ str,
ty: &'_ dyn PhantomCType,
skip_type: bool,
value: &'_ dyn ::core::fmt::Debug,
) -> io::Result<()>
{
if skip_type {
// Skip the whole const for now.
// TODO: properly support constants in C#
return Ok(());
}
let ref indent = Indentation::new(4 /* ctx.indent_width() */);
mk_out!(indent, ctx.out());

Expand Down
1 change: 1 addition & 0 deletions src/headers/languages/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ trait HeaderLanguage : UpcastAny {
docs: Docs<'_>,
name: &'_ str,
ty: &'_ dyn PhantomCType,
skip_type: bool,
value: &'_ dyn ::core::fmt::Debug,
) -> io::Result<()>
;
Expand Down
1 change: 1 addition & 0 deletions src/headers/languages/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ impl HeaderLanguage for Python {
_docs: Docs<'_>,
name: &'_ str,
_ty: &'_ dyn PhantomCType,
_skip_type: bool,
_value: &'_ dyn ::core::fmt::Debug,
) -> io::Result<()>
{
Expand Down
46 changes: 45 additions & 1 deletion src/proc_macro/ffi_export/const_.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,50 @@
use super::*;

#[derive(Default)]
pub(in crate)
struct Args {
pub(in crate) untyped: Option<Untyped>,
}

pub(in crate)
struct Untyped {
pub(in crate) _kw: kw::untyped,
}

mod kw {
::syn::custom_keyword!(untyped);
}

impl Parse for Args {
fn parse (
input: ParseStream<'_>,
) -> Result<Args>
{
let mut ret = Args::default();
while input.is_empty().not() {
let snoopy = input.lookahead1();
match () {
| _case if snoopy.peek(kw::untyped) => {
if ret.untyped.is_some() {
return Err(input.error("duplicate parameter"));
}
ret.untyped = Some(Untyped {
_kw: input.parse().unwrap()
});
},

| _default => return Err(snoopy.error()),
}
let _: Option<Token![,]> = input.parse()?;
}
Ok(ret)
}
}


pub(in super)
fn handle (
_args: parse::Nothing,
Args { untyped }: Args,
input: ItemConst,
) -> Result<TokenStream2>
{
Expand All @@ -23,6 +65,7 @@ fn handle (
let VAR_str @ _ = &VAR.to_string();
let Ty @ _ = &input.ty;
let ref each_doc = utils::extract_docs(&input.attrs)?;
let skip_type = untyped.is_some();

Ok(quote!(
#input
Expand Down Expand Up @@ -64,6 +107,7 @@ fn handle (
&#ඞ::PhantomData::<
#ඞ::CLayoutOf< #Ty >,
>,
#skip_type,
&#VAR,
)
},
Expand Down
2 changes: 1 addition & 1 deletion src/proc_macro/ffi_export/fn_/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;

use args::*;
pub(in crate) use args::*;
mod args;

#[cfg(feature = "async-fn")]
Expand Down

0 comments on commit 2e844e0

Please sign in to comment.