Skip to content
4 changes: 3 additions & 1 deletion src/bootstrap/build/cc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ pub fn find(build: &mut Build) {
let compiler = cfg.get_compiler();
let ar = cc2ar(compiler.path(), target);
build.verbose(&format!("CC_{} = {:?}", target, compiler.path()));
build.verbose(&format!("AR_{} = {:?}", target, ar));
if let Some(ref ar) = ar {
build.verbose(&format!("AR_{} = {:?}", target, ar));
}
build.cc.insert(target.to_string(), (compiler, ar));
}

Expand Down
8 changes: 4 additions & 4 deletions src/bootstrap/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ pub struct Build {
lldb_python_dir: Option<String>,

// Runtime state filled in later on
cc: HashMap<String, (gcc::Tool, PathBuf)>,
cc: HashMap<String, (gcc::Tool, Option<PathBuf>)>,
cxx: HashMap<String, gcc::Tool>,
compiler_rt_built: RefCell<HashMap<String, PathBuf>>,
}
Expand Down Expand Up @@ -549,7 +549,7 @@ impl Build {
// FIXME: the guard against msvc shouldn't need to be here
if !target.contains("msvc") {
cargo.env(format!("CC_{}", target), self.cc(target))
.env(format!("AR_{}", target), self.ar(target))
.env(format!("AR_{}", target), self.ar(target).unwrap()) // only msvc is None
.env(format!("CFLAGS_{}", target), self.cflags(target).join(" "));
}

Expand Down Expand Up @@ -825,8 +825,8 @@ impl Build {
}

/// Returns the path to the `ar` archive utility for the target specified.
fn ar(&self, target: &str) -> &Path {
&self.cc[target].1
fn ar(&self, target: &str) -> Option<&Path> {
self.cc[target].1.as_ref().map(|p| &**p)
}

/// Returns the path to the C++ compiler for the target specified, may panic
Expand Down
4 changes: 3 additions & 1 deletion src/bootstrap/build/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ pub fn check(build: &mut Build) {
// also build some C++ shims for LLVM so we need a C++ compiler.
for target in build.config.target.iter() {
need_cmd(build.cc(target).as_ref());
need_cmd(build.ar(target).as_ref());
if let Some(ar) = build.ar(target) {
need_cmd(ar.as_ref());
}
}
for host in build.config.host.iter() {
need_cmd(build.cxx(host).as_ref());
Expand Down
12 changes: 7 additions & 5 deletions src/build_helper/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,22 @@ pub fn gnu_target(target: &str) -> String {
}
}

pub fn cc2ar(cc: &Path, target: &str) -> PathBuf {
if target.contains("musl") || target.contains("msvc") {
PathBuf::from("ar")
pub fn cc2ar(cc: &Path, target: &str) -> Option<PathBuf> {
if target.contains("msvc") {
None
} else if target.contains("musl") {
Some(PathBuf::from("ar"))
} else {
let parent = cc.parent().unwrap();
let file = cc.file_name().unwrap().to_str().unwrap();
for suffix in &["gcc", "cc", "clang"] {
if let Some(idx) = file.rfind(suffix) {
let mut file = file[..idx].to_owned();
file.push_str("ar");
return parent.join(&file);
return Some(parent.join(&file));
}
}
parent.join(file)
Some(parent.join(file))
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/liballoc_jemalloc/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ fn main() {
}

let compiler = gcc::Config::new().get_compiler();
let ar = build_helper::cc2ar(compiler.path(), &target);
// only msvc returns None for ar so unwrap is okay
let ar = build_helper::cc2ar(compiler.path(), &target).unwrap();
let cflags = compiler.args()
.iter()
.map(|s| s.to_str().unwrap())
Expand Down
57 changes: 30 additions & 27 deletions src/librustc_mir/build/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ use rustc::ty::{Ty, TyCtxt};
use rustc::mir::repr::*;
use syntax::codemap::Span;
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::fnv::FnvHashMap;

pub struct Scope<'tcx> {
/// the scope-id within the scope_auxiliary
Expand Down Expand Up @@ -127,12 +128,8 @@ pub struct Scope<'tcx> {
/// stage.
free: Option<FreeData<'tcx>>,

/// The cached block for the cleanups-on-diverge path. This block
/// contains a block that will just do a RESUME to an appropriate
/// place. This block does not execute any of the drops or free:
/// each of those has their own cached-blocks, which will branch
/// to this point.
cached_block: Option<BasicBlock>
/// The cache for drop chain on “normal” exit into a particular BasicBlock.
cached_exits: FnvHashMap<(BasicBlock, CodeExtent), BasicBlock>,
}

struct DropData<'tcx> {
Expand Down Expand Up @@ -172,7 +169,7 @@ pub struct LoopScope {
pub continue_block: BasicBlock,
/// Block to branch into when the loop terminates (either by being `break`-en out from, or by
/// having its condition to become false)
pub break_block: BasicBlock, // where to go on a `break
pub break_block: BasicBlock,
/// Indicates the reachability of the break_block for this loop
pub might_break: bool
}
Expand All @@ -183,7 +180,7 @@ impl<'tcx> Scope<'tcx> {
/// Should always be run for all inner scopes when a drop is pushed into some scope enclosing a
/// larger extent of code.
fn invalidate_cache(&mut self) {
self.cached_block = None;
self.cached_exits = FnvHashMap();
for dropdata in &mut self.drops {
dropdata.cached_block = None;
}
Expand All @@ -192,7 +189,7 @@ impl<'tcx> Scope<'tcx> {
}
}

/// Returns the cached block for this scope.
/// Returns the cached entrypoint for diverging exit from this scope.
///
/// Precondition: the caches must be fully filled (i.e. diverge_cleanup is called) in order for
/// this method to work correctly.
Expand Down Expand Up @@ -270,7 +267,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
extent: extent,
drops: vec![],
free: None,
cached_block: None,
cached_exits: FnvHashMap()
});
self.scope_auxiliary.push(ScopeAuxiliary {
extent: extent,
Expand Down Expand Up @@ -314,13 +311,25 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
.unwrap_or_else(||{
span_bug!(span, "extent {:?} does not enclose", extent)
});

let len = self.scopes.len();
assert!(scope_count < len, "should not use `exit_scope` to pop ALL scopes");
let tmp = self.get_unit_temp();
for (idx, ref scope) in self.scopes.iter().enumerate().rev().take(scope_count) {
unpack!(block = build_scope_drops(&mut self.cfg,
scope,
&self.scopes[..idx],
block));
{
let mut rest = &mut self.scopes[(len - scope_count)..];
while let Some((scope, rest_)) = {rest}.split_last_mut() {
rest = rest_;
block = if let Some(&e) = scope.cached_exits.get(&(target, extent)) {
self.cfg.terminate(block, scope.source_info(span),
TerminatorKind::Goto { target: e });
return;
} else {
let b = self.cfg.start_new_block();
self.cfg.terminate(block, scope.source_info(span),
TerminatorKind::Goto { target: b });
scope.cached_exits.insert((target, extent), b);
b
};
unpack!(block = build_scope_drops(&mut self.cfg, scope, rest, block));
if let Some(ref free_data) = scope.free {
let next = self.cfg.start_new_block();
let free = build_free(self.hir.tcx(), &tmp, free_data, next);
Expand All @@ -331,14 +340,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
.postdoms
.push(self.cfg.current_location(block));
}

assert!(scope_count < self.scopes.len(),
"should never use `exit_scope` to pop *ALL* scopes");
let scope = self.scopes.iter().rev().skip(scope_count)
.next()
.unwrap();
self.cfg.terminate(block,
scope.source_info(span),
}
let scope = &self.scopes[len - scope_count];
self.cfg.terminate(block, scope.source_info(span),
TerminatorKind::Goto { target: target });
}

Expand Down Expand Up @@ -506,10 +510,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
resumeblk
};

for scope in scopes {
for scope in scopes.iter_mut().filter(|s| !s.drops.is_empty() || s.free.is_some()) {
target = build_diverge_scope(hir.tcx(), cfg, &unit_temp, scope, target);
}

Some(target)
}

Expand All @@ -534,7 +537,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
next_target.unit()
}


/// Utility function for *non*-scope code to build their own drops
pub fn build_drop_and_replace(&mut self,
block: BasicBlock,
span: Span,
Expand Down
19 changes: 17 additions & 2 deletions src/librustc_save_analysis/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ pub struct EnumData {
pub qualname: String,
pub span: Span,
pub scope: NodeId,
pub variants: Vec<NodeId>,

}

/// Data for extern crates.
Expand Down Expand Up @@ -212,6 +214,7 @@ pub struct MethodData {
pub span: Span,
pub scope: NodeId,
pub value: String,
pub decl_id: Option<DefId>,
}

/// Data for modules.
Expand All @@ -223,6 +226,7 @@ pub struct ModData {
pub span: Span,
pub scope: NodeId,
pub filename: String,
pub items: Vec<NodeId>,
}

/// Data for a reference to a module.
Expand All @@ -242,7 +246,8 @@ pub struct StructData {
pub ctor_id: NodeId,
pub qualname: String,
pub scope: NodeId,
pub value: String
pub value: String,
pub fields: Vec<NodeId>,
}

#[derive(Debug, RustcEncodable)]
Expand All @@ -263,7 +268,8 @@ pub struct TraitData {
pub name: String,
pub qualname: String,
pub scope: NodeId,
pub value: String
pub value: String,
pub items: Vec<NodeId>,
}

#[derive(Debug, RustcEncodable)]
Expand Down Expand Up @@ -317,6 +323,7 @@ pub struct UseGlobData {
#[derive(Debug, RustcEncodable)]
pub struct VariableData {
pub id: NodeId,
pub kind: VariableKind,
pub name: String,
pub qualname: String,
pub span: Span,
Expand All @@ -325,6 +332,14 @@ pub struct VariableData {
pub type_value: String,
}

#[derive(Debug, RustcEncodable)]
pub enum VariableKind {
Static,
Const,
Local,
Field,
}

/// Data for the use of some item (e.g., the use of a local variable, which
/// will refer to that variables declaration (by ref_id)).
#[derive(Debug, RustcEncodable)]
Expand Down
Loading