Skip to content

Commit 4943058

Browse files
Bobo1239emilio
authored andcommitted
Add a C naming option (#2045)
Closes #2045. Fixes #1252.
1 parent 425a146 commit 4943058

File tree

5 files changed

+158
-1
lines changed

5 files changed

+158
-1
lines changed

src/ir/item.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::super::codegen::{EnumVariation, CONSTIFIED_ENUM_MODULE_REPR_NAME};
44
use super::analysis::{HasVtable, HasVtableResult, Sizedness, SizednessResult};
55
use super::annotations::Annotations;
66
use super::comment;
7-
use super::comp::MethodKind;
7+
use super::comp::{CompKind, MethodKind};
88
use super::context::{BindgenContext, ItemId, PartialType, TypeId};
99
use super::derive::{
1010
CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveEq,
@@ -904,6 +904,12 @@ impl Item {
904904
names.push(base_name);
905905
}
906906

907+
if ctx.options().c_naming {
908+
if let Some(prefix) = self.c_naming_prefix() {
909+
names.insert(0, prefix.to_string());
910+
}
911+
}
912+
907913
let name = names.join("_");
908914

909915
let name = if opt.user_mangled == UserMangled::Yes {
@@ -1054,6 +1060,22 @@ impl Item {
10541060
path.reverse();
10551061
path
10561062
}
1063+
1064+
/// Returns a prefix for the canonical name when C naming is enabled.
1065+
fn c_naming_prefix(&self) -> Option<&str> {
1066+
if let ItemKind::Type(typ) = &self.kind {
1067+
match typ.kind() {
1068+
TypeKind::Comp(comp_info) => match comp_info.kind() {
1069+
CompKind::Struct => Some("struct"),
1070+
CompKind::Union => Some("union"),
1071+
},
1072+
TypeKind::Enum(_) => Some("enum"),
1073+
_ => None,
1074+
}
1075+
} else {
1076+
None
1077+
}
1078+
}
10571079
}
10581080

10591081
impl<T> IsOpaque for T

src/lib.rs

+17
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,10 @@ impl Builder {
558558
output_vector.push("--translate-enum-integer-types".into());
559559
}
560560

561+
if self.options.c_naming {
562+
output_vector.push("--c-naming".into());
563+
}
564+
561565
// Add clang arguments
562566

563567
output_vector.push("--".into());
@@ -1616,6 +1620,15 @@ impl Builder {
16161620
self.options.translate_enum_integer_types = doit;
16171621
self
16181622
}
1623+
1624+
/// Generate types with C style naming.
1625+
///
1626+
/// This will add prefixes to the generated type names. For example instead of a struct `A` we
1627+
/// will generate struct `struct_A`. Currently applies to structs, unions, and enums.
1628+
pub fn c_naming(mut self, doit: bool) -> Self {
1629+
self.options.c_naming = doit;
1630+
self
1631+
}
16191632
}
16201633

16211634
/// Configuration options for generated bindings.
@@ -1921,6 +1934,9 @@ struct BindgenOptions {
19211934

19221935
/// Always translate enum integer types to native Rust integer types.
19231936
translate_enum_integer_types: bool,
1937+
1938+
/// Generate types with C style naming.
1939+
c_naming: bool,
19241940
}
19251941

19261942
/// TODO(emilio): This is sort of a lie (see the error message that results from
@@ -2062,6 +2078,7 @@ impl Default for BindgenOptions {
20622078
dynamic_link_require_all: false,
20632079
respect_cxx_access_specs: false,
20642080
translate_enum_integer_types: false,
2081+
c_naming: false,
20652082
}
20662083
}
20672084
}

src/options.rs

+7
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,9 @@ where
513513
Arg::with_name("translate-enum-integer-types")
514514
.long("translate-enum-integer-types")
515515
.help("Always translate enum integer types to native Rust integer types."),
516+
Arg::with_name("c-naming")
517+
.long("c-naming")
518+
.help("Generate types with C style naming."),
516519
]) // .args()
517520
.get_matches_from(args);
518521

@@ -953,6 +956,10 @@ where
953956
builder = builder.translate_enum_integer_types(true);
954957
}
955958

959+
if matches.is_present("c-naming") {
960+
builder = builder.c_naming(true);
961+
}
962+
956963
let verbose = matches.is_present("verbose");
957964

958965
Ok((builder, output, verbose))

tests/expectations/tests/c_naming.rs

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#![allow(
2+
dead_code,
3+
non_snake_case,
4+
non_camel_case_types,
5+
non_upper_case_globals
6+
)]
7+
8+
#[repr(C)]
9+
#[derive(Debug, Default, Copy, Clone)]
10+
pub struct struct_a {
11+
pub a: ::std::os::raw::c_int,
12+
}
13+
#[test]
14+
fn bindgen_test_layout_struct_a() {
15+
assert_eq!(
16+
::std::mem::size_of::<struct_a>(),
17+
4usize,
18+
concat!("Size of: ", stringify!(struct_a))
19+
);
20+
assert_eq!(
21+
::std::mem::align_of::<struct_a>(),
22+
4usize,
23+
concat!("Alignment of ", stringify!(struct_a))
24+
);
25+
assert_eq!(
26+
unsafe { &(*(::std::ptr::null::<struct_a>())).a as *const _ as usize },
27+
0usize,
28+
concat!(
29+
"Offset of field: ",
30+
stringify!(struct_a),
31+
"::",
32+
stringify!(a)
33+
)
34+
);
35+
}
36+
pub type a = *const struct_a;
37+
#[repr(C)]
38+
#[derive(Copy, Clone)]
39+
pub union union_b {
40+
pub a: ::std::os::raw::c_int,
41+
pub b: ::std::os::raw::c_int,
42+
}
43+
#[test]
44+
fn bindgen_test_layout_union_b() {
45+
assert_eq!(
46+
::std::mem::size_of::<union_b>(),
47+
4usize,
48+
concat!("Size of: ", stringify!(union_b))
49+
);
50+
assert_eq!(
51+
::std::mem::align_of::<union_b>(),
52+
4usize,
53+
concat!("Alignment of ", stringify!(union_b))
54+
);
55+
assert_eq!(
56+
unsafe { &(*(::std::ptr::null::<union_b>())).a as *const _ as usize },
57+
0usize,
58+
concat!(
59+
"Offset of field: ",
60+
stringify!(union_b),
61+
"::",
62+
stringify!(a)
63+
)
64+
);
65+
assert_eq!(
66+
unsafe { &(*(::std::ptr::null::<union_b>())).b as *const _ as usize },
67+
0usize,
68+
concat!(
69+
"Offset of field: ",
70+
stringify!(union_b),
71+
"::",
72+
stringify!(b)
73+
)
74+
);
75+
}
76+
impl Default for union_b {
77+
fn default() -> Self {
78+
unsafe { ::std::mem::zeroed() }
79+
}
80+
}
81+
pub type b = union_b;
82+
pub const enum_c_A: enum_c = 0;
83+
pub type enum_c = ::std::os::raw::c_uint;
84+
extern "C" {
85+
pub fn takes_a(arg: a);
86+
}
87+
extern "C" {
88+
pub fn takes_b(arg: b);
89+
}
90+
extern "C" {
91+
pub fn takes_c(arg: enum_c);
92+
}

tests/headers/c_naming.h

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// bindgen-flags: --c-naming
2+
3+
typedef const struct a {
4+
int a;
5+
} *a;
6+
7+
union b {
8+
int a;
9+
int b;
10+
};
11+
typedef union b b;
12+
13+
enum c {
14+
A,
15+
};
16+
17+
void takes_a(a arg) {}
18+
void takes_b(b arg) {}
19+
void takes_c(enum c arg) {}

0 commit comments

Comments
 (0)