Skip to content

Commit 6624c72

Browse files
author
Jakub Bukaj
committed
---
yaml --- r: 159447 b: refs/heads/master c: 7137c2c h: refs/heads/master i: 159445: 570d246 159443: 2869915 159439: 4d63597 v: v3
1 parent 52b3e4f commit 6624c72

File tree

10 files changed

+110
-30
lines changed

10 files changed

+110
-30
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 46be8eb47ccd261ecb00ba25e0c24f28c8af75d7
2+
refs/heads/master: 7137c2cc83526e1f74af472380e625fc7c552826
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 9c96a79a74f10bed18b031ce0ac4126c56d6cfb3
55
refs/heads/try: f58aad6dce273570fb130b4df008ef9acd5a5be2

trunk/src/librustc/back/link.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,9 @@ fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) {
728728
if sess.target.target.options.morestack {
729729
ab.add_native_library("morestack").unwrap();
730730
}
731-
ab.add_native_library("compiler-rt").unwrap();
731+
if !sess.target.target.options.no_compiler_rt {
732+
ab.add_native_library("compiler-rt").unwrap();
733+
}
732734

733735
let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
734736
let mut all_native_libs = vec![];

trunk/src/librustc/lint/builtin.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,7 @@ impl LintPass for UnusedAttributes {
623623
"link",
624624
"link_name",
625625
"link_section",
626+
"linkage",
626627
"no_builtins",
627628
"no_mangle",
628629
"no_split_stack",

trunk/src/librustc/middle/trans/base.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use driver::config::{NoDebugInfo, FullDebugInfo};
3636
use driver::driver::{CrateAnalysis, CrateTranslation, ModuleTranslation};
3737
use driver::session::Session;
3838
use lint;
39-
use llvm::{BasicBlockRef, ValueRef, Vector, get_param};
39+
use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
4040
use llvm;
4141
use metadata::{csearch, encoder, loader};
4242
use middle::astencode;
@@ -2137,6 +2137,32 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemVisitor<'a, 'tcx> {
21372137
}
21382138
}
21392139

2140+
pub fn llvm_linkage_by_name(name: &str) -> Option<Linkage> {
2141+
// Use the names from src/llvm/docs/LangRef.rst here. Most types are only
2142+
// applicable to variable declarations and may not really make sense for
2143+
// Rust code in the first place but whitelist them anyway and trust that
2144+
// the user knows what s/he's doing. Who knows, unanticipated use cases
2145+
// may pop up in the future.
2146+
//
2147+
// ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
2148+
// and don't have to be, LLVM treats them as no-ops.
2149+
match name {
2150+
"appending" => Some(llvm::AppendingLinkage),
2151+
"available_externally" => Some(llvm::AvailableExternallyLinkage),
2152+
"common" => Some(llvm::CommonLinkage),
2153+
"extern_weak" => Some(llvm::ExternalWeakLinkage),
2154+
"external" => Some(llvm::ExternalLinkage),
2155+
"internal" => Some(llvm::InternalLinkage),
2156+
"linkonce" => Some(llvm::LinkOnceAnyLinkage),
2157+
"linkonce_odr" => Some(llvm::LinkOnceODRLinkage),
2158+
"private" => Some(llvm::PrivateLinkage),
2159+
"weak" => Some(llvm::WeakAnyLinkage),
2160+
"weak_odr" => Some(llvm::WeakODRLinkage),
2161+
_ => None,
2162+
}
2163+
}
2164+
2165+
21402166
/// Enum describing the origin of an LLVM `Value`, for linkage purposes.
21412167
pub enum ValueOrigin {
21422168
/// The LLVM `Value` is in this context because the corresponding item was
@@ -2174,6 +2200,23 @@ pub fn update_linkage(ccx: &CrateContext,
21742200
OriginalTranslation => {},
21752201
}
21762202

2203+
match id {
2204+
Some(id) => {
2205+
let item = ccx.tcx().map.get(id);
2206+
if let ast_map::NodeItem(i) = item {
2207+
if let Some(name) = attr::first_attr_value_str_by_name(i.attrs[], "linkage") {
2208+
if let Some(linkage) = llvm_linkage_by_name(name.get()) {
2209+
llvm::SetLinkage(llval, linkage);
2210+
} else {
2211+
ccx.sess().span_fatal(i.span, "invalid linkage specified");
2212+
}
2213+
return;
2214+
}
2215+
}
2216+
}
2217+
_ => {}
2218+
}
2219+
21772220
match id {
21782221
Some(id) if ccx.reachable().contains(&id) => {
21792222
llvm::SetLinkage(llval, llvm::ExternalLinkage);

trunk/src/librustc/middle/trans/foreign.rs

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010

1111

1212
use back::{link};
13-
use llvm::{ValueRef, CallConv, Linkage, get_param};
13+
use llvm::{ValueRef, CallConv, get_param};
1414
use llvm;
1515
use middle::weak_lang_items;
16-
use middle::trans::base::push_ctxt;
16+
use middle::trans::base::{llvm_linkage_by_name, push_ctxt};
1717
use middle::trans::base;
1818
use middle::trans::build::*;
1919
use middle::trans::cabi;
@@ -101,31 +101,6 @@ pub fn llvm_calling_convention(ccx: &CrateContext,
101101
}
102102
}
103103

104-
pub fn llvm_linkage_by_name(name: &str) -> Option<Linkage> {
105-
// Use the names from src/llvm/docs/LangRef.rst here. Most types are only
106-
// applicable to variable declarations and may not really make sense for
107-
// Rust code in the first place but whitelist them anyway and trust that
108-
// the user knows what s/he's doing. Who knows, unanticipated use cases
109-
// may pop up in the future.
110-
//
111-
// ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
112-
// and don't have to be, LLVM treats them as no-ops.
113-
match name {
114-
"appending" => Some(llvm::AppendingLinkage),
115-
"available_externally" => Some(llvm::AvailableExternallyLinkage),
116-
"common" => Some(llvm::CommonLinkage),
117-
"extern_weak" => Some(llvm::ExternalWeakLinkage),
118-
"external" => Some(llvm::ExternalLinkage),
119-
"internal" => Some(llvm::InternalLinkage),
120-
"linkonce" => Some(llvm::LinkOnceAnyLinkage),
121-
"linkonce_odr" => Some(llvm::LinkOnceODRLinkage),
122-
"private" => Some(llvm::PrivateLinkage),
123-
"weak" => Some(llvm::WeakAnyLinkage),
124-
"weak_odr" => Some(llvm::WeakODRLinkage),
125-
_ => None,
126-
}
127-
}
128-
129104
pub fn register_static(ccx: &CrateContext,
130105
foreign_item: &ast::ForeignItem) -> ValueRef {
131106
let ty = ty::node_id_to_type(ccx.tcx(), foreign_item.id);

trunk/src/libsyntax/feature_gate.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
182182
"`#[thread_local]` is an experimental feature, and does not \
183183
currently handle destructors. There is no corresponding \
184184
`#[task_local]` mapping to the task model");
185+
} else if attr.name().equiv(&("linkage")) {
186+
self.gate_feature("linkage", i.span,
187+
"the `linkage` attribute is experimental \
188+
and not portable across platforms")
185189
}
186190
}
187191
match i.node {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2014 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+
#[linkage = "external"]
12+
static foo: int = 0;
13+
//~^ ERROR: the `linkage` attribute is experimental and not portable
14+
15+
fn main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-include ../tools.mk
2+
3+
all:
4+
$(CC) foo.c -c -o $(TMPDIR)/foo.o
5+
$(AR) rcs $(TMPDIR)/libfoo.a $(TMPDIR)/foo.o
6+
$(RUSTC) bar.rs -lfoo -L $(TMPDIR)
7+
$(call RUN,bar) || exit 1
8+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2014 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+
#![feature(linkage)]
12+
13+
#[no_mangle]
14+
#[linkage = "external"]
15+
static BAZ: i32 = 21;
16+
17+
extern {
18+
fn what() -> i32;
19+
}
20+
21+
fn main() {
22+
unsafe {
23+
assert_eq!(what(), BAZ);
24+
}
25+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include <stdint.h>
2+
3+
extern int32_t BAZ;
4+
5+
int32_t what() {
6+
return BAZ;
7+
}

0 commit comments

Comments
 (0)