Skip to content

Commit 06c6e0d

Browse files
committed
---
yaml --- r: 233213 b: refs/heads/beta c: 1860714 h: refs/heads/master i: 233211: ea7d5e2 v: v3
1 parent 04d3449 commit 06c6e0d

File tree

5 files changed

+104
-78
lines changed

5 files changed

+104
-78
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ refs/tags/0.9: 36870b185fc5f5486636d4515f0e22677493f225
2323
refs/tags/0.10: ac33f2b15782272ae348dbd7b14b8257b2148b5a
2424
refs/tags/0.11.0: e1247cb1d0d681be034adb4b558b5a0c0d5720f9
2525
refs/tags/0.12.0: f0c419429ef30723ceaf6b42f9b5a2aeb5d2e2d1
26-
refs/heads/beta: 5aca49c693c9be3064d9e6db9473b1fa76834b79
26+
refs/heads/beta: 18607149fbb0836059a96981c78e10ca52d23cd5
2727
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
2828
refs/heads/tmp: 370fe2786109360f7c35b8ba552b83b773dd71d6
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f

branches/beta/src/doc/reference.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,10 +1924,16 @@ On an `extern` block, the following attributes are interpreted:
19241924
name and type. This is feature gated and the exact behavior is
19251925
implementation-defined (due to variety of linker invocation syntax).
19261926
- `link` - indicate that a native library should be linked to for the
1927-
declarations in this block to be linked correctly. `link` supports an optional `kind`
1928-
key with three possible values: `dylib`, `static`, and `framework`. See [external blocks](#external-blocks) for more about external blocks. Two
1927+
declarations in this block to be linked correctly. `link` supports an optional
1928+
`kind` key with three possible values: `dylib`, `static`, and `framework`. See
1929+
[external blocks](#external-blocks) for more about external blocks. Two
19291930
examples: `#[link(name = "readline")]` and
19301931
`#[link(name = "CoreFoundation", kind = "framework")]`.
1932+
- `linked_from` - indicates what native library this block of FFI items is
1933+
coming from. This attribute is of the form `#[linked_from = "foo"]` where
1934+
`foo` is the name of a library in either `#[link]` or a `-l` flag. This
1935+
attribute is currently required to export symbols from a Rust dynamic library
1936+
on Windows, and it is feature gated behind the `linked_from` feature.
19311937

19321938
On declarations inside an `extern` block, the following attributes are
19331939
interpreted:

branches/beta/src/librustc/metadata/creader.rs

Lines changed: 77 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use metadata::cstore::{CStore, CrateSource, MetadataBlob};
2020
use metadata::decoder;
2121
use metadata::loader;
2222
use metadata::loader::CratePaths;
23+
use util::nodemap::FnvHashMap;
2324

2425
use std::cell::RefCell;
2526
use std::path::PathBuf;
@@ -47,6 +48,7 @@ pub struct LocalCrateReader<'a, 'b:'a> {
4748
pub struct CrateReader<'a> {
4849
sess: &'a Session,
4950
next_crate_num: ast::CrateNum,
51+
foreign_item_map: FnvHashMap<String, Vec<ast::NodeId>>,
5052
}
5153

5254
impl<'a, 'b, 'v> visit::Visitor<'v> for LocalCrateReader<'a, 'b> {
@@ -157,6 +159,7 @@ impl<'a> CrateReader<'a> {
157159
CrateReader {
158160
sess: sess,
159161
next_crate_num: sess.cstore.next_crate_num(),
162+
foreign_item_map: FnvHashMap(),
160163
}
161164
}
162165

@@ -490,6 +493,20 @@ impl<'a> CrateReader<'a> {
490493
_ => None,
491494
}
492495
}
496+
497+
fn register_statically_included_foreign_items(&mut self) {
498+
let libs = self.sess.cstore.get_used_libraries();
499+
for (lib, list) in self.foreign_item_map.iter() {
500+
let is_static = libs.borrow().iter().any(|&(ref name, kind)| {
501+
lib == name && kind == cstore::NativeStatic
502+
});
503+
if is_static {
504+
for id in list {
505+
self.sess.cstore.add_statically_included_foreign_item(*id);
506+
}
507+
}
508+
}
509+
}
493510
}
494511

495512
impl<'a, 'b> LocalCrateReader<'a, 'b> {
@@ -515,6 +532,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
515532
for &(ref name, kind) in &self.sess.opts.libs {
516533
register_native_lib(self.sess, None, name.clone(), kind);
517534
}
535+
self.creader.register_statically_included_foreign_items();
518536
}
519537

520538
fn process_crate(&self, c: &ast::Crate) {
@@ -541,87 +559,73 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
541559
None,
542560
i.span,
543561
PathKind::Crate);
544-
self.ast_map.with_path(i.id, |path|
545-
cmeta.update_local_path(path));
562+
self.ast_map.with_path(i.id, |path| {
563+
cmeta.update_local_path(path)
564+
});
546565
self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
547566
}
548567
None => ()
549568
}
550569
}
551-
ast::ItemForeignMod(ref fm) => {
552-
if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic {
553-
return;
554-
}
570+
ast::ItemForeignMod(ref fm) => self.process_foreign_mod(i, fm),
571+
_ => { }
572+
}
573+
}
555574

556-
// First, add all of the custom link_args attributes
557-
let link_args = i.attrs.iter()
558-
.filter_map(|at| if at.name() == "link_args" {
559-
Some(at)
560-
} else {
561-
None
562-
})
563-
.collect::<Vec<&ast::Attribute>>();
564-
for m in &link_args {
565-
match m.value_str() {
566-
Some(linkarg) => self.sess.cstore.add_used_link_args(&linkarg),
567-
None => { /* fallthrough */ }
568-
}
569-
}
575+
fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod) {
576+
if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic {
577+
return;
578+
}
570579

571-
// Next, process all of the #[link(..)]-style arguments
572-
let link_args = i.attrs.iter()
573-
.filter_map(|at| if at.name() == "link" {
574-
Some(at)
575-
} else {
576-
None
577-
})
578-
.collect::<Vec<&ast::Attribute>>();
579-
for m in &link_args {
580-
match m.meta_item_list() {
581-
Some(items) => {
582-
let kind = items.iter().find(|k| {
583-
k.name() == "kind"
584-
}).and_then(|a| a.value_str());
585-
let kind = match kind {
586-
Some(k) => {
587-
if k == "static" {
588-
cstore::NativeStatic
589-
} else if self.sess.target.target.options.is_like_osx
590-
&& k == "framework" {
591-
cstore::NativeFramework
592-
} else if k == "framework" {
593-
cstore::NativeFramework
594-
} else if k == "dylib" {
595-
cstore::NativeUnknown
596-
} else {
597-
self.sess.span_err(m.span,
598-
&format!("unknown kind: `{}`",
599-
k));
600-
cstore::NativeUnknown
601-
}
602-
}
603-
None => cstore::NativeUnknown
604-
};
605-
let n = items.iter().find(|n| {
606-
n.name() == "name"
607-
}).and_then(|a| a.value_str());
608-
let n = match n {
609-
Some(n) => n,
610-
None => {
611-
self.sess.span_err(m.span,
612-
"#[link(...)] specified without \
613-
`name = \"foo\"`");
614-
InternedString::new("foo")
615-
}
616-
};
617-
register_native_lib(self.sess, Some(m.span),
618-
n.to_string(), kind);
619-
}
620-
None => {}
621-
}
622-
}
580+
// First, add all of the custom #[link_args] attributes
581+
for m in i.attrs.iter().filter(|a| a.check_name("link_args")) {
582+
if let Some(linkarg) = m.value_str() {
583+
self.sess.cstore.add_used_link_args(&linkarg);
623584
}
624-
_ => { }
585+
}
586+
587+
// Next, process all of the #[link(..)]-style arguments
588+
for m in i.attrs.iter().filter(|a| a.check_name("link")) {
589+
let items = match m.meta_item_list() {
590+
Some(item) => item,
591+
None => continue,
592+
};
593+
let kind = items.iter().find(|k| {
594+
k.check_name("kind")
595+
}).and_then(|a| a.value_str());
596+
let kind = match kind.as_ref().map(|s| &s[..]) {
597+
Some("static") => cstore::NativeStatic,
598+
Some("dylib") => cstore::NativeUnknown,
599+
Some("framework") => cstore::NativeFramework,
600+
Some(k) => {
601+
self.sess.span_err(m.span, &format!("unknown kind: `{}`", k));
602+
cstore::NativeUnknown
603+
}
604+
None => cstore::NativeUnknown
605+
};
606+
let n = items.iter().find(|n| {
607+
n.check_name("name")
608+
}).and_then(|a| a.value_str());
609+
let n = match n {
610+
Some(n) => n,
611+
None => {
612+
self.sess.span_err(m.span, "#[link(...)] specified without \
613+
`name = \"foo\"`");
614+
InternedString::new("foo")
615+
}
616+
};
617+
register_native_lib(self.sess, Some(m.span), n.to_string(), kind);
618+
}
619+
620+
// Finally, process the #[linked_from = "..."] attribute
621+
for m in i.attrs.iter().filter(|a| a.check_name("linked_from")) {
622+
let lib_name = match m.value_str() {
623+
Some(name) => name,
624+
None => continue,
625+
};
626+
let list = self.creader.foreign_item_map.entry(lib_name.to_string())
627+
.or_insert(Vec::new());
628+
list.extend(fm.items.iter().map(|it| it.id));
625629
}
626630
}
627631
}

branches/beta/src/librustc/metadata/cstore.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub use self::NativeLibraryKind::*;
2020
use back::svh::Svh;
2121
use metadata::{creader, decoder, loader};
2222
use session::search_paths::PathKind;
23-
use util::nodemap::{FnvHashMap, NodeMap};
23+
use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
2424

2525
use std::cell::{RefCell, Ref};
2626
use std::rc::Rc;
@@ -97,6 +97,7 @@ pub struct CStore {
9797
used_crate_sources: RefCell<Vec<CrateSource>>,
9898
used_libraries: RefCell<Vec<(String, NativeLibraryKind)>>,
9999
used_link_args: RefCell<Vec<String>>,
100+
statically_included_foreign_items: RefCell<NodeSet>,
100101
pub intr: Rc<IdentInterner>,
101102
}
102103

@@ -108,7 +109,8 @@ impl CStore {
108109
used_crate_sources: RefCell::new(Vec::new()),
109110
used_libraries: RefCell::new(Vec::new()),
110111
used_link_args: RefCell::new(Vec::new()),
111-
intr: intr
112+
intr: intr,
113+
statically_included_foreign_items: RefCell::new(NodeSet()),
112114
}
113115
}
114116

@@ -167,6 +169,7 @@ impl CStore {
167169
self.used_crate_sources.borrow_mut().clear();
168170
self.used_libraries.borrow_mut().clear();
169171
self.used_link_args.borrow_mut().clear();
172+
self.statically_included_foreign_items.borrow_mut().clear();
170173
}
171174

172175
// This method is used when generating the command line to pass through to
@@ -240,6 +243,14 @@ impl CStore {
240243
-> Option<ast::CrateNum> {
241244
self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
242245
}
246+
247+
pub fn add_statically_included_foreign_item(&self, id: ast::NodeId) {
248+
self.statically_included_foreign_items.borrow_mut().insert(id);
249+
}
250+
251+
pub fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool {
252+
self.statically_included_foreign_items.borrow().contains(&id)
253+
}
243254
}
244255

245256
impl crate_metadata {

branches/beta/src/libsyntax/feature_gate.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
8585
("on_unimplemented", "1.0.0", Active),
8686
("simd_ffi", "1.0.0", Active),
8787
("allocator", "1.0.0", Active),
88+
("linked_from", "1.3.0", Active),
8889

8990
("if_let", "1.0.0", Accepted),
9091
("while_let", "1.0.0", Accepted),
@@ -269,6 +270,10 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
269270
"the `#[fundamental]` attribute \
270271
is an experimental feature")),
271272

273+
("linked_from", Gated("linked_from",
274+
"the `#[linked_from]` attribute \
275+
is an experimental feature")),
276+
272277
// FIXME: #14408 whitelist docs since rustdoc looks at them
273278
("doc", Whitelisted),
274279

0 commit comments

Comments
 (0)