Skip to content

Commit 35680bd

Browse files
committed
Merge branch 'used' of https://github.com/japaric/rust into rollup
2 parents 3ac2180 + 0cb9b23 commit 35680bd

File tree

7 files changed

+81
-1
lines changed

7 files changed

+81
-1
lines changed

src/librustc_trans/base.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ use builder::Builder;
5555
use callee::{Callee};
5656
use common::{C_bool, C_bytes_in_context, C_i32, C_uint};
5757
use collector::{self, TransItemCollectionMode};
58-
use common::{C_struct_in_context, C_u64, C_undef};
58+
use common::{C_struct_in_context, C_u64, C_undef, C_array};
5959
use common::CrateContext;
6060
use common::{fulfill_obligation};
6161
use common::{type_is_zero_size, val_ty};
@@ -1262,6 +1262,24 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
12621262
}
12631263
}
12641264

1265+
// Create llvm.used variable
1266+
if !ccx.used_statics().borrow().is_empty() {
1267+
debug!("llvm.used");
1268+
1269+
let name = CString::new("llvm.used").unwrap();
1270+
let section = CString::new("llvm.metadata").unwrap();
1271+
let array = C_array(Type::i8(&ccx).ptr_to(), &*ccx.used_statics().borrow());
1272+
1273+
unsafe {
1274+
let g = llvm::LLVMAddGlobal(ccx.llmod(),
1275+
val_ty(array).to_ref(),
1276+
name.as_ptr());
1277+
llvm::LLVMSetInitializer(g, array);
1278+
llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage);
1279+
llvm::LLVMSetSection(g, section.as_ptr());
1280+
}
1281+
}
1282+
12651283
// Finalize debuginfo
12661284
if ccx.sess().opts.debuginfo != NoDebugInfo {
12671285
debuginfo::finalize(&ccx);

src/librustc_trans/consts.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,10 @@ pub fn trans_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
275275

276276
base::set_link_section(ccx, g, attrs);
277277

278+
if attr::contains_name(attrs, "used") {
279+
ccx.used_statics().borrow_mut().push(g);
280+
}
281+
278282
Ok(g)
279283
}
280284
}

src/librustc_trans/context.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ pub struct LocalCrateContext<'tcx> {
137137
/// to constants.)
138138
statics_to_rauw: RefCell<Vec<(ValueRef, ValueRef)>>,
139139

140+
used_statics: RefCell<Vec<ValueRef>>,
141+
140142
lltypes: RefCell<FxHashMap<Ty<'tcx>, Type>>,
141143
llsizingtypes: RefCell<FxHashMap<Ty<'tcx>, Type>>,
142144
type_hashcodes: RefCell<FxHashMap<Ty<'tcx>, String>>,
@@ -610,6 +612,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
610612
impl_method_cache: RefCell::new(FxHashMap()),
611613
closure_bare_wrapper_cache: RefCell::new(FxHashMap()),
612614
statics_to_rauw: RefCell::new(Vec::new()),
615+
used_statics: RefCell::new(Vec::new()),
613616
lltypes: RefCell::new(FxHashMap()),
614617
llsizingtypes: RefCell::new(FxHashMap()),
615618
type_hashcodes: RefCell::new(FxHashMap()),
@@ -790,6 +793,10 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
790793
&self.local().statics_to_rauw
791794
}
792795

796+
pub fn used_statics<'a>(&'a self) -> &'a RefCell<Vec<ValueRef>> {
797+
&self.local().used_statics
798+
}
799+
793800
pub fn lltypes<'a>(&'a self) -> &'a RefCell<FxHashMap<Ty<'tcx>, Type>> {
794801
&self.local().lltypes
795802
}

src/libsyntax/feature_gate.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,9 @@ declare_features! (
342342

343343
// Allows the `catch {...}` expression
344344
(active, catch_expr, "1.17.0", Some(31436)),
345+
346+
// Used to preserve symbols
347+
(active, used, "1.17.0", Some(40289)),
345348
);
346349

347350
declare_features! (
@@ -745,6 +748,10 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
745748
"unwind_attributes",
746749
"#[unwind] is experimental",
747750
cfg_fn!(unwind_attributes))),
751+
("used", Whitelisted, Gated(
752+
Stability::Unstable, "used",
753+
"the `#[used]` attribute is an experimental feature",
754+
cfg_fn!(used))),
748755

749756
// used in resolve
750757
("prelude_import", Whitelisted, Gated(Stability::Unstable,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#[used]
12+
fn foo() {}
13+
//~^^ ERROR the `#[used]` attribute is an experimental feature
14+
15+
fn main() {}

src/test/run-make/used/Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-include ../tools.mk
2+
3+
ifdef IS_WINDOWS
4+
# Do nothing on MSVC.
5+
all:
6+
exit 0
7+
else
8+
all:
9+
$(RUSTC) -C opt-level=3 --emit=obj used.rs
10+
nm -C $(TMPDIR)/used.o | grep FOO
11+
nm -C $(TMPDIR)/used.o | grep -v BAR
12+
endif

src/test/run-make/used/used.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![crate_type = "lib"]
12+
#![feature(used)]
13+
14+
#[used]
15+
static FOO: u32 = 0;
16+
17+
static BAR: u32 = 0;

0 commit comments

Comments
 (0)