Skip to content

Commit 9b78e09

Browse files
author
bors-servo
authored
Auto merge of #325 - emilio:stable-template-test, r=heycam
codegen: generate stable names for tests functions. r? @heycam
2 parents 6903812 + dd80c27 commit 9b78e09

File tree

5 files changed

+109
-94
lines changed

5 files changed

+109
-94
lines changed

libbindgen/src/codegen/mod.rs

Lines changed: 103 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use ir::var::Var;
1919
use self::helpers::{BlobTyBuilder, attributes};
2020

2121
use std::borrow::Cow;
22+
use std::cell::Cell;
2223
use std::collections::HashSet;
2324
use std::collections::hash_map::{Entry, HashMap};
2425
use std::fmt::Write;
@@ -59,9 +60,16 @@ fn root_import(ctx: &BindgenContext, module: &Item) -> P<ast::Item> {
5960
quote_item!(ctx.ext_cx(), #[allow(unused_imports)] $use_root).unwrap()
6061
}
6162

62-
struct CodegenResult {
63+
struct CodegenResult<'a> {
6364
items: Vec<P<ast::Item>>,
65+
66+
/// A monotonic counter used to add stable unique id's to stuff that doesn't
67+
/// need to be referenced by anything.
68+
codegen_id: &'a Cell<usize>,
69+
70+
/// Whether an union has been generated at least once.
6471
saw_union: bool,
72+
6573
items_seen: HashSet<ItemId>,
6674
/// The set of generated function/var names, needed because in C/C++ is
6775
/// legal to do something like:
@@ -88,18 +96,24 @@ struct CodegenResult {
8896
overload_counters: HashMap<String, u32>,
8997
}
9098

91-
impl CodegenResult {
92-
fn new() -> Self {
99+
impl<'a> CodegenResult<'a> {
100+
fn new(codegen_id: &'a Cell<usize>) -> Self {
93101
CodegenResult {
94102
items: vec![],
95103
saw_union: false,
104+
codegen_id: codegen_id,
96105
items_seen: Default::default(),
97106
functions_seen: Default::default(),
98107
vars_seen: Default::default(),
99108
overload_counters: Default::default(),
100109
}
101110
}
102111

112+
fn next_id(&mut self) -> usize {
113+
self.codegen_id.set(self.codegen_id.get() + 1);
114+
self.codegen_id.get()
115+
}
116+
103117
fn saw_union(&mut self) {
104118
self.saw_union = true;
105119
}
@@ -142,7 +156,7 @@ impl CodegenResult {
142156
fn inner<F>(&mut self, cb: F) -> Vec<P<ast::Item>>
143157
where F: FnOnce(&mut Self),
144158
{
145-
let mut new = Self::new();
159+
let mut new = Self::new(self.codegen_id);
146160

147161
cb(&mut new);
148162

@@ -152,15 +166,15 @@ impl CodegenResult {
152166
}
153167
}
154168

155-
impl ops::Deref for CodegenResult {
169+
impl<'a> ops::Deref for CodegenResult<'a> {
156170
type Target = Vec<P<ast::Item>>;
157171

158172
fn deref(&self) -> &Self::Target {
159173
&self.items
160174
}
161175
}
162176

163-
impl ops::DerefMut for CodegenResult {
177+
impl<'a> ops::DerefMut for CodegenResult<'a> {
164178
fn deref_mut(&mut self) -> &mut Self::Target {
165179
&mut self.items
166180
}
@@ -237,21 +251,21 @@ trait CodeGenerator {
237251
/// Extra information from the caller.
238252
type Extra;
239253

240-
fn codegen(&self,
241-
ctx: &BindgenContext,
242-
result: &mut CodegenResult,
243-
whitelisted_items: &ItemSet,
244-
extra: &Self::Extra);
254+
fn codegen<'a>(&self,
255+
ctx: &BindgenContext,
256+
result: &mut CodegenResult<'a>,
257+
whitelisted_items: &ItemSet,
258+
extra: &Self::Extra);
245259
}
246260

247261
impl CodeGenerator for Item {
248262
type Extra = ();
249263

250-
fn codegen(&self,
251-
ctx: &BindgenContext,
252-
result: &mut CodegenResult,
253-
whitelisted_items: &ItemSet,
254-
_extra: &()) {
264+
fn codegen<'a>(&self,
265+
ctx: &BindgenContext,
266+
result: &mut CodegenResult<'a>,
267+
whitelisted_items: &ItemSet,
268+
_extra: &()) {
255269
if self.is_hidden(ctx) || result.seen(self.id()) {
256270
debug!("<Item as CodeGenerator>::codegen: Ignoring hidden or seen: \
257271
self = {:?}", self);
@@ -288,11 +302,11 @@ impl CodeGenerator for Item {
288302
impl CodeGenerator for Module {
289303
type Extra = Item;
290304

291-
fn codegen(&self,
292-
ctx: &BindgenContext,
293-
result: &mut CodegenResult,
294-
whitelisted_items: &ItemSet,
295-
item: &Item) {
305+
fn codegen<'a>(&self,
306+
ctx: &BindgenContext,
307+
result: &mut CodegenResult<'a>,
308+
whitelisted_items: &ItemSet,
309+
item: &Item) {
296310
debug!("<Module as CodeGenerator>::codegen: item = {:?}", item);
297311

298312
let codegen_self = |result: &mut CodegenResult, found_any: &mut bool| {
@@ -348,11 +362,11 @@ impl CodeGenerator for Module {
348362

349363
impl CodeGenerator for Var {
350364
type Extra = Item;
351-
fn codegen(&self,
352-
ctx: &BindgenContext,
353-
result: &mut CodegenResult,
354-
_whitelisted_items: &ItemSet,
355-
item: &Item) {
365+
fn codegen<'a>(&self,
366+
ctx: &BindgenContext,
367+
result: &mut CodegenResult<'a>,
368+
_whitelisted_items: &ItemSet,
369+
item: &Item) {
356370
use ir::var::VarType;
357371
debug!("<Var as CodeGenerator>::codegen: item = {:?}", item);
358372

@@ -439,11 +453,11 @@ impl CodeGenerator for Var {
439453
impl CodeGenerator for Type {
440454
type Extra = Item;
441455

442-
fn codegen(&self,
443-
ctx: &BindgenContext,
444-
result: &mut CodegenResult,
445-
whitelisted_items: &ItemSet,
446-
item: &Item) {
456+
fn codegen<'a>(&self,
457+
ctx: &BindgenContext,
458+
result: &mut CodegenResult<'a>,
459+
whitelisted_items: &ItemSet,
460+
item: &Item) {
447461
debug!("<Type as CodeGenerator>::codegen: item = {:?}", item);
448462

449463
match *self.kind() {
@@ -560,11 +574,11 @@ impl<'a> Vtable<'a> {
560574
impl<'a> CodeGenerator for Vtable<'a> {
561575
type Extra = Item;
562576

563-
fn codegen(&self,
564-
ctx: &BindgenContext,
565-
result: &mut CodegenResult,
566-
_whitelisted_items: &ItemSet,
567-
item: &Item) {
577+
fn codegen<'b>(&self,
578+
ctx: &BindgenContext,
579+
result: &mut CodegenResult<'b>,
580+
_whitelisted_items: &ItemSet,
581+
item: &Item) {
568582
assert_eq!(item.id(), self.item_id);
569583
// For now, generate an empty struct, later we should generate function
570584
// pointers and whatnot.
@@ -694,11 +708,11 @@ impl<'a> Bitfield<'a> {
694708
impl CodeGenerator for CompInfo {
695709
type Extra = Item;
696710

697-
fn codegen(&self,
698-
ctx: &BindgenContext,
699-
result: &mut CodegenResult,
700-
whitelisted_items: &ItemSet,
701-
item: &Item) {
711+
fn codegen<'a>(&self,
712+
ctx: &BindgenContext,
713+
result: &mut CodegenResult<'a>,
714+
whitelisted_items: &ItemSet,
715+
item: &Item) {
702716
use aster::struct_field::StructFieldBuilder;
703717

704718
debug!("<CompInfo as CodeGenerator>::codegen: item = {:?}", item);
@@ -713,7 +727,7 @@ impl CodeGenerator for CompInfo {
713727
let layout = item.kind().expect_type().layout(ctx);
714728

715729
if let Some(layout) = layout {
716-
let fn_name = format!("__bindgen_test_layout_template_{}", item.id().as_usize());
730+
let fn_name = format!("__bindgen_test_layout_template_{}", result.next_id());
717731
let fn_name = ctx.rust_ident_raw(&fn_name);
718732
let ident = item.to_rust_ty(ctx);
719733
let prefix = ctx.trait_prefix();
@@ -1222,23 +1236,23 @@ impl CodeGenerator for CompInfo {
12221236
}
12231237

12241238
trait MethodCodegen {
1225-
fn codegen_method(&self,
1226-
ctx: &BindgenContext,
1227-
methods: &mut Vec<ast::ImplItem>,
1228-
method_names: &mut HashMap<String, usize>,
1229-
result: &mut CodegenResult,
1230-
whitelisted_items: &ItemSet,
1231-
parent: &Item);
1239+
fn codegen_method<'a>(&self,
1240+
ctx: &BindgenContext,
1241+
methods: &mut Vec<ast::ImplItem>,
1242+
method_names: &mut HashMap<String, usize>,
1243+
result: &mut CodegenResult<'a>,
1244+
whitelisted_items: &ItemSet,
1245+
parent: &Item);
12321246
}
12331247

12341248
impl MethodCodegen for Method {
1235-
fn codegen_method(&self,
1236-
ctx: &BindgenContext,
1237-
methods: &mut Vec<ast::ImplItem>,
1238-
method_names: &mut HashMap<String, usize>,
1239-
result: &mut CodegenResult,
1240-
whitelisted_items: &ItemSet,
1241-
_parent: &Item) {
1249+
fn codegen_method<'a>(&self,
1250+
ctx: &BindgenContext,
1251+
methods: &mut Vec<ast::ImplItem>,
1252+
method_names: &mut HashMap<String, usize>,
1253+
result: &mut CodegenResult<'a>,
1254+
whitelisted_items: &ItemSet,
1255+
_parent: &Item) {
12421256
if self.is_virtual() {
12431257
return; // FIXME
12441258
}
@@ -1408,13 +1422,13 @@ impl<'a> EnumBuilder<'a> {
14081422
}
14091423

14101424
/// Add a variant to this enum.
1411-
fn with_variant(self,
1412-
ctx: &BindgenContext,
1413-
variant: &EnumVariant,
1414-
mangling_prefix: Option<&String>,
1415-
rust_ty: P<ast::Ty>,
1416-
result: &mut CodegenResult)
1417-
-> Self {
1425+
fn with_variant<'b>(self,
1426+
ctx: &BindgenContext,
1427+
variant: &EnumVariant,
1428+
mangling_prefix: Option<&String>,
1429+
rust_ty: P<ast::Ty>,
1430+
result: &mut CodegenResult<'b>)
1431+
-> Self {
14181432
let variant_name = ctx.rust_mangle(variant.name());
14191433
let expr = aster::AstBuilder::new().expr();
14201434
let expr = match variant.val() {
@@ -1456,11 +1470,11 @@ impl<'a> EnumBuilder<'a> {
14561470
}
14571471
}
14581472

1459-
fn build(self,
1460-
ctx: &BindgenContext,
1461-
rust_ty: P<ast::Ty>,
1462-
result: &mut CodegenResult)
1463-
-> P<ast::Item> {
1473+
fn build<'b>(self,
1474+
ctx: &BindgenContext,
1475+
rust_ty: P<ast::Ty>,
1476+
result: &mut CodegenResult<'b>)
1477+
-> P<ast::Item> {
14641478
match self {
14651479
EnumBuilder::Rust(b) => b.build(),
14661480
EnumBuilder::Bitfield { canonical_name, aster } => {
@@ -1489,11 +1503,11 @@ impl<'a> EnumBuilder<'a> {
14891503
impl CodeGenerator for Enum {
14901504
type Extra = Item;
14911505

1492-
fn codegen(&self,
1493-
ctx: &BindgenContext,
1494-
result: &mut CodegenResult,
1495-
_whitelisted_items: &ItemSet,
1496-
item: &Item) {
1506+
fn codegen<'a>(&self,
1507+
ctx: &BindgenContext,
1508+
result: &mut CodegenResult<'a>,
1509+
_whitelisted_items: &ItemSet,
1510+
item: &Item) {
14971511
debug!("<Enum as CodeGenerator>::codegen: item = {:?}", item);
14981512

14991513
let name = item.canonical_name(ctx);
@@ -1567,15 +1581,15 @@ impl CodeGenerator for Enum {
15671581

15681582
builder = builder.with_attr(derives);
15691583

1570-
fn add_constant(enum_: &Type,
1571-
// Only to avoid recomputing every time.
1572-
enum_canonical_name: &str,
1573-
// May be the same as "variant" if it's because the
1574-
// enum is unnamed and we still haven't seen the value.
1575-
variant_name: &str,
1576-
referenced_name: &str,
1577-
enum_rust_ty: P<ast::Ty>,
1578-
result: &mut CodegenResult) {
1584+
fn add_constant<'a>(enum_: &Type,
1585+
// Only to avoid recomputing every time.
1586+
enum_canonical_name: &str,
1587+
// May be the same as "variant" if it's because the
1588+
// enum is unnamed and we still haven't seen the value.
1589+
variant_name: &str,
1590+
referenced_name: &str,
1591+
enum_rust_ty: P<ast::Ty>,
1592+
result: &mut CodegenResult<'a>) {
15791593
let constant_name = if enum_.name().is_some() {
15801594
format!("{}_{}", enum_canonical_name, variant_name)
15811595
} else {
@@ -1935,11 +1949,11 @@ impl ToRustTy for FunctionSig {
19351949
impl CodeGenerator for Function {
19361950
type Extra = Item;
19371951

1938-
fn codegen(&self,
1939-
ctx: &BindgenContext,
1940-
result: &mut CodegenResult,
1941-
_whitelisted_items: &ItemSet,
1942-
item: &Item) {
1952+
fn codegen<'a>(&self,
1953+
ctx: &BindgenContext,
1954+
result: &mut CodegenResult<'a>,
1955+
_whitelisted_items: &ItemSet,
1956+
item: &Item) {
19431957
debug!("<Function as CodeGenerator>::codegen: item = {:?}", item);
19441958

19451959
let name = self.name();
@@ -2007,7 +2021,8 @@ impl CodeGenerator for Function {
20072021

20082022
pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> {
20092023
context.gen(|context| {
2010-
let mut result = CodegenResult::new();
2024+
let counter = Cell::new(0);
2025+
let mut result = CodegenResult::new(&counter);
20112026

20122027
debug!("codegen: {:?}", context.options());
20132028

libbindgen/tests/expectations/tests/anon_union.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub struct TErrorResult__bindgen_ty_1<T> {
6363
pub _phantom_0: ::std::marker::PhantomData<T>,
6464
}
6565
#[test]
66-
fn __bindgen_test_layout_template_17() {
66+
fn __bindgen_test_layout_template_1() {
6767
assert_eq!(::std::mem::size_of::<TErrorResult<::std::os::raw::c_int>>() ,
6868
24usize);
6969
assert_eq!(::std::mem::align_of::<TErrorResult<::std::os::raw::c_int>>() ,

libbindgen/tests/expectations/tests/class_with_dtor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn bindgen_test_layout_WithoutDtor() {
2121
assert_eq!(::std::mem::align_of::<WithoutDtor>() , 8usize);
2222
}
2323
#[test]
24-
fn __bindgen_test_layout_template_11() {
24+
fn __bindgen_test_layout_template_1() {
2525
assert_eq!(::std::mem::size_of::<HandleWithDtor<::std::os::raw::c_int>>()
2626
, 8usize);
2727
assert_eq!(::std::mem::align_of::<HandleWithDtor<::std::os::raw::c_int>>()

libbindgen/tests/expectations/tests/crtp.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub struct Base<T> {
1111
pub _phantom_0: ::std::marker::PhantomData<T>,
1212
}
1313
#[test]
14-
fn __bindgen_test_layout_template_5() {
14+
fn __bindgen_test_layout_template_1() {
1515
assert_eq!(::std::mem::size_of::<Base<Derived>>() , 1usize);
1616
assert_eq!(::std::mem::align_of::<Base<Derived>>() , 1usize);
1717
}
@@ -35,7 +35,7 @@ pub struct BaseWithDestructor<T> {
3535
pub _phantom_0: ::std::marker::PhantomData<T>,
3636
}
3737
#[test]
38-
fn __bindgen_test_layout_template_12() {
38+
fn __bindgen_test_layout_template_2() {
3939
assert_eq!(::std::mem::size_of::<BaseWithDestructor<DerivedFromBaseWithDestructor>>()
4040
, 1usize);
4141
assert_eq!(::std::mem::align_of::<BaseWithDestructor<DerivedFromBaseWithDestructor>>()

0 commit comments

Comments
 (0)