Add docs, move mangling configuration to its own place, add integration tests.

This commit is contained in:
Emilio Cobos Álvarez
2020-09-22 12:01:47 +02:00
parent 0005ad1f24
commit 18110669fc
18 changed files with 205 additions and 87 deletions
+8
View File
@@ -591,6 +591,14 @@ private:
void cppMethod() const;
"""
# Configuration for name mangling
[export.mangle]
# Whether the types should be renamed during mangling, for example
# c_char -> CChar, etc.
rename_types = "PascalCase"
# Whether the underscores from the mangled name should be omitted.
remove_underscores = false
[layout]
# A string that should come before the name of any type which has been marked
# as `#[repr(packed)]`. For instance, "__attribute__((packed))" would be a
+13 -3
View File
@@ -287,8 +287,6 @@ pub struct ExportConfig {
pub include: Vec<String>,
/// A list of items to not include in the generated bindings
pub exclude: Vec<String>,
/// The rename rule to apply to the type names
pub rename_types: Option<RenameRule>,
/// Table of name conversions to apply to item names
pub rename: HashMap<String, String>,
/// Table of raw strings to prepend to the body of items.
@@ -301,7 +299,19 @@ pub struct ExportConfig {
pub item_types: Vec<ItemType>,
/// Whether renaming overrides or extends prefixing.
pub renaming_overrides_prefixing: bool,
/// Remove the underscores used for name mangling
/// Mangling configuration.
pub mangle: MangleConfig,
}
/// Mangling-specific configuration.
#[derive(Debug, Clone, Deserialize, Default)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct MangleConfig {
/// The rename rule to apply to the type names mangled.
pub rename_types: Option<RenameRule>,
/// Remove the underscores used for name mangling.
pub remove_underscores: bool,
}
+2 -8
View File
@@ -236,12 +236,7 @@ impl EnumVariant {
config: &Config,
) -> Self {
Self::new(
mangle::mangle_name(
&self.name,
generic_values,
config.export.remove_underscores,
config.export.rename_types,
),
mangle::mangle_name(&self.name, generic_values, &config.export.mangle),
self.discriminant,
self.body.specialize(generic_values, mappings, config),
self.cfg.clone(),
@@ -562,8 +557,7 @@ impl Item for Enum {
let mangled_path = mangle::mangle_path(
&self.path,
generic_values,
library.get_config().export.remove_underscores,
library.get_config().export.rename_types,
&library.get_config().export.mangle,
);
let monomorph = Enum::new(
+1 -2
View File
@@ -122,8 +122,7 @@ impl Item for OpaqueItem {
let mangled_path = mangle::mangle_path(
&self.path,
generic_values,
library.get_config().export.remove_underscores,
library.get_config().export.rename_types,
&library.get_config().export.mangle,
);
let monomorph = OpaqueItem::new(
+1 -6
View File
@@ -177,12 +177,7 @@ impl Struct {
mappings: &[(&Path, &Type)],
config: &Config,
) -> Self {
let mangled_path = mangle::mangle_path(
&self.path,
generic_values,
config.export.remove_underscores,
config.export.rename_types,
);
let mangled_path = mangle::mangle_path(&self.path, generic_values, &config.export.mangle);
Struct::new(
mangled_path,
GenericParams::default(),
+1 -2
View File
@@ -175,8 +175,7 @@ impl Item for Typedef {
let mangled_path = mangle::mangle_path(
&self.path,
generic_values,
library.get_config().export.remove_underscores,
library.get_config().export.rename_types,
&library.get_config().export.mangle,
);
let monomorph = Typedef::new(
+1 -2
View File
@@ -238,8 +238,7 @@ impl Item for Union {
let mangled_path = mangle::mangle_path(
&self.path,
generic_values,
library.get_config().export.remove_underscores,
library.get_config().export.rename_types,
&library.get_config().export.mangle,
);
let monomorph = Union::new(
+50 -64
View File
@@ -2,38 +2,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use crate::bindgen::config::MangleConfig;
use crate::bindgen::ir::{Path, Type};
use crate::bindgen::rename::IdentifierType;
use crate::bindgen::rename::RenameRule;
pub fn mangle_path(
path: &Path,
generic_values: &[Type],
remove_underscores: bool,
rename_types: Option<RenameRule>,
) -> Path {
Path::new(mangle_name(
path.name(),
generic_values,
remove_underscores,
rename_types,
))
pub fn mangle_path(path: &Path, generic_values: &[Type], config: &MangleConfig) -> Path {
Path::new(mangle_name(path.name(), generic_values, config))
}
pub fn mangle_name(
name: &str,
generic_values: &[Type],
remove_underscores: bool,
rename_types: Option<RenameRule>,
) -> String {
Mangler::new(
name,
generic_values,
/* last = */ true,
remove_underscores,
rename_types,
)
.mangle()
pub fn mangle_name(name: &str, generic_values: &[Type], config: &MangleConfig) -> String {
Mangler::new(name, generic_values, /* last = */ true, config).mangle()
}
enum Separator {
@@ -49,8 +28,7 @@ struct Mangler<'a> {
generic_values: &'a [Type],
output: String,
last: bool,
remove_underscores: bool,
rename_types: Option<RenameRule>,
config: &'a MangleConfig,
}
impl<'a> Mangler<'a> {
@@ -58,16 +36,14 @@ impl<'a> Mangler<'a> {
input: &'a str,
generic_values: &'a [Type],
last: bool,
remove_underscores: bool,
type_rename_rule: Option<RenameRule>,
config: &'a MangleConfig,
) -> Self {
Self {
input,
generic_values,
output: String::new(),
last,
remove_underscores,
rename_types: type_rename_rule,
config,
}
}
@@ -78,36 +54,35 @@ impl<'a> Mangler<'a> {
fn push(&mut self, id: Separator) {
let count = id as usize;
let separator = if self.remove_underscores { "" } else { "_" };
let separator = if self.config.remove_underscores {
""
} else {
"_"
};
self.output.extend(std::iter::repeat(separator).take(count));
}
fn append_mangled_type(&mut self, ty: &Type, last: bool) {
match *ty {
Type::Path(ref generic) => {
let sub_path = Mangler::new(
generic.export_name(),
generic.generics(),
last,
self.remove_underscores,
self.rename_types,
)
.mangle();
let sub_path =
Mangler::new(generic.export_name(), generic.generics(), last, self.config)
.mangle();
self.output.push_str(
&self
.config
.rename_types
.as_ref()
.unwrap_or(&RenameRule::None)
.unwrap_or(RenameRule::None)
.apply(&sub_path, IdentifierType::Type),
);
}
Type::Primitive(ref primitive) => {
self.output.push_str(
&self
.config
.rename_types
.as_ref()
.unwrap_or(&RenameRule::None)
.unwrap_or(RenameRule::None)
.apply(primitive.to_repr_rust(), IdentifierType::Type),
);
}
@@ -179,7 +154,7 @@ fn generics() {
// Foo<f32> => Foo_f32
assert_eq!(
mangle_path(&Path::new("Foo"), &vec![float()], false, None),
mangle_path(&Path::new("Foo"), &vec![float()], &MangleConfig::default()),
Path::new("Foo_f32")
);
@@ -188,21 +163,27 @@ fn generics() {
mangle_path(
&Path::new("Foo"),
&vec![generic_path("Bar", &[float()])],
false,
None,
&MangleConfig::default(),
),
Path::new("Foo_Bar_f32")
);
// Foo<Bar> => Foo_Bar
assert_eq!(
mangle_path(&Path::new("Foo"), &[path("Bar")], false, None),
mangle_path(&Path::new("Foo"), &[path("Bar")], &MangleConfig::default()),
Path::new("Foo_Bar")
);
// Foo<Bar> => FooBar
assert_eq!(
mangle_path(&Path::new("Foo"), &[path("Bar")], true, None),
mangle_path(
&Path::new("Foo"),
&[path("Bar")],
&MangleConfig {
remove_underscores: true,
rename_types: None,
}
),
Path::new("FooBar")
);
@@ -211,8 +192,10 @@ fn generics() {
mangle_path(
&Path::new("Foo"),
&vec![generic_path("Bar", &[float()])],
true,
Some(PascalCase),
&MangleConfig {
remove_underscores: true,
rename_types: Some(PascalCase),
},
),
Path::new("FooBarF32")
);
@@ -222,8 +205,10 @@ fn generics() {
mangle_path(
&Path::new("Foo"),
&vec![generic_path("Bar", &[c_char()])],
true,
Some(PascalCase),
&MangleConfig {
remove_underscores: true,
rename_types: Some(PascalCase),
},
),
Path::new("FooBarCChar")
);
@@ -233,8 +218,7 @@ fn generics() {
mangle_path(
&Path::new("Foo"),
&[generic_path("Bar", &[path("T")])],
false,
None,
&MangleConfig::default(),
),
Path::new("Foo_Bar_T")
);
@@ -244,8 +228,7 @@ fn generics() {
mangle_path(
&Path::new("Foo"),
&[generic_path("Bar", &[path("T")]), path("E")],
false,
None,
&MangleConfig::default(),
),
Path::new("Foo_Bar_T_____E")
);
@@ -258,8 +241,7 @@ fn generics() {
generic_path("Bar", &[path("T")]),
generic_path("Bar", &[path("E")]),
],
false,
None,
&MangleConfig::default(),
),
Path::new("Foo_Bar_T_____Bar_E")
);
@@ -269,8 +251,10 @@ fn generics() {
mangle_path(
&Path::new("Foo"),
&[generic_path("Bar", &[path("T")]), path("E")],
true,
Some(PascalCase),
&MangleConfig {
remove_underscores: true,
rename_types: Some(PascalCase),
},
),
Path::new("FooBarTE")
);
@@ -283,8 +267,10 @@ fn generics() {
generic_path("Bar", &[path("T")]),
generic_path("Bar", &[path("E")]),
],
true,
Some(PascalCase),
&MangleConfig {
remove_underscores: true,
rename_types: Some(PascalCase),
},
),
Path::new("FooBarTBarE")
);
+1
View File
@@ -68,6 +68,7 @@ renaming_overrides_prefixing = false
[export.body]
[export.mangle]
[fn]
+12
View File
@@ -0,0 +1,12 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct FooU8 {
uint8_t a;
} FooU8;
typedef FooU8 Boo;
void root(Boo x);
+20
View File
@@ -0,0 +1,20 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct FooU8 {
uint8_t a;
} FooU8;
typedef FooU8 Boo;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void root(Boo x);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+12
View File
@@ -0,0 +1,12 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct {
uint8_t a;
} FooU8;
typedef FooU8 Boo;
void root(Boo x);
+20
View File
@@ -0,0 +1,20 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct {
uint8_t a;
} FooU8;
typedef FooU8 Boo;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void root(Boo x);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+17
View File
@@ -0,0 +1,17 @@
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <new>
template<typename T>
struct Foo {
T a;
};
using Boo = Foo<uint8_t>;
extern "C" {
void root(Boo x);
} // extern "C"
+12
View File
@@ -0,0 +1,12 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
struct FooU8 {
uint8_t a;
};
typedef struct FooU8 Boo;
void root(Boo x);
+20
View File
@@ -0,0 +1,20 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
struct FooU8 {
uint8_t a;
};
typedef struct FooU8 Boo;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void root(Boo x);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+11
View File
@@ -0,0 +1,11 @@
#[repr(C)]
pub struct Foo<T> {
a: T,
}
pub type Boo = Foo<u8>;
#[no_mangle]
pub extern "C" fn root(
x: Boo,
) { }
+3
View File
@@ -0,0 +1,3 @@
[export.mangle]
remove_underscores = true
rename_types = "PascalCase"