Auto merge of #41565 - rkruppe:llvm-sys, r=eddyb
Make only rustc_trans depend on rustc_llvm With these changes, only rustc_trans depends directly on rustc_llvm (and no crate gained a new dependency on trans). This means changing LLVM doesn't rebuild librustc or rustc_metadata, only rustc_trans, rustc_driver and the rustc executable Also, rustc_driver technically doesn't know about LLVM any more (of course, it still handles a ton of options that conceptually refer to LLVM, but it delegates their implementation to trans). What I *didn't* implement was merging most or all of rustc_llvm into rustc_trans. I ran into a nasty bug, which was probably just a silly typo somewhere but I probably won't have the time to figure it out in the next week or two. I opened #41699 for that step. Fixes #41473
This commit is contained in:
commit
fa78d5bb87
21
src/Cargo.lock
generated
21
src/Cargo.lock
generated
@ -405,6 +405,14 @@ name = "open"
|
|||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "owning_ref"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "panic_abort"
|
name = "panic_abort"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
@ -531,12 +539,12 @@ dependencies = [
|
|||||||
"fmt_macros 0.0.0",
|
"fmt_macros 0.0.0",
|
||||||
"graphviz 0.0.0",
|
"graphviz 0.0.0",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc_back 0.0.0",
|
"rustc_back 0.0.0",
|
||||||
"rustc_bitflags 0.0.0",
|
"rustc_bitflags 0.0.0",
|
||||||
"rustc_const_math 0.0.0",
|
"rustc_const_math 0.0.0",
|
||||||
"rustc_data_structures 0.0.0",
|
"rustc_data_structures 0.0.0",
|
||||||
"rustc_errors 0.0.0",
|
"rustc_errors 0.0.0",
|
||||||
"rustc_llvm 0.0.0",
|
|
||||||
"serialize 0.0.0",
|
"serialize 0.0.0",
|
||||||
"syntax 0.0.0",
|
"syntax 0.0.0",
|
||||||
"syntax_pos 0.0.0",
|
"syntax_pos 0.0.0",
|
||||||
@ -646,7 +654,6 @@ dependencies = [
|
|||||||
"rustc_errors 0.0.0",
|
"rustc_errors 0.0.0",
|
||||||
"rustc_incremental 0.0.0",
|
"rustc_incremental 0.0.0",
|
||||||
"rustc_lint 0.0.0",
|
"rustc_lint 0.0.0",
|
||||||
"rustc_llvm 0.0.0",
|
|
||||||
"rustc_metadata 0.0.0",
|
"rustc_metadata 0.0.0",
|
||||||
"rustc_mir 0.0.0",
|
"rustc_mir 0.0.0",
|
||||||
"rustc_passes 0.0.0",
|
"rustc_passes 0.0.0",
|
||||||
@ -720,13 +727,13 @@ version = "0.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"flate 0.0.0",
|
"flate 0.0.0",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"proc_macro 0.0.0",
|
"proc_macro 0.0.0",
|
||||||
"rustc 0.0.0",
|
"rustc 0.0.0",
|
||||||
"rustc_back 0.0.0",
|
"rustc_back 0.0.0",
|
||||||
"rustc_const_math 0.0.0",
|
"rustc_const_math 0.0.0",
|
||||||
"rustc_data_structures 0.0.0",
|
"rustc_data_structures 0.0.0",
|
||||||
"rustc_errors 0.0.0",
|
"rustc_errors 0.0.0",
|
||||||
"rustc_llvm 0.0.0",
|
|
||||||
"serialize 0.0.0",
|
"serialize 0.0.0",
|
||||||
"syntax 0.0.0",
|
"syntax 0.0.0",
|
||||||
"syntax_ext 0.0.0",
|
"syntax_ext 0.0.0",
|
||||||
@ -828,6 +835,7 @@ version = "0.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"flate 0.0.0",
|
"flate 0.0.0",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc 0.0.0",
|
"rustc 0.0.0",
|
||||||
"rustc_back 0.0.0",
|
"rustc_back 0.0.0",
|
||||||
"rustc_bitflags 0.0.0",
|
"rustc_bitflags 0.0.0",
|
||||||
@ -923,6 +931,11 @@ dependencies = [
|
|||||||
name = "serialize"
|
name = "serialize"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "std"
|
name = "std"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
@ -1167,6 +1180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
|
"checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
|
||||||
"checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167"
|
"checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167"
|
||||||
"checksum open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3478ed1686bd1300c8a981a940abc92b06fac9cbef747f4c668d4e032ff7b842"
|
"checksum open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3478ed1686bd1300c8a981a940abc92b06fac9cbef747f4c668d4e032ff7b842"
|
||||||
|
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
|
||||||
"checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8"
|
"checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8"
|
||||||
"checksum pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ab1e588ef8efd702c7ed9d2bd774db5e6f4d878bb5a1a9f371828fbdff6973"
|
"checksum pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ab1e588ef8efd702c7ed9d2bd774db5e6f4d878bb5a1a9f371828fbdff6973"
|
||||||
"checksum pulldown-cmark 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1058d7bb927ca067656537eec4e02c2b4b70eaaa129664c5b90c111e20326f41"
|
"checksum pulldown-cmark 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1058d7bb927ca067656537eec4e02c2b4b70eaaa129664c5b90c111e20326f41"
|
||||||
@ -1180,6 +1194,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
|
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
|
||||||
"checksum serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a702319c807c016e51f672e5c77d6f0b46afddd744b5e437d6b8436b888b458f"
|
"checksum serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a702319c807c016e51f672e5c77d6f0b46afddd744b5e437d6b8436b888b458f"
|
||||||
"checksum serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc45439552eb8fb86907a2c41c1fd0ef97458efb87ff7f878db466eb581824e"
|
"checksum serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc45439552eb8fb86907a2c41c1fd0ef97458efb87ff7f878db466eb581824e"
|
||||||
|
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
|
||||||
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
|
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
|
||||||
"checksum tar 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ab0ef9ead2fe0aa9e18475a96a207bfd5143f4124779ef7429503a8665416ce8"
|
"checksum tar 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ab0ef9ead2fe0aa9e18475a96a207bfd5143f4124779ef7429503a8665416ce8"
|
||||||
"checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a"
|
"checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a"
|
||||||
|
@ -13,12 +13,12 @@ arena = { path = "../libarena" }
|
|||||||
fmt_macros = { path = "../libfmt_macros" }
|
fmt_macros = { path = "../libfmt_macros" }
|
||||||
graphviz = { path = "../libgraphviz" }
|
graphviz = { path = "../libgraphviz" }
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
owning_ref = "0.3.3"
|
||||||
rustc_back = { path = "../librustc_back" }
|
rustc_back = { path = "../librustc_back" }
|
||||||
rustc_bitflags = { path = "../librustc_bitflags" }
|
rustc_bitflags = { path = "../librustc_bitflags" }
|
||||||
rustc_const_math = { path = "../librustc_const_math" }
|
rustc_const_math = { path = "../librustc_const_math" }
|
||||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||||
rustc_errors = { path = "../librustc_errors" }
|
rustc_errors = { path = "../librustc_errors" }
|
||||||
rustc_llvm = { path = "../librustc_llvm" }
|
|
||||||
serialize = { path = "../libserialize" }
|
serialize = { path = "../libserialize" }
|
||||||
syntax = { path = "../libsyntax" }
|
syntax = { path = "../libsyntax" }
|
||||||
syntax_pos = { path = "../libsyntax_pos" }
|
syntax_pos = { path = "../libsyntax_pos" }
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
extern crate graphviz;
|
extern crate graphviz;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate rustc_llvm as llvm;
|
extern crate owning_ref;
|
||||||
extern crate rustc_back;
|
extern crate rustc_back;
|
||||||
extern crate rustc_data_structures;
|
extern crate rustc_data_structures;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
|
@ -36,8 +36,9 @@
|
|||||||
use util::nodemap::{NodeSet, DefIdMap};
|
use util::nodemap::{NodeSet, DefIdMap};
|
||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use owning_ref::ErasedBoxRef;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ext::base::SyntaxExtension;
|
use syntax::ext::base::SyntaxExtension;
|
||||||
use syntax::symbol::Symbol;
|
use syntax::symbol::Symbol;
|
||||||
@ -201,11 +202,33 @@ pub fn new() -> EncodedMetadataHashes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The backend's way to give the crate store access to the metadata in a library.
|
||||||
|
/// Note that it returns the raw metadata bytes stored in the library file, whether
|
||||||
|
/// it is compressed, uncompressed, some weird mix, etc.
|
||||||
|
/// rmeta files are backend independent and not handled here.
|
||||||
|
///
|
||||||
|
/// At the time of this writing, there is only one backend and one way to store
|
||||||
|
/// metadata in library -- this trait just serves to decouple rustc_metadata from
|
||||||
|
/// the archive reader, which depends on LLVM.
|
||||||
|
pub trait MetadataLoader {
|
||||||
|
fn get_rlib_metadata(&self,
|
||||||
|
target: &Target,
|
||||||
|
filename: &Path)
|
||||||
|
-> Result<ErasedBoxRef<[u8]>, String>;
|
||||||
|
fn get_dylib_metadata(&self,
|
||||||
|
target: &Target,
|
||||||
|
filename: &Path)
|
||||||
|
-> Result<ErasedBoxRef<[u8]>, String>;
|
||||||
|
}
|
||||||
|
|
||||||
/// A store of Rust crates, through with their metadata
|
/// A store of Rust crates, through with their metadata
|
||||||
/// can be accessed.
|
/// can be accessed.
|
||||||
pub trait CrateStore {
|
pub trait CrateStore {
|
||||||
fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc<Any>;
|
fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc<Any>;
|
||||||
|
|
||||||
|
// access to the metadata loader
|
||||||
|
fn metadata_loader(&self) -> &MetadataLoader;
|
||||||
|
|
||||||
// item info
|
// item info
|
||||||
fn visibility(&self, def: DefId) -> ty::Visibility;
|
fn visibility(&self, def: DefId) -> ty::Visibility;
|
||||||
fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap<DefId>>;
|
fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap<DefId>>;
|
||||||
@ -275,8 +298,6 @@ fn item_body<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
|||||||
fn used_link_args(&self) -> Vec<String>;
|
fn used_link_args(&self) -> Vec<String>;
|
||||||
|
|
||||||
// utility functions
|
// utility functions
|
||||||
fn metadata_filename(&self) -> &str;
|
|
||||||
fn metadata_section_name(&self, target: &Target) -> &str;
|
|
||||||
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>;
|
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>;
|
||||||
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
|
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
|
||||||
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
|
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
|
||||||
@ -413,8 +434,6 @@ fn used_libraries(&self) -> Vec<NativeLibrary> { vec![] }
|
|||||||
fn used_link_args(&self) -> Vec<String> { vec![] }
|
fn used_link_args(&self) -> Vec<String> { vec![] }
|
||||||
|
|
||||||
// utility functions
|
// utility functions
|
||||||
fn metadata_filename(&self) -> &str { bug!("metadata_filename") }
|
|
||||||
fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") }
|
|
||||||
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
|
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
|
||||||
{ vec![] }
|
{ vec![] }
|
||||||
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }
|
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }
|
||||||
@ -427,6 +446,9 @@ fn encode_metadata<'a, 'tcx>(&self,
|
|||||||
bug!("encode_metadata")
|
bug!("encode_metadata")
|
||||||
}
|
}
|
||||||
fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
|
fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
|
||||||
|
|
||||||
|
// access to the metadata loader
|
||||||
|
fn metadata_loader(&self) -> &MetadataLoader { bug!("metadata_loader") }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CrateLoader {
|
pub trait CrateLoader {
|
||||||
|
@ -328,7 +328,7 @@ pub struct Options {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
pub enum PrintRequest {
|
pub enum PrintRequest {
|
||||||
FileNames,
|
FileNames,
|
||||||
Sysroot,
|
Sysroot,
|
||||||
|
@ -37,19 +37,16 @@
|
|||||||
use rustc_back::{LinkerFlavor, PanicStrategy};
|
use rustc_back::{LinkerFlavor, PanicStrategy};
|
||||||
use rustc_back::target::Target;
|
use rustc_back::target::Target;
|
||||||
use rustc_data_structures::flock;
|
use rustc_data_structures::flock;
|
||||||
use llvm;
|
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::cell::{self, Cell, RefCell};
|
use std::cell::{self, Cell, RefCell};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::CString;
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use libc::c_int;
|
|
||||||
|
|
||||||
mod code_stats;
|
mod code_stats;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
@ -713,8 +710,6 @@ pub fn build_session_(sopts: config::Options,
|
|||||||
out_of_fuel: Cell::new(false),
|
out_of_fuel: Cell::new(false),
|
||||||
};
|
};
|
||||||
|
|
||||||
init_llvm(&sess);
|
|
||||||
|
|
||||||
sess
|
sess
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -743,55 +738,6 @@ pub enum IncrCompSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_llvm(sess: &Session) {
|
|
||||||
unsafe {
|
|
||||||
// Before we touch LLVM, make sure that multithreading is enabled.
|
|
||||||
use std::sync::Once;
|
|
||||||
static INIT: Once = Once::new();
|
|
||||||
static mut POISONED: bool = false;
|
|
||||||
INIT.call_once(|| {
|
|
||||||
if llvm::LLVMStartMultithreaded() != 1 {
|
|
||||||
// use an extra bool to make sure that all future usage of LLVM
|
|
||||||
// cannot proceed despite the Once not running more than once.
|
|
||||||
POISONED = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
configure_llvm(sess);
|
|
||||||
});
|
|
||||||
|
|
||||||
if POISONED {
|
|
||||||
bug!("couldn't enable multi-threaded LLVM");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn configure_llvm(sess: &Session) {
|
|
||||||
let mut llvm_c_strs = Vec::new();
|
|
||||||
let mut llvm_args = Vec::new();
|
|
||||||
|
|
||||||
{
|
|
||||||
let mut add = |arg: &str| {
|
|
||||||
let s = CString::new(arg).unwrap();
|
|
||||||
llvm_args.push(s.as_ptr());
|
|
||||||
llvm_c_strs.push(s);
|
|
||||||
};
|
|
||||||
add("rustc"); // fake program name
|
|
||||||
if sess.time_llvm_passes() { add("-time-passes"); }
|
|
||||||
if sess.print_llvm_passes() { add("-debug-pass=Structure"); }
|
|
||||||
|
|
||||||
for arg in &sess.opts.cg.llvm_args {
|
|
||||||
add(&(*arg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
llvm::LLVMInitializePasses();
|
|
||||||
|
|
||||||
llvm::initialize_available_targets();
|
|
||||||
|
|
||||||
llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int,
|
|
||||||
llvm_args.as_ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
|
pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
|
||||||
let emitter: Box<Emitter> = match output {
|
let emitter: Box<Emitter> = match output {
|
||||||
config::ErrorOutputType::HumanReadable(color_config) => {
|
config::ErrorOutputType::HumanReadable(color_config) => {
|
||||||
|
@ -22,7 +22,6 @@ rustc_data_structures = { path = "../librustc_data_structures" }
|
|||||||
rustc_errors = { path = "../librustc_errors" }
|
rustc_errors = { path = "../librustc_errors" }
|
||||||
rustc_incremental = { path = "../librustc_incremental" }
|
rustc_incremental = { path = "../librustc_incremental" }
|
||||||
rustc_lint = { path = "../librustc_lint" }
|
rustc_lint = { path = "../librustc_lint" }
|
||||||
rustc_llvm = { path = "../librustc_llvm" }
|
|
||||||
rustc_metadata = { path = "../librustc_metadata" }
|
rustc_metadata = { path = "../librustc_metadata" }
|
||||||
rustc_mir = { path = "../librustc_mir" }
|
rustc_mir = { path = "../librustc_mir" }
|
||||||
rustc_passes = { path = "../librustc_passes" }
|
rustc_passes = { path = "../librustc_passes" }
|
||||||
|
@ -56,7 +56,6 @@
|
|||||||
extern crate rustc_trans;
|
extern crate rustc_trans;
|
||||||
extern crate rustc_typeck;
|
extern crate rustc_typeck;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate rustc_llvm as llvm;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
@ -70,7 +69,7 @@
|
|||||||
use rustc_save_analysis as save;
|
use rustc_save_analysis as save;
|
||||||
use rustc_save_analysis::DumpHandler;
|
use rustc_save_analysis::DumpHandler;
|
||||||
use rustc_trans::back::link;
|
use rustc_trans::back::link;
|
||||||
use rustc_trans::back::write::{create_target_machine, RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS};
|
use rustc_trans::back::write::{RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS};
|
||||||
use rustc::dep_graph::DepGraph;
|
use rustc::dep_graph::DepGraph;
|
||||||
use rustc::session::{self, config, Session, build_session, CompileResult};
|
use rustc::session::{self, config, Session, build_session, CompileResult};
|
||||||
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
|
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
|
||||||
@ -182,7 +181,7 @@ macro_rules! do_or_return {($expr: expr, $sess: expr) => {
|
|||||||
let (sopts, cfg) = config::build_session_options_and_crate_config(&matches);
|
let (sopts, cfg) = config::build_session_options_and_crate_config(&matches);
|
||||||
|
|
||||||
if sopts.debugging_opts.debug_llvm {
|
if sopts.debugging_opts.debug_llvm {
|
||||||
unsafe { llvm::LLVMRustSetDebug(1); }
|
rustc_trans::enable_llvm_debug();
|
||||||
}
|
}
|
||||||
|
|
||||||
let descriptions = diagnostics_registry();
|
let descriptions = diagnostics_registry();
|
||||||
@ -204,13 +203,14 @@ macro_rules! do_or_return {($expr: expr, $sess: expr) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let dep_graph = DepGraph::new(sopts.build_dep_graph());
|
let dep_graph = DepGraph::new(sopts.build_dep_graph());
|
||||||
let cstore = Rc::new(CStore::new(&dep_graph));
|
let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
|
||||||
|
|
||||||
let loader = file_loader.unwrap_or(box RealFileLoader);
|
let loader = file_loader.unwrap_or(box RealFileLoader);
|
||||||
let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping()));
|
let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping()));
|
||||||
let mut sess = session::build_session_with_codemap(
|
let mut sess = session::build_session_with_codemap(
|
||||||
sopts, &dep_graph, input_file_path, descriptions, cstore.clone(), codemap, emitter_dest,
|
sopts, &dep_graph, input_file_path, descriptions, cstore.clone(), codemap, emitter_dest,
|
||||||
);
|
);
|
||||||
|
rustc_trans::init(&sess);
|
||||||
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
||||||
|
|
||||||
let mut cfg = config::build_configuration(&sess, cfg);
|
let mut cfg = config::build_configuration(&sess, cfg);
|
||||||
@ -409,12 +409,13 @@ fn no_input(&mut self,
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let dep_graph = DepGraph::new(sopts.build_dep_graph());
|
let dep_graph = DepGraph::new(sopts.build_dep_graph());
|
||||||
let cstore = Rc::new(CStore::new(&dep_graph));
|
let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
|
||||||
let mut sess = build_session(sopts.clone(),
|
let mut sess = build_session(sopts.clone(),
|
||||||
&dep_graph,
|
&dep_graph,
|
||||||
None,
|
None,
|
||||||
descriptions.clone(),
|
descriptions.clone(),
|
||||||
cstore.clone());
|
cstore.clone());
|
||||||
|
rustc_trans::init(&sess);
|
||||||
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
||||||
let mut cfg = config::build_configuration(&sess, cfg.clone());
|
let mut cfg = config::build_configuration(&sess, cfg.clone());
|
||||||
target_features::add_configuration(&mut cfg, &sess);
|
target_features::add_configuration(&mut cfg, &sess);
|
||||||
@ -558,7 +559,11 @@ pub fn list_metadata(sess: &Session, matches: &getopts::Matches, input: &Input)
|
|||||||
&Input::File(ref ifile) => {
|
&Input::File(ref ifile) => {
|
||||||
let path = &(*ifile);
|
let path = &(*ifile);
|
||||||
let mut v = Vec::new();
|
let mut v = Vec::new();
|
||||||
locator::list_file_metadata(&sess.target.target, path, &mut v).unwrap();
|
locator::list_file_metadata(&sess.target.target,
|
||||||
|
path,
|
||||||
|
sess.cstore.metadata_loader(),
|
||||||
|
&mut v)
|
||||||
|
.unwrap();
|
||||||
println!("{}", String::from_utf8(v).unwrap());
|
println!("{}", String::from_utf8(v).unwrap());
|
||||||
}
|
}
|
||||||
&Input::Str { .. } => {
|
&Input::Str { .. } => {
|
||||||
@ -665,14 +670,6 @@ fn print_crate_info(sess: &Session,
|
|||||||
println!("{}", cfg);
|
println!("{}", cfg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PrintRequest::TargetCPUs => {
|
|
||||||
let tm = create_target_machine(sess);
|
|
||||||
unsafe { llvm::LLVMRustPrintTargetCPUs(tm); }
|
|
||||||
}
|
|
||||||
PrintRequest::TargetFeatures => {
|
|
||||||
let tm = create_target_machine(sess);
|
|
||||||
unsafe { llvm::LLVMRustPrintTargetFeatures(tm); }
|
|
||||||
}
|
|
||||||
PrintRequest::RelocationModels => {
|
PrintRequest::RelocationModels => {
|
||||||
println!("Available relocation models:");
|
println!("Available relocation models:");
|
||||||
for &(name, _) in RELOC_MODEL_ARGS.iter() {
|
for &(name, _) in RELOC_MODEL_ARGS.iter() {
|
||||||
@ -687,6 +684,9 @@ fn print_crate_info(sess: &Session,
|
|||||||
}
|
}
|
||||||
println!("");
|
println!("");
|
||||||
}
|
}
|
||||||
|
PrintRequest::TargetCPUs | PrintRequest::TargetFeatures => {
|
||||||
|
rustc_trans::print(*req, sess);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Compilation::Stop;
|
return Compilation::Stop;
|
||||||
@ -724,10 +724,7 @@ fn unw(x: Option<&str>) -> &str {
|
|||||||
println!("commit-date: {}", unw(commit_date_str()));
|
println!("commit-date: {}", unw(commit_date_str()));
|
||||||
println!("host: {}", config::host_triple());
|
println!("host: {}", config::host_triple());
|
||||||
println!("release: {}", unw(release_str()));
|
println!("release: {}", unw(release_str()));
|
||||||
unsafe {
|
rustc_trans::print_version();
|
||||||
println!("LLVM version: {}.{}",
|
|
||||||
llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1020,9 +1017,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cg_flags.contains(&"passes=list".to_string()) {
|
if cg_flags.contains(&"passes=list".to_string()) {
|
||||||
unsafe {
|
rustc_trans::print_passes();
|
||||||
::llvm::LLVMRustPrintPasses();
|
|
||||||
}
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,24 +9,9 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use llvm::LLVMRustHasFeature;
|
|
||||||
use rustc::session::Session;
|
use rustc::session::Session;
|
||||||
use rustc_trans::back::write::create_target_machine;
|
|
||||||
use syntax::symbol::Symbol;
|
use syntax::symbol::Symbol;
|
||||||
use libc::c_char;
|
use rustc_trans;
|
||||||
|
|
||||||
// WARNING: the features must be known to LLVM or the feature
|
|
||||||
// detection code will walk past the end of the feature array,
|
|
||||||
// leading to crashes.
|
|
||||||
|
|
||||||
const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "vfp2\0", "vfp3\0", "vfp4\0"];
|
|
||||||
|
|
||||||
const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bmi2\0", "sse\0",
|
|
||||||
"sse2\0", "sse3\0", "sse4.1\0", "sse4.2\0",
|
|
||||||
"ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0",
|
|
||||||
"sse4a\0", "rdrnd\0", "rdseed\0", "fma\0"];
|
|
||||||
|
|
||||||
const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"];
|
|
||||||
|
|
||||||
/// Add `target_feature = "..."` cfgs for a variety of platform
|
/// Add `target_feature = "..."` cfgs for a variety of platform
|
||||||
/// specific features (SSE, NEON etc.).
|
/// specific features (SSE, NEON etc.).
|
||||||
@ -34,21 +19,10 @@
|
|||||||
/// This is performed by checking whether a whitelisted set of
|
/// This is performed by checking whether a whitelisted set of
|
||||||
/// features is available on the target machine, by querying LLVM.
|
/// features is available on the target machine, by querying LLVM.
|
||||||
pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) {
|
pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) {
|
||||||
let target_machine = create_target_machine(sess);
|
|
||||||
|
|
||||||
let whitelist = match &*sess.target.target.arch {
|
|
||||||
"arm" => ARM_WHITELIST,
|
|
||||||
"x86" | "x86_64" => X86_WHITELIST,
|
|
||||||
"hexagon" => HEXAGON_WHITELIST,
|
|
||||||
_ => &[],
|
|
||||||
};
|
|
||||||
|
|
||||||
let tf = Symbol::intern("target_feature");
|
let tf = Symbol::intern("target_feature");
|
||||||
for feat in whitelist {
|
|
||||||
assert_eq!(feat.chars().last(), Some('\0'));
|
for feat in rustc_trans::target_features(sess) {
|
||||||
if unsafe { LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } {
|
cfg.insert((tf, Some(feat)));
|
||||||
cfg.insert((tf, Some(Symbol::intern(&feat[..feat.len() - 1]))));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let requested_features = sess.opts.cg.target_feature.split(',');
|
let requested_features = sess.opts.cg.target_feature.split(',');
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
use rustc::dep_graph::DepGraph;
|
use rustc::dep_graph::DepGraph;
|
||||||
use rustc_lint;
|
use rustc_lint;
|
||||||
use rustc_resolve::MakeGlobMap;
|
use rustc_resolve::MakeGlobMap;
|
||||||
|
use rustc_trans;
|
||||||
use rustc::middle::lang_items;
|
use rustc::middle::lang_items;
|
||||||
use rustc::middle::free_region::FreeRegionMap;
|
use rustc::middle::free_region::FreeRegionMap;
|
||||||
use rustc::middle::region::{CodeExtent, RegionMaps};
|
use rustc::middle::region::{CodeExtent, RegionMaps};
|
||||||
@ -104,13 +105,14 @@ fn test_env<F>(source_string: &str,
|
|||||||
|
|
||||||
let dep_graph = DepGraph::new(false);
|
let dep_graph = DepGraph::new(false);
|
||||||
let _ignore = dep_graph.in_ignore();
|
let _ignore = dep_graph.in_ignore();
|
||||||
let cstore = Rc::new(CStore::new(&dep_graph));
|
let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
|
||||||
let sess = session::build_session_(options,
|
let sess = session::build_session_(options,
|
||||||
&dep_graph,
|
&dep_graph,
|
||||||
None,
|
None,
|
||||||
diagnostic_handler,
|
diagnostic_handler,
|
||||||
Rc::new(CodeMap::new(FilePathMapping::empty())),
|
Rc::new(CodeMap::new(FilePathMapping::empty())),
|
||||||
cstore.clone());
|
cstore.clone());
|
||||||
|
rustc_trans::init(&sess);
|
||||||
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
||||||
let input = config::Input::Str {
|
let input = config::Input::Str {
|
||||||
name: driver::anon_src(),
|
name: driver::anon_src(),
|
||||||
|
@ -11,13 +11,13 @@ crate-type = ["dylib"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
flate = { path = "../libflate" }
|
flate = { path = "../libflate" }
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
owning_ref = "0.3.3"
|
||||||
proc_macro = { path = "../libproc_macro" }
|
proc_macro = { path = "../libproc_macro" }
|
||||||
rustc = { path = "../librustc" }
|
rustc = { path = "../librustc" }
|
||||||
rustc_back = { path = "../librustc_back" }
|
rustc_back = { path = "../librustc_back" }
|
||||||
rustc_const_math = { path = "../librustc_const_math" }
|
rustc_const_math = { path = "../librustc_const_math" }
|
||||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||||
rustc_errors = { path = "../librustc_errors" }
|
rustc_errors = { path = "../librustc_errors" }
|
||||||
rustc_llvm = { path = "../librustc_llvm" }
|
|
||||||
serialize = { path = "../libserialize" }
|
serialize = { path = "../libserialize" }
|
||||||
syntax = { path = "../libsyntax" }
|
syntax = { path = "../libsyntax" }
|
||||||
syntax_ext = { path = "../libsyntax_ext" }
|
syntax_ext = { path = "../libsyntax_ext" }
|
||||||
|
@ -393,6 +393,7 @@ fn resolve_crate(&mut self,
|
|||||||
rejected_via_filename: vec![],
|
rejected_via_filename: vec![],
|
||||||
should_match_name: true,
|
should_match_name: true,
|
||||||
is_proc_macro: Some(false),
|
is_proc_macro: Some(false),
|
||||||
|
metadata_loader: &*self.cstore.metadata_loader,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.load(&mut locate_ctxt).or_else(|| {
|
self.load(&mut locate_ctxt).or_else(|| {
|
||||||
@ -554,6 +555,7 @@ fn read_extension_crate(&mut self, span: Span, info: &ExternCrateInfo) -> Extens
|
|||||||
rejected_via_filename: vec![],
|
rejected_via_filename: vec![],
|
||||||
should_match_name: true,
|
should_match_name: true,
|
||||||
is_proc_macro: None,
|
is_proc_macro: None,
|
||||||
|
metadata_loader: &*self.cstore.metadata_loader,
|
||||||
};
|
};
|
||||||
let library = self.load(&mut locate_ctxt).or_else(|| {
|
let library = self.load(&mut locate_ctxt).or_else(|| {
|
||||||
if !is_cross {
|
if !is_cross {
|
||||||
|
@ -11,21 +11,20 @@
|
|||||||
// The crate store - a central repo for information collected about external
|
// The crate store - a central repo for information collected about external
|
||||||
// crates and libraries
|
// crates and libraries
|
||||||
|
|
||||||
use locator;
|
|
||||||
use schema::{self, Tracked};
|
use schema::{self, Tracked};
|
||||||
|
|
||||||
use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind};
|
use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind};
|
||||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefIndex, DefId};
|
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefIndex, DefId};
|
||||||
use rustc::hir::map::definitions::DefPathTable;
|
use rustc::hir::map::definitions::DefPathTable;
|
||||||
use rustc::hir::svh::Svh;
|
use rustc::hir::svh::Svh;
|
||||||
use rustc::middle::cstore::{DepKind, ExternCrate};
|
use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
|
||||||
use rustc_back::PanicStrategy;
|
use rustc_back::PanicStrategy;
|
||||||
use rustc_data_structures::indexed_vec::IndexVec;
|
use rustc_data_structures::indexed_vec::IndexVec;
|
||||||
use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap, DefIdMap};
|
use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap, DefIdMap};
|
||||||
|
|
||||||
use std::cell::{RefCell, Cell};
|
use std::cell::{RefCell, Cell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use flate::Bytes;
|
use owning_ref::ErasedBoxRef;
|
||||||
use syntax::{ast, attr};
|
use syntax::{ast, attr};
|
||||||
use syntax::ext::base::SyntaxExtension;
|
use syntax::ext::base::SyntaxExtension;
|
||||||
use syntax::symbol::Symbol;
|
use syntax::symbol::Symbol;
|
||||||
@ -43,11 +42,7 @@
|
|||||||
// own crate numbers.
|
// own crate numbers.
|
||||||
pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
|
pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
|
||||||
|
|
||||||
pub enum MetadataBlob {
|
pub struct MetadataBlob(pub ErasedBoxRef<[u8]>);
|
||||||
Inflated(Bytes),
|
|
||||||
Archive(locator::ArchiveMetadata),
|
|
||||||
Raw(Vec<u8>),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Holds information about a syntax_pos::FileMap imported from another crate.
|
/// Holds information about a syntax_pos::FileMap imported from another crate.
|
||||||
/// See `imported_filemaps()` for more information.
|
/// See `imported_filemaps()` for more information.
|
||||||
@ -103,10 +98,11 @@ pub struct CStore {
|
|||||||
statically_included_foreign_items: RefCell<FxHashSet<DefIndex>>,
|
statically_included_foreign_items: RefCell<FxHashSet<DefIndex>>,
|
||||||
pub dllimport_foreign_items: RefCell<FxHashSet<DefIndex>>,
|
pub dllimport_foreign_items: RefCell<FxHashSet<DefIndex>>,
|
||||||
pub visible_parent_map: RefCell<DefIdMap<DefId>>,
|
pub visible_parent_map: RefCell<DefIdMap<DefId>>,
|
||||||
|
pub metadata_loader: Box<MetadataLoader>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CStore {
|
impl CStore {
|
||||||
pub fn new(dep_graph: &DepGraph) -> CStore {
|
pub fn new(dep_graph: &DepGraph, metadata_loader: Box<MetadataLoader>) -> CStore {
|
||||||
CStore {
|
CStore {
|
||||||
dep_graph: dep_graph.clone(),
|
dep_graph: dep_graph.clone(),
|
||||||
metas: RefCell::new(FxHashMap()),
|
metas: RefCell::new(FxHashMap()),
|
||||||
@ -116,6 +112,7 @@ pub fn new(dep_graph: &DepGraph) -> CStore {
|
|||||||
statically_included_foreign_items: RefCell::new(FxHashSet()),
|
statically_included_foreign_items: RefCell::new(FxHashSet()),
|
||||||
dllimport_foreign_items: RefCell::new(FxHashSet()),
|
dllimport_foreign_items: RefCell::new(FxHashSet()),
|
||||||
visible_parent_map: RefCell::new(FxHashMap()),
|
visible_parent_map: RefCell::new(FxHashMap()),
|
||||||
|
metadata_loader: metadata_loader,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,12 +10,11 @@
|
|||||||
|
|
||||||
use cstore;
|
use cstore;
|
||||||
use encoder;
|
use encoder;
|
||||||
use locator;
|
|
||||||
use schema;
|
use schema;
|
||||||
|
|
||||||
use rustc::dep_graph::DepTrackingMapConfig;
|
use rustc::dep_graph::DepTrackingMapConfig;
|
||||||
use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind,
|
use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind,
|
||||||
ExternCrate, NativeLibrary, LinkMeta,
|
ExternCrate, NativeLibrary, MetadataLoader, LinkMeta,
|
||||||
LinkagePreference, LoadedMacro, EncodedMetadata};
|
LinkagePreference, LoadedMacro, EncodedMetadata};
|
||||||
use rustc::hir::def;
|
use rustc::hir::def;
|
||||||
use rustc::middle::lang_items;
|
use rustc::middle::lang_items;
|
||||||
@ -38,7 +37,6 @@
|
|||||||
use syntax::symbol::Symbol;
|
use syntax::symbol::Symbol;
|
||||||
use syntax_pos::{Span, NO_EXPANSION};
|
use syntax_pos::{Span, NO_EXPANSION};
|
||||||
use rustc::hir::svh::Svh;
|
use rustc::hir::svh::Svh;
|
||||||
use rustc_back::target::Target;
|
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
|
|
||||||
macro_rules! provide {
|
macro_rules! provide {
|
||||||
@ -135,6 +133,10 @@ fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc<Any> {
|
|||||||
self.get_crate_data(krate)
|
self.get_crate_data(krate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn metadata_loader(&self) -> &MetadataLoader {
|
||||||
|
&*self.metadata_loader
|
||||||
|
}
|
||||||
|
|
||||||
fn visibility(&self, def: DefId) -> ty::Visibility {
|
fn visibility(&self, def: DefId) -> ty::Visibility {
|
||||||
self.dep_graph.read(DepNode::MetaData(def));
|
self.dep_graph.read(DepNode::MetaData(def));
|
||||||
self.get_crate_data(def.krate).get_visibility(def.index)
|
self.get_crate_data(def.krate).get_visibility(def.index)
|
||||||
@ -420,17 +422,6 @@ fn used_link_args(&self) -> Vec<String>
|
|||||||
{
|
{
|
||||||
self.get_used_link_args().borrow().clone()
|
self.get_used_link_args().borrow().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn metadata_filename(&self) -> &str
|
|
||||||
{
|
|
||||||
locator::METADATA_FILENAME
|
|
||||||
}
|
|
||||||
|
|
||||||
fn metadata_section_name(&self, target: &Target) -> &str
|
|
||||||
{
|
|
||||||
locator::meta_section_name(target)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
|
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
|
||||||
{
|
{
|
||||||
self.do_get_used_crates(prefer)
|
self.do_get_used_crates(prefer)
|
||||||
@ -522,4 +513,4 @@ fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap<DefId>> {
|
|||||||
drop(visible_parent_map);
|
drop(visible_parent_map);
|
||||||
self.visible_parent_map.borrow()
|
self.visible_parent_map.borrow()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -77,11 +77,7 @@ fn decoder(self, pos: usize) -> DecodeContext<'a, 'tcx> {
|
|||||||
|
|
||||||
impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob {
|
impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob {
|
||||||
fn raw_bytes(self) -> &'a [u8] {
|
fn raw_bytes(self) -> &'a [u8] {
|
||||||
match *self {
|
&self.0
|
||||||
MetadataBlob::Inflated(ref vec) => vec,
|
|
||||||
MetadataBlob::Archive(ref ar) => ar.as_slice(),
|
|
||||||
MetadataBlob::Raw(ref vec) => vec,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
extern crate syntax_pos;
|
extern crate syntax_pos;
|
||||||
extern crate flate;
|
extern crate flate;
|
||||||
extern crate serialize as rustc_serialize; // used by deriving
|
extern crate serialize as rustc_serialize; // used by deriving
|
||||||
|
extern crate owning_ref;
|
||||||
extern crate rustc_errors as errors;
|
extern crate rustc_errors as errors;
|
||||||
extern crate syntax_ext;
|
extern crate syntax_ext;
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
@ -46,7 +47,6 @@
|
|||||||
extern crate rustc_back;
|
extern crate rustc_back;
|
||||||
extern crate rustc_const_math;
|
extern crate rustc_const_math;
|
||||||
extern crate rustc_data_structures;
|
extern crate rustc_data_structures;
|
||||||
extern crate rustc_llvm;
|
|
||||||
|
|
||||||
mod diagnostics;
|
mod diagnostics;
|
||||||
|
|
||||||
|
@ -224,15 +224,12 @@
|
|||||||
use schema::{METADATA_HEADER, rustc_version};
|
use schema::{METADATA_HEADER, rustc_version};
|
||||||
|
|
||||||
use rustc::hir::svh::Svh;
|
use rustc::hir::svh::Svh;
|
||||||
|
use rustc::middle::cstore::MetadataLoader;
|
||||||
use rustc::session::{config, Session};
|
use rustc::session::{config, Session};
|
||||||
use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
|
use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
|
||||||
use rustc::session::search_paths::PathKind;
|
use rustc::session::search_paths::PathKind;
|
||||||
use rustc::util::common;
|
|
||||||
use rustc::util::nodemap::FxHashMap;
|
use rustc::util::nodemap::FxHashMap;
|
||||||
|
|
||||||
use rustc_llvm as llvm;
|
|
||||||
use rustc_llvm::{False, ObjectFile, mk_section_iter};
|
|
||||||
use rustc_llvm::archive_ro::ArchiveRO;
|
|
||||||
use errors::DiagnosticBuilder;
|
use errors::DiagnosticBuilder;
|
||||||
use syntax::symbol::Symbol;
|
use syntax::symbol::Symbol;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
@ -243,11 +240,10 @@
|
|||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::ptr;
|
|
||||||
use std::slice;
|
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
use flate;
|
use flate;
|
||||||
|
use owning_ref::{ErasedBoxRef, OwningRef};
|
||||||
|
|
||||||
pub struct CrateMismatch {
|
pub struct CrateMismatch {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
@ -272,12 +268,7 @@ pub struct Context<'a> {
|
|||||||
pub rejected_via_filename: Vec<CrateMismatch>,
|
pub rejected_via_filename: Vec<CrateMismatch>,
|
||||||
pub should_match_name: bool,
|
pub should_match_name: bool,
|
||||||
pub is_proc_macro: Option<bool>,
|
pub is_proc_macro: Option<bool>,
|
||||||
}
|
pub metadata_loader: &'a MetadataLoader,
|
||||||
|
|
||||||
pub struct ArchiveMetadata {
|
|
||||||
_archive: ArchiveRO,
|
|
||||||
// points into self._archive
|
|
||||||
data: *const [u8],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CratePaths {
|
pub struct CratePaths {
|
||||||
@ -287,8 +278,6 @@ pub struct CratePaths {
|
|||||||
pub rmeta: Option<PathBuf>,
|
pub rmeta: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const METADATA_FILENAME: &'static str = "rust.metadata.bin";
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
enum CrateFlavor {
|
enum CrateFlavor {
|
||||||
Rlib,
|
Rlib,
|
||||||
@ -596,20 +585,21 @@ fn extract_one(&mut self,
|
|||||||
let mut err: Option<DiagnosticBuilder> = None;
|
let mut err: Option<DiagnosticBuilder> = None;
|
||||||
for (lib, kind) in m {
|
for (lib, kind) in m {
|
||||||
info!("{} reading metadata from: {}", flavor, lib.display());
|
info!("{} reading metadata from: {}", flavor, lib.display());
|
||||||
let (hash, metadata) = match get_metadata_section(self.target, flavor, &lib) {
|
let (hash, metadata) =
|
||||||
Ok(blob) => {
|
match get_metadata_section(self.target, flavor, &lib, self.metadata_loader) {
|
||||||
if let Some(h) = self.crate_matches(&blob, &lib) {
|
Ok(blob) => {
|
||||||
(h, blob)
|
if let Some(h) = self.crate_matches(&blob, &lib) {
|
||||||
} else {
|
(h, blob)
|
||||||
info!("metadata mismatch");
|
} else {
|
||||||
|
info!("metadata mismatch");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
info!("no metadata found: {}", err);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
Err(err) => {
|
|
||||||
info!("no metadata found: {}", err);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// If we see multiple hashes, emit an error about duplicate candidates.
|
// If we see multiple hashes, emit an error about duplicate candidates.
|
||||||
if slot.as_ref().map_or(false, |s| s.0 != hash) {
|
if slot.as_ref().map_or(false, |s| s.0 != hash) {
|
||||||
let mut e = struct_span_err!(self.sess,
|
let mut e = struct_span_err!(self.sess,
|
||||||
@ -833,50 +823,14 @@ pub fn note_crate_name(err: &mut DiagnosticBuilder, name: &str) {
|
|||||||
err.note(&format!("crate name: {}", name));
|
err.note(&format!("crate name: {}", name));
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ArchiveMetadata {
|
|
||||||
fn new(ar: ArchiveRO) -> Option<ArchiveMetadata> {
|
|
||||||
let data = {
|
|
||||||
let section = ar.iter()
|
|
||||||
.filter_map(|s| s.ok())
|
|
||||||
.find(|sect| sect.name() == Some(METADATA_FILENAME));
|
|
||||||
match section {
|
|
||||||
Some(s) => s.data() as *const [u8],
|
|
||||||
None => {
|
|
||||||
debug!("didn't find '{}' in the archive", METADATA_FILENAME);
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(ArchiveMetadata {
|
|
||||||
_archive: ar,
|
|
||||||
data: data,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_slice<'a>(&'a self) -> &'a [u8] {
|
|
||||||
unsafe { &*self.data }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn verify_decompressed_encoding_version(blob: &MetadataBlob,
|
|
||||||
filename: &Path)
|
|
||||||
-> Result<(), String> {
|
|
||||||
if !blob.is_compatible() {
|
|
||||||
Err((format!("incompatible metadata version found: '{}'",
|
|
||||||
filename.display())))
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just a small wrapper to time how long reading metadata takes.
|
// Just a small wrapper to time how long reading metadata takes.
|
||||||
fn get_metadata_section(target: &Target,
|
fn get_metadata_section(target: &Target,
|
||||||
flavor: CrateFlavor,
|
flavor: CrateFlavor,
|
||||||
filename: &Path)
|
filename: &Path,
|
||||||
|
loader: &MetadataLoader)
|
||||||
-> Result<MetadataBlob, String> {
|
-> Result<MetadataBlob, String> {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let ret = get_metadata_section_imp(target, flavor, filename);
|
let ret = get_metadata_section_imp(target, flavor, filename, loader);
|
||||||
info!("reading {:?} => {:?}",
|
info!("reading {:?} => {:?}",
|
||||||
filename.file_name().unwrap(),
|
filename.file_name().unwrap(),
|
||||||
start.elapsed());
|
start.elapsed());
|
||||||
@ -885,118 +839,61 @@ fn get_metadata_section(target: &Target,
|
|||||||
|
|
||||||
fn get_metadata_section_imp(target: &Target,
|
fn get_metadata_section_imp(target: &Target,
|
||||||
flavor: CrateFlavor,
|
flavor: CrateFlavor,
|
||||||
filename: &Path)
|
filename: &Path,
|
||||||
|
loader: &MetadataLoader)
|
||||||
-> Result<MetadataBlob, String> {
|
-> Result<MetadataBlob, String> {
|
||||||
if !filename.exists() {
|
if !filename.exists() {
|
||||||
return Err(format!("no such file: '{}'", filename.display()));
|
return Err(format!("no such file: '{}'", filename.display()));
|
||||||
}
|
}
|
||||||
if flavor == CrateFlavor::Rlib {
|
let raw_bytes: ErasedBoxRef<[u8]> = match flavor {
|
||||||
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
|
CrateFlavor::Rlib => loader.get_rlib_metadata(target, filename)?,
|
||||||
// internally to read the file. We also avoid even using a memcpy by
|
CrateFlavor::Dylib => {
|
||||||
// just keeping the archive along while the metadata is in use.
|
let buf = loader.get_dylib_metadata(target, filename)?;
|
||||||
let archive = match ArchiveRO::open(filename) {
|
// The header is uncompressed
|
||||||
Some(ar) => ar,
|
let header_len = METADATA_HEADER.len();
|
||||||
None => {
|
debug!("checking {} bytes of metadata-version stamp", header_len);
|
||||||
debug!("llvm didn't like `{}`", filename.display());
|
let header = &buf[..cmp::min(header_len, buf.len())];
|
||||||
return Err(format!("failed to read rlib metadata: '{}'", filename.display()));
|
if header != METADATA_HEADER {
|
||||||
|
return Err(format!("incompatible metadata version found: '{}'",
|
||||||
|
filename.display()));
|
||||||
}
|
}
|
||||||
};
|
|
||||||
return match ArchiveMetadata::new(archive).map(|ar| MetadataBlob::Archive(ar)) {
|
|
||||||
None => Err(format!("failed to read rlib metadata: '{}'", filename.display())),
|
|
||||||
Some(blob) => {
|
|
||||||
verify_decompressed_encoding_version(&blob, filename)?;
|
|
||||||
Ok(blob)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else if flavor == CrateFlavor::Rmeta {
|
|
||||||
let mut file = File::open(filename).map_err(|_|
|
|
||||||
format!("could not open file: '{}'", filename.display()))?;
|
|
||||||
let mut buf = vec![];
|
|
||||||
file.read_to_end(&mut buf).map_err(|_|
|
|
||||||
format!("failed to read rlib metadata: '{}'", filename.display()))?;
|
|
||||||
let blob = MetadataBlob::Raw(buf);
|
|
||||||
verify_decompressed_encoding_version(&blob, filename)?;
|
|
||||||
return Ok(blob);
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
let buf = common::path2cstr(filename);
|
|
||||||
let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
|
|
||||||
if mb as isize == 0 {
|
|
||||||
return Err(format!("error reading library: '{}'", filename.display()));
|
|
||||||
}
|
|
||||||
let of = match ObjectFile::new(mb) {
|
|
||||||
Some(of) => of,
|
|
||||||
_ => {
|
|
||||||
return Err((format!("provided path not an object file: '{}'", filename.display())))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let si = mk_section_iter(of.llof);
|
|
||||||
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
|
|
||||||
let mut name_buf = ptr::null();
|
|
||||||
let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf);
|
|
||||||
let name = slice::from_raw_parts(name_buf as *const u8, name_len as usize).to_vec();
|
|
||||||
let name = String::from_utf8(name).unwrap();
|
|
||||||
debug!("get_metadata_section: name {}", name);
|
|
||||||
if read_meta_section_name(target) == name {
|
|
||||||
let cbuf = llvm::LLVMGetSectionContents(si.llsi);
|
|
||||||
let csz = llvm::LLVMGetSectionSize(si.llsi) as usize;
|
|
||||||
let cvbuf: *const u8 = cbuf as *const u8;
|
|
||||||
let vlen = METADATA_HEADER.len();
|
|
||||||
debug!("checking {} bytes of metadata-version stamp", vlen);
|
|
||||||
let minsz = cmp::min(vlen, csz);
|
|
||||||
let buf0 = slice::from_raw_parts(cvbuf, minsz);
|
|
||||||
let version_ok = buf0 == METADATA_HEADER;
|
|
||||||
if !version_ok {
|
|
||||||
return Err((format!("incompatible metadata version found: '{}'",
|
|
||||||
filename.display())));
|
|
||||||
}
|
|
||||||
|
|
||||||
let cvbuf1 = cvbuf.offset(vlen as isize);
|
// Header is okay -> inflate the actual metadata
|
||||||
debug!("inflating {} bytes of compressed metadata", csz - vlen);
|
let compressed_bytes = &buf[header_len..];
|
||||||
let bytes = slice::from_raw_parts(cvbuf1, csz - vlen);
|
debug!("inflating {} bytes of compressed metadata", compressed_bytes.len());
|
||||||
match flate::inflate_bytes(bytes) {
|
match flate::inflate_bytes(compressed_bytes) {
|
||||||
Ok(inflated) => {
|
Ok(inflated) => {
|
||||||
let blob = MetadataBlob::Inflated(inflated);
|
let buf = unsafe { OwningRef::new_assert_stable_address(inflated) };
|
||||||
verify_decompressed_encoding_version(&blob, filename)?;
|
buf.map_owner_box().erase_owner()
|
||||||
return Ok(blob);
|
}
|
||||||
}
|
Err(_) => {
|
||||||
Err(_) => {}
|
return Err(format!("failed to decompress metadata: {}", filename.display()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
llvm::LLVMMoveToNextSection(si.llsi);
|
|
||||||
}
|
}
|
||||||
Err(format!("metadata not found: '{}'", filename.display()))
|
CrateFlavor::Rmeta => {
|
||||||
}
|
let mut file = File::open(filename).map_err(|_|
|
||||||
}
|
format!("could not open file: '{}'", filename.display()))?;
|
||||||
|
let mut buf = vec![];
|
||||||
pub fn meta_section_name(target: &Target) -> &'static str {
|
file.read_to_end(&mut buf).map_err(|_|
|
||||||
// Historical note:
|
format!("failed to read rmeta metadata: '{}'", filename.display()))?;
|
||||||
//
|
OwningRef::new(buf).map_owner_box().erase_owner()
|
||||||
// When using link.exe it was seen that the section name `.note.rustc`
|
}
|
||||||
// was getting shortened to `.note.ru`, and according to the PE and COFF
|
};
|
||||||
// specification:
|
let blob = MetadataBlob(raw_bytes);
|
||||||
//
|
if blob.is_compatible() {
|
||||||
// > Executable images do not use a string table and do not support
|
Ok(blob)
|
||||||
// > section names longer than 8 characters
|
|
||||||
//
|
|
||||||
// https://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx
|
|
||||||
//
|
|
||||||
// As a result, we choose a slightly shorter name! As to why
|
|
||||||
// `.note.rustc` works on MinGW, that's another good question...
|
|
||||||
|
|
||||||
if target.options.is_like_osx {
|
|
||||||
"__DATA,.rustc"
|
|
||||||
} else {
|
} else {
|
||||||
".rustc"
|
Err(format!("incompatible metadata version found: '{}'", filename.display()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_meta_section_name(_target: &Target) -> &'static str {
|
|
||||||
".rustc"
|
|
||||||
}
|
|
||||||
|
|
||||||
// A diagnostic function for dumping crate metadata to an output stream
|
// A diagnostic function for dumping crate metadata to an output stream
|
||||||
pub fn list_file_metadata(target: &Target, path: &Path, out: &mut io::Write) -> io::Result<()> {
|
pub fn list_file_metadata(target: &Target,
|
||||||
|
path: &Path,
|
||||||
|
loader: &MetadataLoader,
|
||||||
|
out: &mut io::Write)
|
||||||
|
-> io::Result<()> {
|
||||||
let filename = path.file_name().unwrap().to_str().unwrap();
|
let filename = path.file_name().unwrap().to_str().unwrap();
|
||||||
let flavor = if filename.ends_with(".rlib") {
|
let flavor = if filename.ends_with(".rlib") {
|
||||||
CrateFlavor::Rlib
|
CrateFlavor::Rlib
|
||||||
@ -1005,7 +902,7 @@ pub fn list_file_metadata(target: &Target, path: &Path, out: &mut io::Write) ->
|
|||||||
} else {
|
} else {
|
||||||
CrateFlavor::Dylib
|
CrateFlavor::Dylib
|
||||||
};
|
};
|
||||||
match get_metadata_section(target, flavor, path) {
|
match get_metadata_section(target, flavor, path, loader) {
|
||||||
Ok(metadata) => metadata.list_crate_metadata(out),
|
Ok(metadata) => metadata.list_crate_metadata(out),
|
||||||
Err(msg) => write!(out, "{}\n", msg),
|
Err(msg) => write!(out, "{}\n", msg),
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ test = false
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
flate = { path = "../libflate" }
|
flate = { path = "../libflate" }
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
owning_ref = "0.3.3"
|
||||||
rustc = { path = "../librustc" }
|
rustc = { path = "../librustc" }
|
||||||
rustc_back = { path = "../librustc_back" }
|
rustc_back = { path = "../librustc_back" }
|
||||||
rustc_bitflags = { path = "../librustc_bitflags" }
|
rustc_bitflags = { path = "../librustc_bitflags" }
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
use libc;
|
use libc;
|
||||||
use llvm::archive_ro::{ArchiveRO, Child};
|
use llvm::archive_ro::{ArchiveRO, Child};
|
||||||
use llvm::{self, ArchiveKind};
|
use llvm::{self, ArchiveKind};
|
||||||
|
use metadata::METADATA_FILENAME;
|
||||||
use rustc::session::Session;
|
use rustc::session::Session;
|
||||||
|
|
||||||
pub struct ArchiveConfig<'a> {
|
pub struct ArchiveConfig<'a> {
|
||||||
@ -158,11 +159,9 @@ pub fn add_rlib(&mut self,
|
|||||||
// Ignoring all bytecode files, no matter of
|
// Ignoring all bytecode files, no matter of
|
||||||
// name
|
// name
|
||||||
let bc_ext = ".bytecode.deflate";
|
let bc_ext = ".bytecode.deflate";
|
||||||
let metadata_filename =
|
|
||||||
self.config.sess.cstore.metadata_filename().to_owned();
|
|
||||||
|
|
||||||
self.add_archive(rlib, move |fname: &str| {
|
self.add_archive(rlib, move |fname: &str| {
|
||||||
if fname.ends_with(bc_ext) || fname == metadata_filename {
|
if fname.ends_with(bc_ext) || fname == METADATA_FILENAME {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
use super::rpath::RPathConfig;
|
use super::rpath::RPathConfig;
|
||||||
use super::rpath;
|
use super::rpath;
|
||||||
use super::msvc;
|
use super::msvc;
|
||||||
|
use metadata::METADATA_FILENAME;
|
||||||
use session::config;
|
use session::config;
|
||||||
use session::config::NoDebugInfo;
|
use session::config::NoDebugInfo;
|
||||||
use session::config::{OutputFilenames, Input, OutputType};
|
use session::config::{OutputFilenames, Input, OutputType};
|
||||||
@ -521,7 +522,7 @@ fn link_rlib<'a>(sess: &'a Session,
|
|||||||
// contain the metadata in a separate file. We use a temp directory
|
// contain the metadata in a separate file. We use a temp directory
|
||||||
// here so concurrent builds in the same directory don't try to use
|
// here so concurrent builds in the same directory don't try to use
|
||||||
// the same filename for metadata (stomping over one another)
|
// the same filename for metadata (stomping over one another)
|
||||||
let metadata = tmpdir.join(sess.cstore.metadata_filename());
|
let metadata = tmpdir.join(METADATA_FILENAME);
|
||||||
emit_metadata(sess, trans, &metadata);
|
emit_metadata(sess, trans, &metadata);
|
||||||
ab.add_file(&metadata);
|
ab.add_file(&metadata);
|
||||||
|
|
||||||
@ -1141,8 +1142,7 @@ fn link_sanitizer_runtime(cmd: &mut Linker,
|
|||||||
archive.update_symbols();
|
archive.update_symbols();
|
||||||
|
|
||||||
for f in archive.src_files() {
|
for f in archive.src_files() {
|
||||||
if f.ends_with("bytecode.deflate") ||
|
if f.ends_with("bytecode.deflate") || f == METADATA_FILENAME {
|
||||||
f == sess.cstore.metadata_filename() {
|
|
||||||
archive.remove_file(&f);
|
archive.remove_file(&f);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -1217,8 +1217,7 @@ fn add_static_crate(cmd: &mut Linker,
|
|||||||
|
|
||||||
let mut any_objects = false;
|
let mut any_objects = false;
|
||||||
for f in archive.src_files() {
|
for f in archive.src_files() {
|
||||||
if f.ends_with("bytecode.deflate") ||
|
if f.ends_with("bytecode.deflate") || f == METADATA_FILENAME {
|
||||||
f == sess.cstore.metadata_filename() {
|
|
||||||
archive.remove_file(&f);
|
archive.remove_file(&f);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
use back::symbol_export::{self, ExportedSymbols};
|
use back::symbol_export::{self, ExportedSymbols};
|
||||||
use llvm::{ContextRef, Linkage, ModuleRef, ValueRef, Vector, get_param};
|
use llvm::{ContextRef, Linkage, ModuleRef, ValueRef, Vector, get_param};
|
||||||
use llvm;
|
use llvm;
|
||||||
|
use metadata;
|
||||||
use rustc::hir::def_id::LOCAL_CRATE;
|
use rustc::hir::def_id::LOCAL_CRATE;
|
||||||
use middle::lang_items::StartFnLangItem;
|
use middle::lang_items::StartFnLangItem;
|
||||||
use middle::cstore::EncodedMetadata;
|
use middle::cstore::EncodedMetadata;
|
||||||
@ -778,8 +779,7 @@ enum MetadataKind {
|
|||||||
};
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||||
let section_name =
|
let section_name = metadata::metadata_section_name(&tcx.sess.target.target);
|
||||||
tcx.sess.cstore.metadata_section_name(&tcx.sess.target.target);
|
|
||||||
let name = CString::new(section_name).unwrap();
|
let name = CString::new(section_name).unwrap();
|
||||||
llvm::LLVMSetSection(llglobal, name.as_ptr());
|
llvm::LLVMSetSection(llglobal, name.as_ptr());
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
|
|
||||||
extern crate flate;
|
extern crate flate;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
extern crate owning_ref;
|
||||||
#[macro_use] extern crate rustc;
|
#[macro_use] extern crate rustc;
|
||||||
extern crate rustc_back;
|
extern crate rustc_back;
|
||||||
extern crate rustc_data_structures;
|
extern crate rustc_data_structures;
|
||||||
@ -70,6 +71,9 @@
|
|||||||
pub use base::trans_crate;
|
pub use base::trans_crate;
|
||||||
pub use back::symbol_names::provide;
|
pub use back::symbol_names::provide;
|
||||||
|
|
||||||
|
pub use metadata::LlvmMetadataLoader;
|
||||||
|
pub use llvm_util::{init, target_features, print_version, print_passes, print, enable_llvm_debug};
|
||||||
|
|
||||||
pub mod back {
|
pub mod back {
|
||||||
pub use rustc::hir::svh;
|
pub use rustc::hir::svh;
|
||||||
|
|
||||||
@ -119,7 +123,9 @@ pub mod back {
|
|||||||
mod declare;
|
mod declare;
|
||||||
mod glue;
|
mod glue;
|
||||||
mod intrinsic;
|
mod intrinsic;
|
||||||
|
mod llvm_util;
|
||||||
mod machine;
|
mod machine;
|
||||||
|
mod metadata;
|
||||||
mod meth;
|
mod meth;
|
||||||
mod mir;
|
mod mir;
|
||||||
mod monomorphize;
|
mod monomorphize;
|
||||||
|
127
src/librustc_trans/llvm_util.rs
Normal file
127
src/librustc_trans/llvm_util.rs
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
use syntax_pos::symbol::Symbol;
|
||||||
|
use back::write::create_target_machine;
|
||||||
|
use llvm;
|
||||||
|
use rustc::session::Session;
|
||||||
|
use rustc::session::config::PrintRequest;
|
||||||
|
use libc::{c_int, c_char};
|
||||||
|
use std::ffi::CString;
|
||||||
|
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::Once;
|
||||||
|
|
||||||
|
pub fn init(sess: &Session) {
|
||||||
|
unsafe {
|
||||||
|
// Before we touch LLVM, make sure that multithreading is enabled.
|
||||||
|
static POISONED: AtomicBool = AtomicBool::new(false);
|
||||||
|
static INIT: Once = Once::new();
|
||||||
|
INIT.call_once(|| {
|
||||||
|
if llvm::LLVMStartMultithreaded() != 1 {
|
||||||
|
// use an extra bool to make sure that all future usage of LLVM
|
||||||
|
// cannot proceed despite the Once not running more than once.
|
||||||
|
POISONED.store(true, Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_llvm(sess);
|
||||||
|
});
|
||||||
|
|
||||||
|
if POISONED.load(Ordering::SeqCst) {
|
||||||
|
bug!("couldn't enable multi-threaded LLVM");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn configure_llvm(sess: &Session) {
|
||||||
|
let mut llvm_c_strs = Vec::new();
|
||||||
|
let mut llvm_args = Vec::new();
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut add = |arg: &str| {
|
||||||
|
let s = CString::new(arg).unwrap();
|
||||||
|
llvm_args.push(s.as_ptr());
|
||||||
|
llvm_c_strs.push(s);
|
||||||
|
};
|
||||||
|
add("rustc"); // fake program name
|
||||||
|
if sess.time_llvm_passes() { add("-time-passes"); }
|
||||||
|
if sess.print_llvm_passes() { add("-debug-pass=Structure"); }
|
||||||
|
|
||||||
|
for arg in &sess.opts.cg.llvm_args {
|
||||||
|
add(&(*arg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::LLVMInitializePasses();
|
||||||
|
|
||||||
|
llvm::initialize_available_targets();
|
||||||
|
|
||||||
|
llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int,
|
||||||
|
llvm_args.as_ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARNING: the features must be known to LLVM or the feature
|
||||||
|
// detection code will walk past the end of the feature array,
|
||||||
|
// leading to crashes.
|
||||||
|
|
||||||
|
const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "vfp2\0", "vfp3\0", "vfp4\0"];
|
||||||
|
|
||||||
|
const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bmi2\0", "sse\0",
|
||||||
|
"sse2\0", "sse3\0", "sse4.1\0", "sse4.2\0",
|
||||||
|
"ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0",
|
||||||
|
"sse4a\0", "rdrnd\0", "rdseed\0", "fma\0"];
|
||||||
|
|
||||||
|
const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"];
|
||||||
|
|
||||||
|
pub fn target_features(sess: &Session) -> Vec<Symbol> {
|
||||||
|
let target_machine = create_target_machine(sess);
|
||||||
|
|
||||||
|
let whitelist = match &*sess.target.target.arch {
|
||||||
|
"arm" => ARM_WHITELIST,
|
||||||
|
"x86" | "x86_64" => X86_WHITELIST,
|
||||||
|
"hexagon" => HEXAGON_WHITELIST,
|
||||||
|
_ => &[],
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut features = Vec::new();
|
||||||
|
for feat in whitelist {
|
||||||
|
assert_eq!(feat.chars().last(), Some('\0'));
|
||||||
|
if unsafe { llvm::LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } {
|
||||||
|
features.push(Symbol::intern(&feat[..feat.len() - 1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
features
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_version() {
|
||||||
|
unsafe {
|
||||||
|
println!("LLVM version: {}.{}",
|
||||||
|
llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_passes() {
|
||||||
|
unsafe { llvm::LLVMRustPrintPasses(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print(req: PrintRequest, sess: &Session) {
|
||||||
|
let tm = create_target_machine(sess);
|
||||||
|
unsafe {
|
||||||
|
match req {
|
||||||
|
PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm),
|
||||||
|
PrintRequest::TargetFeatures => llvm::LLVMRustPrintTargetFeatures(tm),
|
||||||
|
_ => bug!("rustc_trans can't handle print request: {:?}", req),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enable_llvm_debug() {
|
||||||
|
unsafe { llvm::LLVMRustSetDebug(1); }
|
||||||
|
}
|
122
src/librustc_trans/metadata.rs
Normal file
122
src/librustc_trans/metadata.rs
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
use rustc::util::common;
|
||||||
|
use rustc::middle::cstore::MetadataLoader;
|
||||||
|
use rustc_back::target::Target;
|
||||||
|
use llvm;
|
||||||
|
use llvm::{False, ObjectFile, mk_section_iter};
|
||||||
|
use llvm::archive_ro::ArchiveRO;
|
||||||
|
|
||||||
|
use owning_ref::{ErasedBoxRef, OwningRef};
|
||||||
|
use std::path::Path;
|
||||||
|
use std::ptr;
|
||||||
|
use std::slice;
|
||||||
|
|
||||||
|
pub const METADATA_FILENAME: &str = "rust.metadata.bin";
|
||||||
|
|
||||||
|
pub struct LlvmMetadataLoader;
|
||||||
|
|
||||||
|
impl MetadataLoader for LlvmMetadataLoader {
|
||||||
|
fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<ErasedBoxRef<[u8]>, String> {
|
||||||
|
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
|
||||||
|
// internally to read the file. We also avoid even using a memcpy by
|
||||||
|
// just keeping the archive along while the metadata is in use.
|
||||||
|
let archive = ArchiveRO::open(filename)
|
||||||
|
.map(|ar| OwningRef::new(box ar))
|
||||||
|
.ok_or_else(|| {
|
||||||
|
debug!("llvm didn't like `{}`", filename.display());
|
||||||
|
format!("failed to read rlib metadata: '{}'", filename.display())
|
||||||
|
})?;
|
||||||
|
let buf: OwningRef<_, [u8]> = archive
|
||||||
|
.try_map(|ar| {
|
||||||
|
ar.iter()
|
||||||
|
.filter_map(|s| s.ok())
|
||||||
|
.find(|sect| sect.name() == Some(METADATA_FILENAME))
|
||||||
|
.map(|s| s.data())
|
||||||
|
.ok_or_else(|| {
|
||||||
|
debug!("didn't find '{}' in the archive", METADATA_FILENAME);
|
||||||
|
format!("failed to read rlib metadata: '{}'",
|
||||||
|
filename.display())
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
Ok(buf.erase_owner())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_dylib_metadata(&self,
|
||||||
|
target: &Target,
|
||||||
|
filename: &Path)
|
||||||
|
-> Result<ErasedBoxRef<[u8]>, String> {
|
||||||
|
unsafe {
|
||||||
|
let buf = common::path2cstr(filename);
|
||||||
|
let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
|
||||||
|
if mb as isize == 0 {
|
||||||
|
return Err(format!("error reading library: '{}'", filename.display()));
|
||||||
|
}
|
||||||
|
let of = ObjectFile::new(mb)
|
||||||
|
.map(|of| OwningRef::new(box of))
|
||||||
|
.ok_or_else(|| format!("provided path not an object file: '{}'",
|
||||||
|
filename.display()))?;
|
||||||
|
let buf = of.try_map(|of| search_meta_section(of, target, filename))?;
|
||||||
|
Ok(buf.erase_owner())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn search_meta_section<'a>(of: &'a ObjectFile,
|
||||||
|
target: &Target,
|
||||||
|
filename: &Path)
|
||||||
|
-> Result<&'a [u8], String> {
|
||||||
|
unsafe {
|
||||||
|
let si = mk_section_iter(of.llof);
|
||||||
|
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
|
||||||
|
let mut name_buf = ptr::null();
|
||||||
|
let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf);
|
||||||
|
let name = slice::from_raw_parts(name_buf as *const u8, name_len as usize).to_vec();
|
||||||
|
let name = String::from_utf8(name).unwrap();
|
||||||
|
debug!("get_metadata_section: name {}", name);
|
||||||
|
if read_metadata_section_name(target) == name {
|
||||||
|
let cbuf = llvm::LLVMGetSectionContents(si.llsi);
|
||||||
|
let csz = llvm::LLVMGetSectionSize(si.llsi) as usize;
|
||||||
|
// The buffer is valid while the object file is around
|
||||||
|
let buf: &'a [u8] = slice::from_raw_parts(cbuf as *const u8, csz);
|
||||||
|
return Ok(buf);
|
||||||
|
}
|
||||||
|
llvm::LLVMMoveToNextSection(si.llsi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(format!("metadata not found: '{}'", filename.display()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn metadata_section_name(target: &Target) -> &'static str {
|
||||||
|
// Historical note:
|
||||||
|
//
|
||||||
|
// When using link.exe it was seen that the section name `.note.rustc`
|
||||||
|
// was getting shortened to `.note.ru`, and according to the PE and COFF
|
||||||
|
// specification:
|
||||||
|
//
|
||||||
|
// > Executable images do not use a string table and do not support
|
||||||
|
// > section names longer than 8 characters
|
||||||
|
//
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx
|
||||||
|
//
|
||||||
|
// As a result, we choose a slightly shorter name! As to why
|
||||||
|
// `.note.rustc` works on MinGW, that's another good question...
|
||||||
|
|
||||||
|
if target.options.is_like_osx {
|
||||||
|
"__DATA,.rustc"
|
||||||
|
} else {
|
||||||
|
".rustc"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_metadata_section_name(_target: &Target) -> &'static str {
|
||||||
|
".rustc"
|
||||||
|
}
|
@ -19,6 +19,7 @@
|
|||||||
use rustc::hir::map as hir_map;
|
use rustc::hir::map as hir_map;
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
use rustc::util::nodemap::FxHashMap;
|
use rustc::util::nodemap::FxHashMap;
|
||||||
|
use rustc_trans;
|
||||||
use rustc_trans::back::link;
|
use rustc_trans::back::link;
|
||||||
use rustc_resolve as resolve;
|
use rustc_resolve as resolve;
|
||||||
use rustc_metadata::cstore::CStore;
|
use rustc_metadata::cstore::CStore;
|
||||||
@ -138,10 +139,11 @@ pub fn run_core(search_paths: SearchPaths,
|
|||||||
|
|
||||||
let dep_graph = DepGraph::new(false);
|
let dep_graph = DepGraph::new(false);
|
||||||
let _ignore = dep_graph.in_ignore();
|
let _ignore = dep_graph.in_ignore();
|
||||||
let cstore = Rc::new(CStore::new(&dep_graph));
|
let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
|
||||||
let mut sess = session::build_session_(
|
let mut sess = session::build_session_(
|
||||||
sessopts, &dep_graph, cpath, diagnostic_handler, codemap, cstore.clone()
|
sessopts, &dep_graph, cpath, diagnostic_handler, codemap, cstore.clone()
|
||||||
);
|
);
|
||||||
|
rustc_trans::init(&sess);
|
||||||
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
||||||
|
|
||||||
let mut cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs));
|
let mut cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs));
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
use rustc_driver::driver::phase_2_configure_and_expand;
|
use rustc_driver::driver::phase_2_configure_and_expand;
|
||||||
use rustc_metadata::cstore::CStore;
|
use rustc_metadata::cstore::CStore;
|
||||||
use rustc_resolve::MakeGlobMap;
|
use rustc_resolve::MakeGlobMap;
|
||||||
|
use rustc_trans;
|
||||||
use rustc_trans::back::link;
|
use rustc_trans::back::link;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap::CodeMap;
|
use syntax::codemap::CodeMap;
|
||||||
@ -81,10 +82,11 @@ pub fn run(input: &str,
|
|||||||
|
|
||||||
let dep_graph = DepGraph::new(false);
|
let dep_graph = DepGraph::new(false);
|
||||||
let _ignore = dep_graph.in_ignore();
|
let _ignore = dep_graph.in_ignore();
|
||||||
let cstore = Rc::new(CStore::new(&dep_graph));
|
let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
|
||||||
let mut sess = session::build_session_(
|
let mut sess = session::build_session_(
|
||||||
sessopts, &dep_graph, Some(input_path.clone()), handler, codemap.clone(), cstore.clone(),
|
sessopts, &dep_graph, Some(input_path.clone()), handler, codemap.clone(), cstore.clone(),
|
||||||
);
|
);
|
||||||
|
rustc_trans::init(&sess);
|
||||||
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
||||||
sess.parse_sess.config =
|
sess.parse_sess.config =
|
||||||
config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone()));
|
config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone()));
|
||||||
@ -229,10 +231,11 @@ fn drop(&mut self) {
|
|||||||
let diagnostic_handler = errors::Handler::with_emitter(true, false, box emitter);
|
let diagnostic_handler = errors::Handler::with_emitter(true, false, box emitter);
|
||||||
|
|
||||||
let dep_graph = DepGraph::new(false);
|
let dep_graph = DepGraph::new(false);
|
||||||
let cstore = Rc::new(CStore::new(&dep_graph));
|
let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
|
||||||
let mut sess = session::build_session_(
|
let mut sess = session::build_session_(
|
||||||
sessopts, &dep_graph, None, diagnostic_handler, codemap, cstore.clone(),
|
sessopts, &dep_graph, None, diagnostic_handler, codemap, cstore.clone(),
|
||||||
);
|
);
|
||||||
|
rustc_trans::init(&sess);
|
||||||
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
||||||
|
|
||||||
let outdir = Mutex::new(TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir"));
|
let outdir = Mutex::new(TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir"));
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
extern crate rustc_lint;
|
extern crate rustc_lint;
|
||||||
extern crate rustc_metadata;
|
extern crate rustc_metadata;
|
||||||
extern crate rustc_errors;
|
extern crate rustc_errors;
|
||||||
|
extern crate rustc_trans;
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
|
|
||||||
use rustc::dep_graph::DepGraph;
|
use rustc::dep_graph::DepGraph;
|
||||||
@ -58,8 +59,9 @@ fn basic_sess(sysroot: PathBuf) -> (Session, Rc<CStore>) {
|
|||||||
|
|
||||||
let descriptions = Registry::new(&rustc::DIAGNOSTICS);
|
let descriptions = Registry::new(&rustc::DIAGNOSTICS);
|
||||||
let dep_graph = DepGraph::new(opts.build_dep_graph());
|
let dep_graph = DepGraph::new(opts.build_dep_graph());
|
||||||
let cstore = Rc::new(CStore::new(&dep_graph));
|
let cstore = Rc::new(CStore::new(&dep_graph, Box::new(rustc_trans::LlvmMetadataLoader)));
|
||||||
let sess = build_session(opts, &dep_graph, None, descriptions, cstore.clone());
|
let sess = build_session(opts, &dep_graph, None, descriptions, cstore.clone());
|
||||||
|
rustc_trans::init(&sess);
|
||||||
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
||||||
(sess, cstore)
|
(sess, cstore)
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
extern crate rustc;
|
extern crate rustc;
|
||||||
extern crate rustc_plugin;
|
extern crate rustc_plugin;
|
||||||
|
extern crate rustc_trans;
|
||||||
|
|
||||||
#[link(name = "llvm-function-pass", kind = "static")]
|
#[link(name = "llvm-function-pass", kind = "static")]
|
||||||
#[link(name = "llvm-module-pass", kind = "static")]
|
#[link(name = "llvm-module-pass", kind = "static")]
|
||||||
|
Loading…
Reference in New Issue
Block a user