generate bindings for non-public extern items
Signed-off-by: Marin Veršić <marin.versic101@gmail.com>
This commit is contained in:
committed by
Emilio Cobos Álvarez
parent
acb1b8d89e
commit
5f235ec199
@@ -4,8 +4,6 @@
|
||||
|
||||
use std::io::Write;
|
||||
|
||||
use syn::ext::IdentExt;
|
||||
|
||||
use crate::bindgen::cdecl;
|
||||
use crate::bindgen::config::Config;
|
||||
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
@@ -26,7 +24,11 @@ pub struct Static {
|
||||
}
|
||||
|
||||
impl Static {
|
||||
pub fn load(item: &syn::ItemStatic, mod_cfg: Option<&Cfg>) -> Result<Static, String> {
|
||||
pub fn load(
|
||||
path: Path,
|
||||
item: &syn::ItemStatic,
|
||||
mod_cfg: Option<&Cfg>,
|
||||
) -> Result<Static, String> {
|
||||
let ty = Type::load(&item.ty)?;
|
||||
|
||||
if ty.is_none() {
|
||||
@@ -34,7 +36,7 @@ impl Static {
|
||||
}
|
||||
|
||||
Ok(Static::new(
|
||||
Path::new(item.ident.unraw().to_string()),
|
||||
path,
|
||||
ty.unwrap(),
|
||||
item.mutability.is_some(),
|
||||
Cfg::append(mod_cfg, Cfg::load(&item.attrs)),
|
||||
|
||||
+30
-66
@@ -18,7 +18,7 @@ use crate::bindgen::ir::{
|
||||
AnnotationSet, Cfg, Constant, Documentation, Enum, Function, GenericParam, GenericParams,
|
||||
ItemMap, OpaqueItem, Path, Static, Struct, Type, Typedef, Union,
|
||||
};
|
||||
use crate::bindgen::utilities::{SynAbiHelpers, SynAttributeHelpers, SynItemFnHelpers};
|
||||
use crate::bindgen::utilities::{SynAbiHelpers, SynAttributeHelpers, SynItemHelpers};
|
||||
|
||||
const STD_CRATES: &[&str] = &[
|
||||
"std",
|
||||
@@ -643,7 +643,6 @@ impl Parse {
|
||||
item,
|
||||
Some(self_type),
|
||||
&item.sig,
|
||||
&item.vis,
|
||||
&item.attrs,
|
||||
)
|
||||
}
|
||||
@@ -665,7 +664,6 @@ impl Parse {
|
||||
item,
|
||||
None,
|
||||
&item.sig,
|
||||
&item.vis,
|
||||
&item.attrs,
|
||||
);
|
||||
}
|
||||
@@ -677,10 +675,9 @@ impl Parse {
|
||||
binding_crate_name: &str,
|
||||
crate_name: &str,
|
||||
mod_cfg: Option<&Cfg>,
|
||||
named_symbol: &dyn SynItemFnHelpers,
|
||||
named_symbol: &dyn SynItemHelpers,
|
||||
self_type: Option<&Path>,
|
||||
sig: &syn::Signature,
|
||||
vis: &syn::Visibility,
|
||||
attrs: &[syn::Attribute],
|
||||
) {
|
||||
if !config
|
||||
@@ -707,53 +704,29 @@ impl Parse {
|
||||
let is_extern_c = sig.abi.is_omitted() || sig.abi.is_c();
|
||||
let exported_name = named_symbol.exported_name();
|
||||
|
||||
if let syn::Visibility::Public(_) = vis {
|
||||
match (is_extern_c, exported_name) {
|
||||
(true, Some(exported_name)) => {
|
||||
let path = Path::new(exported_name);
|
||||
match Function::load(path, self_type, sig, false, attrs, mod_cfg) {
|
||||
Ok(func) => {
|
||||
info!("Take {}.", loggable_item_name());
|
||||
self.functions.push(func);
|
||||
}
|
||||
Err(msg) => {
|
||||
error!("Cannot use fn {} ({}).", loggable_item_name(), msg);
|
||||
}
|
||||
match (is_extern_c, exported_name) {
|
||||
(true, Some(exported_name)) => {
|
||||
let path = Path::new(exported_name);
|
||||
match Function::load(path, self_type, sig, false, attrs, mod_cfg) {
|
||||
Ok(func) => {
|
||||
info!("Take {}.", loggable_item_name());
|
||||
self.functions.push(func);
|
||||
}
|
||||
Err(msg) => {
|
||||
error!("Cannot use fn {} ({}).", loggable_item_name(), msg);
|
||||
}
|
||||
}
|
||||
(true, None) => {
|
||||
warn!(
|
||||
"Skipping {} - (not `no_mangle`, and has no `export_name` attribute)",
|
||||
loggable_item_name()
|
||||
);
|
||||
}
|
||||
(false, Some(_exported_name)) => {
|
||||
warn!("Skipping {} - (not `extern \"C\"`", loggable_item_name());
|
||||
}
|
||||
(false, None) => {}
|
||||
}
|
||||
} else {
|
||||
match (is_extern_c, exported_name) {
|
||||
(true, Some(..)) => {
|
||||
warn!(
|
||||
"Skipping {} - (not `pub` but is `extern \"C\"` and `no_mangle`)",
|
||||
loggable_item_name()
|
||||
);
|
||||
}
|
||||
(true, None) => {
|
||||
warn!(
|
||||
"Skipping {} - (not `pub` but is `extern \"C\"`)",
|
||||
loggable_item_name()
|
||||
);
|
||||
}
|
||||
(false, Some(..)) => {
|
||||
warn!(
|
||||
"Skipping {} - (not `pub` but is `no_mangle`)",
|
||||
loggable_item_name()
|
||||
);
|
||||
}
|
||||
(false, None) => {}
|
||||
(true, None) => {
|
||||
warn!(
|
||||
"Skipping {} - (not `no_mangle`, and has no `export_name` attribute)",
|
||||
loggable_item_name()
|
||||
);
|
||||
}
|
||||
(false, Some(_exported_name)) => {
|
||||
warn!("Skipping {} - (not `extern \"C\"`", loggable_item_name());
|
||||
}
|
||||
(false, None) => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -892,27 +865,18 @@ impl Parse {
|
||||
return;
|
||||
}
|
||||
|
||||
if let syn::Visibility::Public(_) = item.vis {
|
||||
if item.is_no_mangle() {
|
||||
match Static::load(item, mod_cfg) {
|
||||
Ok(constant) => {
|
||||
info!("Take {}::{}.", crate_name, &item.ident);
|
||||
|
||||
self.globals.try_insert(constant);
|
||||
}
|
||||
Err(msg) => {
|
||||
warn!("Skip {}::{} - ({})", crate_name, &item.ident, msg);
|
||||
}
|
||||
if let Some(exported_name) = item.exported_name() {
|
||||
let path = Path::new(exported_name);
|
||||
match Static::load(path, item, mod_cfg) {
|
||||
Ok(constant) => {
|
||||
info!("Take {}::{}.", crate_name, &item.ident);
|
||||
self.globals.try_insert(constant);
|
||||
}
|
||||
Err(msg) => {
|
||||
warn!("Skip {}::{} - ({})", crate_name, &item.ident, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
if let syn::Visibility::Public(_) = item.vis {
|
||||
} else {
|
||||
warn!("Skip {}::{} - (not `pub`).", crate_name, &item.ident);
|
||||
}
|
||||
if !item.is_no_mangle() {
|
||||
warn!("Skip {}::{} - (not `no_mangle`).", crate_name, &item.ident);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +30,11 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub trait SynItemFnHelpers: SynAttributeHelpers {
|
||||
pub trait SynItemHelpers: SynAttributeHelpers {
|
||||
fn exported_name(&self) -> Option<String>;
|
||||
}
|
||||
|
||||
impl SynItemFnHelpers for syn::ItemFn {
|
||||
impl SynItemHelpers for syn::ItemFn {
|
||||
fn exported_name(&self) -> Option<String> {
|
||||
self.attrs
|
||||
.attr_name_value_lookup("export_name")
|
||||
@@ -48,7 +48,7 @@ impl SynItemFnHelpers for syn::ItemFn {
|
||||
}
|
||||
}
|
||||
|
||||
impl SynItemFnHelpers for syn::ImplItemMethod {
|
||||
impl SynItemHelpers for syn::ImplItemMethod {
|
||||
fn exported_name(&self) -> Option<String> {
|
||||
self.attrs
|
||||
.attr_name_value_lookup("export_name")
|
||||
@@ -62,6 +62,20 @@ impl SynItemFnHelpers for syn::ImplItemMethod {
|
||||
}
|
||||
}
|
||||
|
||||
impl SynItemHelpers for syn::ItemStatic {
|
||||
fn exported_name(&self) -> Option<String> {
|
||||
self.attrs
|
||||
.attr_name_value_lookup("export_name")
|
||||
.or_else(|| {
|
||||
if self.is_no_mangle() {
|
||||
Some(self.ident.unraw().to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether this attribute causes us to skip at item. This basically
|
||||
/// checks for `#[cfg(test)]`, `#[test]`, `/// cbindgen::ignore` and
|
||||
/// variations thereof.
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern const uint32_t FIRST;
|
||||
|
||||
extern const uint32_t RENAMED;
|
||||
|
||||
void first(void);
|
||||
|
||||
void renamed(void);
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
extern const uint32_t FIRST;
|
||||
|
||||
extern const uint32_t RENAMED;
|
||||
|
||||
void first(void);
|
||||
|
||||
void renamed(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
@@ -0,0 +1,17 @@
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <ostream>
|
||||
#include <new>
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern const uint32_t FIRST;
|
||||
|
||||
extern const uint32_t RENAMED;
|
||||
|
||||
void first();
|
||||
|
||||
void renamed();
|
||||
|
||||
} // extern "C"
|
||||
@@ -0,0 +1,15 @@
|
||||
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 *:
|
||||
|
||||
extern const uint32_t FIRST;
|
||||
|
||||
extern const uint32_t RENAMED;
|
||||
|
||||
void first();
|
||||
|
||||
void renamed();
|
||||
@@ -0,0 +1,13 @@
|
||||
#[no_mangle]
|
||||
static FIRST: u32 = 10;
|
||||
|
||||
#[export_name = "RENAMED"]
|
||||
static SECOND: u32 = 42;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn first()
|
||||
{ }
|
||||
|
||||
#[export_name = "renamed"]
|
||||
extern fn second()
|
||||
{ }
|
||||
Reference in New Issue
Block a user