提交 114be1e9 编写于 作者: B bors 提交者: GitHub

Auto merge of #34315 - Manishearth:rollup, r=Manishearth

Rollup of 4 pull requests

- Successful merges: #34298, #34302, #34307, #34312
- Failed merges:
......@@ -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));
}
......
......@@ -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>>,
}
......@@ -549,7 +549,7 @@ fn cargo(&self,
// 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(" "));
}
......@@ -825,8 +825,8 @@ fn cflags(&self, target: &str) -> Vec<String> {
}
/// 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
......
......@@ -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());
......
......@@ -39,9 +39,11 @@ 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();
......@@ -49,10 +51,10 @@ pub fn cc2ar(cc: &Path, target: &str) -> PathBuf {
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))
}
}
......
......@@ -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())
......
......@@ -94,6 +94,7 @@
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
......@@ -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> {
......@@ -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
}
......@@ -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;
}
......@@ -192,7 +189,7 @@ fn invalidate_cache(&mut self) {
}
}
/// 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.
......@@ -270,7 +267,7 @@ pub fn push_scope(&mut self, extent: CodeExtent, entry: BasicBlock) {
extent: extent,
drops: vec![],
free: None,
cached_block: None,
cached_exits: FnvHashMap()
});
self.scope_auxiliary.push(ScopeAuxiliary {
extent: extent,
......@@ -314,13 +311,25 @@ pub fn exit_scope(&mut self,
.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);
......@@ -331,14 +340,9 @@ pub fn exit_scope(&mut self,
.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 });
}
......@@ -506,10 +510,9 @@ pub fn diverge_cleanup(&mut self) -> Option<BasicBlock> {
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)
}
......@@ -534,7 +537,7 @@ pub fn build_drop(&mut self,
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,
......
......@@ -102,6 +102,8 @@ pub struct EnumData {
pub qualname: String,
pub span: Span,
pub scope: NodeId,
pub variants: Vec<NodeId>,
}
/// Data for extern crates.
......@@ -212,6 +214,7 @@ pub struct MethodData {
pub span: Span,
pub scope: NodeId,
pub value: String,
pub decl_id: Option<DefId>,
}
/// Data for modules.
......@@ -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.
......@@ -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)]
......@@ -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)]
......@@ -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,
......@@ -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)]
......
......@@ -30,7 +30,7 @@
use rustc::hir::def::Def;
use rustc::hir::def_id::DefId;
use rustc::session::Session;
use rustc::ty::{self, TyCtxt};
use rustc::ty::{self, TyCtxt, ImplOrTraitItem, ImplOrTraitItemContainer};
use std::collections::HashSet;
use std::hash::*;
......@@ -356,6 +356,7 @@ fn process_formals(&mut self, formals: &Vec<ast::Arg>, qualname: &str) {
if !self.span.filter_generated(sub_span, p.span) {
self.dumper.variable(VariableData {
id: id,
kind: VariableKind::Local,
span: sub_span.expect("No span found for variable"),
name: path_to_string(p),
qualname: format!("{}::{}", qualname, path_to_string(p)),
......@@ -380,24 +381,42 @@ fn process_method(&mut self,
let sig_str = ::make_signature(&sig.decl, &sig.generics);
if body.is_some() {
if !self.span.filter_generated(Some(method_data.span), span) {
let mut data = method_data.clone();
data.value = sig_str;
self.dumper.function(data.lower(self.tcx));
}
self.process_formals(&sig.decl.inputs, &method_data.qualname);
} else {
if !self.span.filter_generated(Some(method_data.span), span) {
self.dumper.method(MethodData {
id: method_data.id,
name: method_data.name,
span: method_data.span,
scope: method_data.scope,
qualname: method_data.qualname.clone(),
value: sig_str,
}.lower(self.tcx));
}
}
// If the method is defined in an impl, then try and find the corresponding
// method decl in a trait, and if there is one, make a decl_id for it. This
// requires looking up the impl, then the trait, then searching for a method
// with the right name.
if !self.span.filter_generated(Some(method_data.span), span) {
let container =
self.tcx.impl_or_trait_item(self.tcx.map.local_def_id(id)).container();
let decl_id = if let ImplOrTraitItemContainer::ImplContainer(id) = container {
self.tcx.trait_id_of_impl(id).and_then(|id| {
for item in &**self.tcx.trait_items(id) {
if let &ImplOrTraitItem::MethodTraitItem(ref m) = item {
if m.name == name {
return Some(m.def_id);
}
}
}
None
})
} else {
None
};
self.dumper.method(MethodData {
id: method_data.id,
name: method_data.name,
span: method_data.span,
scope: method_data.scope,
qualname: method_data.qualname.clone(),
value: sig_str,
decl_id: decl_id,
}.lower(self.tcx));
}
self.process_generic_params(&sig.generics, span, &method_data.qualname, id);
}
......@@ -519,6 +538,7 @@ fn process_const(&mut self,
if !self.span.filter_generated(sub_span, span) {
self.dumper.variable(VariableData {
span: sub_span.expect("No span found for variable"),
kind: VariableKind::Const,
id: id,
name: name.to_string(),
qualname: qualname,
......@@ -542,17 +562,18 @@ fn process_struct(&mut self,
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Struct);
let val = if let ast::ItemKind::Struct(ast::VariantData::Struct(ref fields, _), _) =
item.node {
let (val, fields) =
if let ast::ItemKind::Struct(ast::VariantData::Struct(ref fields, _), _) = item.node
{
let fields_str = fields.iter()
.enumerate()
.map(|(i, f)| f.ident.map(|i| i.to_string())
.unwrap_or(i.to_string()))
.collect::<Vec<_>>()
.join(", ");
format!("{} {{ {} }}", name, fields_str)
(format!("{} {{ {} }}", name, fields_str), fields.iter().map(|f| f.id).collect())
} else {
String::new()
(String::new(), vec![])
};
if !self.span.filter_generated(sub_span, item.span) {
......@@ -563,7 +584,8 @@ fn process_struct(&mut self,
ctor_id: def.id(),
qualname: qualname.clone(),
scope: self.cur_scope,
value: val
value: val,
fields: fields,
}.lower(self.tcx));
}
......@@ -718,7 +740,8 @@ fn process_trait(&mut self,
name: name,
qualname: qualname.clone(),
scope: self.cur_scope,
value: val
value: val,
items: methods.iter().map(|i| i.id).collect(),
}.lower(self.tcx));
}
......@@ -958,6 +981,7 @@ fn process_var_decl(&mut self, p: &ast::Pat, value: String) {
if !self.span.filter_generated(sub_span, p.span) {
self.dumper.variable(VariableData {
span: sub_span.expect("No span found for variable"),
kind: VariableKind::Local,
id: id,
name: path_to_string(p),
qualname: format!("{}${}", path_to_string(p), id),
......@@ -1366,6 +1390,7 @@ fn visit_arm(&mut self, arm: &ast::Arm) {
if !self.span.filter_generated(Some(p.span), p.span) {
self.dumper.variable(VariableData {
span: p.span,
kind: VariableKind::Local,
id: id,
name: path_to_string(p),
qualname: format!("{}${}", path_to_string(p), id),
......
......@@ -14,7 +14,7 @@
use syntax::ast::{CrateNum, NodeId};
use syntax::codemap::{Span, CodeMap};
use super::data;
use data;
// FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet
pub trait Lower {
......@@ -90,6 +90,7 @@ pub struct EnumData {
pub qualname: String,
pub span: SpanData,
pub scope: DefId,
pub variants: Vec<DefId>
}
impl Lower for data::EnumData {
......@@ -103,6 +104,7 @@ fn lower(self, tcx: TyCtxt) -> EnumData {
qualname: self.qualname,
span: SpanData::from_span(self.span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.map),
variants: self.variants.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(),
}
}
}
......@@ -319,6 +321,7 @@ pub struct MethodData {
pub span: SpanData,
pub scope: DefId,
pub value: String,
pub decl_id: Option<DefId>,
}
impl Lower for data::MethodData {
......@@ -332,6 +335,7 @@ fn lower(self, tcx: TyCtxt) -> MethodData {
id: make_def_id(self.id, &tcx.map),
qualname: self.qualname,
value: self.value,
decl_id: self.decl_id,
}
}
}
......@@ -345,6 +349,7 @@ pub struct ModData {
pub span: SpanData,
pub scope: DefId,
pub filename: String,
pub items: Vec<DefId>,
}
impl Lower for data::ModData {
......@@ -358,6 +363,7 @@ fn lower(self, tcx: TyCtxt) -> ModData {
span: SpanData::from_span(self.span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.map),
filename: self.filename,
items: self.items.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(),
}
}
}
......@@ -392,7 +398,8 @@ pub struct StructData {
pub ctor_id: DefId,
pub qualname: String,
pub scope: DefId,
pub value: String
pub value: String,
pub fields: Vec<DefId>,
}
impl Lower for data::StructData {
......@@ -406,7 +413,8 @@ fn lower(self, tcx: TyCtxt) -> StructData {
ctor_id: make_def_id(self.ctor_id, &tcx.map),
qualname: self.qualname,
scope: make_def_id(self.scope, &tcx.map),
value: self.value
value: self.value,
fields: self.fields.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(),
}
}
}
......@@ -445,7 +453,8 @@ pub struct TraitData {
pub id: DefId,
pub qualname: String,
pub scope: DefId,
pub value: String
pub value: String,
pub items: Vec<DefId>,
}
impl Lower for data::TraitData {
......@@ -459,6 +468,7 @@ fn lower(self, tcx: TyCtxt) -> TraitData {
qualname: self.qualname,
scope: make_def_id(self.scope, &tcx.map),
value: self.value,
items: self.items.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(),
}
}
}
......@@ -585,6 +595,7 @@ fn lower(self, tcx: TyCtxt) -> UseGlobData {
pub struct VariableData {
pub id: DefId,
pub name: String,
pub kind: data::VariableKind,
pub qualname: String,
pub span: SpanData,
pub scope: DefId,
......@@ -598,6 +609,7 @@ impl Lower for data::VariableData {
fn lower(self, tcx: TyCtxt) -> VariableData {
VariableData {
id: make_def_id(self.id, &tcx.map),
kind: self.kind,
name: self.name,
qualname: self.qualname,
span: SpanData::from_span(self.span, tcx.sess.codemap()),
......
......@@ -13,8 +13,9 @@
use rustc::hir::def_id::DefId;
use rustc_serialize::json::as_json;
use super::external_data::*;
use super::dump::Dump;
use external_data::*;
use data::VariableKind;
use dump::Dump;
pub struct JsonDumper<'b, W: Write + 'b> {
output: &'b mut W,
......@@ -180,6 +181,8 @@ struct Def {
name: String,
qualname: String,
value: String,
children: Vec<Id>,
decl_id: Option<Id>,
}
#[derive(Debug, RustcEncodable)]
......@@ -194,14 +197,19 @@ enum DefKind {
Trait,
// value = type + generics
Function,
// value = type + generics
Method,
// No id, no value.
Macro,
// value = file_name
Mod,
// value = aliased type
Type,
// value = type and init expression
Variable,
// value = type and init expression (for all variable kinds).
Local,
Static,
Const,
Field,
}
impl From<EnumData> for Def {
......@@ -213,6 +221,8 @@ fn from(data: EnumData) -> Def {
name: data.name,
qualname: data.qualname,
value: data.value,
children: data.variants.into_iter().map(|id| From::from(id)).collect(),
decl_id: None,
}
}
}
......@@ -226,6 +236,8 @@ fn from(data: TupleVariantData) -> Def {
name: data.name,
qualname: data.qualname,
value: data.value,
children: vec![],
decl_id: None,
}
}
}
......@@ -238,6 +250,8 @@ fn from(data: StructVariantData) -> Def {
name: data.name,
qualname: data.qualname,
value: data.value,
children: vec![],
decl_id: None,
}
}
}
......@@ -250,6 +264,8 @@ fn from(data: StructData) -> Def {
name: data.name,
qualname: data.qualname,
value: data.value,
children: data.fields.into_iter().map(|id| From::from(id)).collect(),
decl_id: None,
}
}
}
......@@ -262,6 +278,8 @@ fn from(data: TraitData) -> Def {
name: data.name,
qualname: data.qualname,
value: data.value,
children: data.items.into_iter().map(|id| From::from(id)).collect(),
decl_id: None,
}
}
}
......@@ -274,18 +292,22 @@ fn from(data: FunctionData) -> Def {
name: data.name,
qualname: data.qualname,
value: data.value,
children: vec![],
decl_id: None,
}
}
}
impl From<MethodData> for Def {
fn from(data: MethodData) -> Def {
Def {
kind: DefKind::Function,
kind: DefKind::Method,
id: From::from(data.id),
span: data.span,
name: data.name,
qualname: data.qualname,
value: data.value,
children: vec![],
decl_id: data.decl_id.map(|id| From::from(id)),
}
}
}
......@@ -298,6 +320,8 @@ fn from(data: MacroData) -> Def {
name: data.name,
qualname: data.qualname,
value: String::new(),
children: vec![],
decl_id: None,
}
}
}
......@@ -310,6 +334,8 @@ fn from(data:ModData) -> Def {
name: data.name,
qualname: data.qualname,
value: data.filename,
children: data.items.into_iter().map(|id| From::from(id)).collect(),
decl_id: None,
}
}
}
......@@ -322,18 +348,27 @@ fn from(data: TypeDefData) -> Def {
name: data.name,
qualname: data.qualname,
value: data.value,
children: vec![],
decl_id: None,
}
}
}
impl From<VariableData> for Def {
fn from(data: VariableData) -> Def {
Def {
kind: DefKind::Variable,
kind: match data.kind {
VariableKind::Static => DefKind::Static,
VariableKind::Const => DefKind::Const,
VariableKind::Local => DefKind::Local,
VariableKind::Field => DefKind::Field,
},
id: From::from(data.id),
span: data.span,
name: data.name,
qualname: data.qualname,
value: data.value,
children: vec![],
decl_id: None,
}
}
}
......
......@@ -153,6 +153,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
filter!(self.span_utils, sub_span, item.span, None);
Some(Data::VariableData(VariableData {
id: item.id,
kind: VariableKind::Static,
name: item.ident.to_string(),
qualname: qualname,
span: sub_span.unwrap(),
......@@ -167,6 +168,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
filter!(self.span_utils, sub_span, item.span, None);
Some(Data::VariableData(VariableData {
id: item.id,
kind: VariableKind::Const,
name: item.ident.to_string(),
qualname: qualname,
span: sub_span.unwrap(),
......@@ -190,6 +192,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
span: sub_span.unwrap(),
scope: self.enclosing_scope(item.id),
filename: filename,
items: m.items.iter().map(|i| i.id).collect(),
}))
}
ast::ItemKind::Enum(ref def, _) => {
......@@ -209,6 +212,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
span: sub_span.unwrap(),
qualname: qualname,
scope: self.enclosing_scope(item.id),
variants: def.variants.iter().map(|v| v.node.data.id()).collect(),
}))
}
ast::ItemKind::Impl(_, _, _, ref trait_ref, ref typ, _) => {
......@@ -266,6 +270,7 @@ pub fn get_field_data(&self, field: &ast::StructField,
filter!(self.span_utils, sub_span, field.span, None);
Some(VariableData {
id: field.id,
kind: VariableKind::Field,
name: ident.to_string(),
qualname: qualname,
span: sub_span.unwrap(),
......
......@@ -80,7 +80,8 @@ fn build_libbacktrace(host: &str, target: &str) {
}
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())
.collect::<Vec<_>>().join(" ");
run(Command::new("sh")
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册