Skip to content

Commit ad7e90f

Browse files
author
bors-servo
authored
Auto merge of rust-lang#63 - jeanphilippeD:deduplicate-statics, r=emilio
Handle re-declaration of a global variable. Fix rust-lang#47
2 parents 978846c + 8b41159 commit ad7e90f

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

src/codegen/mod.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,24 @@ struct CodegenResult {
3838
items: Vec<P<ast::Item>>,
3939
saw_union: bool,
4040
items_seen: HashSet<ItemId>,
41-
/// The set of generated function names, needed because in C/C++ is legal to
41+
/// The set of generated function/var names, needed because in C/C++ is legal to
4242
/// do something like:
4343
///
4444
/// ```
4545
/// extern "C" {
4646
/// void foo();
47+
/// extern int bar;
4748
/// }
4849
///
4950
/// extern "C" {
5051
/// void foo();
52+
/// extern int bar;
5153
/// }
5254
/// ```
5355
///
5456
/// Being these two different declarations.
5557
functions_seen: HashSet<String>,
58+
vars_seen: HashSet<String>,
5659
}
5760

5861
impl CodegenResult {
@@ -62,6 +65,7 @@ impl CodegenResult {
6265
saw_union: false,
6366
items_seen: Default::default(),
6467
functions_seen: Default::default(),
68+
vars_seen: Default::default(),
6569
}
6670
}
6771

@@ -85,6 +89,14 @@ impl CodegenResult {
8589
self.functions_seen.insert(name.into());
8690
}
8791

92+
fn seen_var(&self, name: &str) -> bool {
93+
self.vars_seen.contains(name)
94+
}
95+
96+
fn saw_var(&mut self, name: &str) {
97+
self.vars_seen.insert(name.into());
98+
}
99+
88100
fn inner<F>(&mut self, cb: F) -> Vec<P<ast::Item>>
89101
where F: FnOnce(&mut Self)
90102
{
@@ -265,23 +277,30 @@ impl CodeGenerator for Var {
265277
ctx: &BindgenContext,
266278
result: &mut CodegenResult,
267279
item: &Item) {
268-
let name = item.canonical_name(ctx);
280+
let canonical_name = item.canonical_name(ctx);
281+
282+
if result.seen_var(&canonical_name) {
283+
return;
284+
}
285+
result.saw_var(&canonical_name);
286+
269287
let ty = self.ty().to_rust_ty(ctx);
270288

271289
if let Some(val) = self.val() {
272-
let const_item = aster::AstBuilder::new().item().pub_().const_(name)
290+
let const_item = aster::AstBuilder::new().item().pub_()
291+
.const_(canonical_name)
273292
.expr().int(val).build(ty);
274293
result.push(const_item)
275294
} else {
276295
let mut attrs = vec![];
277296
if let Some(mangled) = self.mangled_name() {
278297
attrs.push(attributes::link_name(mangled));
279-
} else if name != self.name() {
298+
} else if canonical_name != self.name() {
280299
attrs.push(attributes::link_name(self.name()));
281300
}
282301

283302
let item = ast::ForeignItem {
284-
ident: ctx.rust_ident_raw(&name),
303+
ident: ctx.rust_ident_raw(&canonical_name),
285304
attrs: attrs,
286305
node: ast::ForeignItemKind::Static(ty, !self.is_const()),
287306
id: ast::DUMMY_NODE_ID,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
4+
#![allow(non_snake_case)]
5+
6+
7+
extern "C" {
8+
#[link_name = "foo"]
9+
pub static mut foo: ::std::os::raw::c_int;
10+
}

tests/headers/decl_extern_int_twice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
extern int foo;
2+
extern int foo;

0 commit comments

Comments
 (0)