Clean up trans::trans_crate() after making things collector driven.
This commit is contained in:
parent
37a10ecbe8
commit
283c94cd49
|
@ -2198,34 +2198,17 @@ pub fn set_link_section(ccx: &CrateContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
|
fn trans_item(ccx: &CrateContext, item: &hir::Item) {
|
||||||
let _icx = push_ctxt("trans_item");
|
let _icx = push_ctxt("trans_item");
|
||||||
|
|
||||||
let tcx = ccx.tcx();
|
|
||||||
match item.node {
|
match item.node {
|
||||||
hir::ItemFn(_, _, _, _, _, _) => {
|
|
||||||
let def_id = tcx.map.local_def_id(item.id);
|
|
||||||
// check for the #[rustc_error] annotation, which forces an
|
|
||||||
// error in trans. This is used to write compile-fail tests
|
|
||||||
// that actually test that compilation succeeds without
|
|
||||||
// reporting an error.
|
|
||||||
if is_entry_fn(ccx.sess(), item.id) {
|
|
||||||
let empty_substs = ccx.empty_substs_for_def_id(def_id);
|
|
||||||
let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val;
|
|
||||||
create_entry_wrapper(ccx, item.span, llfn);
|
|
||||||
if tcx.has_attr(def_id, "rustc_error") {
|
|
||||||
tcx.sess.span_fatal(item.span, "compilation successful");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function is actually translated in trans_instance
|
|
||||||
}
|
|
||||||
hir::ItemEnum(ref enum_definition, ref gens) => {
|
hir::ItemEnum(ref enum_definition, ref gens) => {
|
||||||
if gens.ty_params.is_empty() {
|
if gens.ty_params.is_empty() {
|
||||||
// sizes only make sense for non-generic types
|
// sizes only make sense for non-generic types
|
||||||
enum_variant_size_lint(ccx, enum_definition, item.span, item.id);
|
enum_variant_size_lint(ccx, enum_definition, item.span, item.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hir::ItemFn(..) |
|
||||||
hir::ItemImpl(..) |
|
hir::ItemImpl(..) |
|
||||||
hir::ItemStatic(..) => {
|
hir::ItemStatic(..) => {
|
||||||
// Don't do anything here. Translation has been moved to
|
// Don't do anything here. Translation has been moved to
|
||||||
|
@ -2235,22 +2218,40 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_entry_fn(sess: &Session, node_id: ast::NodeId) -> bool {
|
/// Create the `main` function which will initialise the rust runtime and call
|
||||||
match *sess.entry_fn.borrow() {
|
/// users’ main function.
|
||||||
Some((entry_id, _)) => node_id == entry_id,
|
pub fn maybe_create_entry_wrapper(ccx: &CrateContext) {
|
||||||
None => false,
|
let (main_def_id, span) = match *ccx.sess().entry_fn.borrow() {
|
||||||
}
|
Some((id, span)) => {
|
||||||
}
|
(ccx.tcx().map.local_def_id(id), span)
|
||||||
|
}
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
// check for the #[rustc_error] annotation, which forces an
|
||||||
|
// error in trans. This is used to write compile-fail tests
|
||||||
|
// that actually test that compilation succeeds without
|
||||||
|
// reporting an error.
|
||||||
|
if ccx.tcx().has_attr(main_def_id, "rustc_error") {
|
||||||
|
ccx.tcx().sess.span_fatal(span, "compilation successful");
|
||||||
|
}
|
||||||
|
|
||||||
|
let instance = Instance::mono(ccx.shared(), main_def_id);
|
||||||
|
|
||||||
|
if !ccx.codegen_unit().items.contains_key(&TransItem::Fn(instance)) {
|
||||||
|
// We want to create the wrapper in the same codegen unit as Rust's main
|
||||||
|
// function.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let main_llfn = Callee::def(ccx, main_def_id, instance.substs).reify(ccx).val;
|
||||||
|
|
||||||
/// Create the `main` function which will initialise the rust runtime and call users’ main
|
|
||||||
/// function.
|
|
||||||
pub fn create_entry_wrapper(ccx: &CrateContext, sp: Span, main_llfn: ValueRef) {
|
|
||||||
let et = ccx.sess().entry_type.get().unwrap();
|
let et = ccx.sess().entry_type.get().unwrap();
|
||||||
match et {
|
match et {
|
||||||
config::EntryMain => {
|
config::EntryMain => {
|
||||||
create_entry_fn(ccx, sp, main_llfn, true);
|
create_entry_fn(ccx, span, main_llfn, true);
|
||||||
}
|
}
|
||||||
config::EntryStart => create_entry_fn(ccx, sp, main_llfn, false),
|
config::EntryStart => create_entry_fn(ccx, span, main_llfn, false),
|
||||||
config::EntryNone => {} // Do nothing.
|
config::EntryNone => {} // Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2590,13 +2591,11 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
};
|
};
|
||||||
let no_builtins = attr::contains_name(&krate.attrs, "no_builtins");
|
let no_builtins = attr::contains_name(&krate.attrs, "no_builtins");
|
||||||
|
|
||||||
let (codegen_units, symbol_map) =
|
// Run the translation item collector and partition the collected items into
|
||||||
collect_and_partition_translation_items(&shared_ccx);
|
// codegen units.
|
||||||
|
let (codegen_units, symbol_map) = collect_and_partition_translation_items(&shared_ccx);
|
||||||
let codegen_unit_count = codegen_units.len();
|
let codegen_unit_count = codegen_units.len();
|
||||||
|
|
||||||
assert!(tcx.sess.opts.cg.codegen_units == codegen_unit_count ||
|
|
||||||
tcx.sess.opts.debugging_opts.incremental.is_some());
|
|
||||||
|
|
||||||
let symbol_map = Rc::new(symbol_map);
|
let symbol_map = Rc::new(symbol_map);
|
||||||
|
|
||||||
let crate_context_list = CrateContextList::new(&shared_ccx,
|
let crate_context_list = CrateContextList::new(&shared_ccx,
|
||||||
|
@ -2642,28 +2641,12 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
for (trans_item, _) in trans_items {
|
for (trans_item, _) in trans_items {
|
||||||
trans_item.define(&ccx);
|
trans_item.define(&ccx);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
{
|
// If this codegen unit contains the main function, also create the
|
||||||
let ccx = crate_context_list.get_ccx(0);
|
// wrapper here
|
||||||
|
maybe_create_entry_wrapper(&ccx);
|
||||||
|
|
||||||
// Translate all items. See `TransModVisitor` for
|
// Run replace-all-uses-with for statics that need it
|
||||||
// details on why we walk in this particular way.
|
|
||||||
{
|
|
||||||
let _icx = push_ctxt("text");
|
|
||||||
intravisit::walk_mod(&mut TransItemsWithinModVisitor { ccx: &ccx }, &krate.module);
|
|
||||||
krate.visit_all_items(&mut TransModVisitor { ccx: &ccx });
|
|
||||||
}
|
|
||||||
|
|
||||||
collector::print_collection_results(ccx.shared());
|
|
||||||
|
|
||||||
symbol_names_test::report_symbol_names(&ccx);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ccx in crate_context_list.iter() {
|
|
||||||
if ccx.sess().opts.debuginfo != NoDebugInfo {
|
|
||||||
debuginfo::finalize(&ccx);
|
|
||||||
}
|
|
||||||
for &(old_g, new_g) in ccx.statics_to_rauw().borrow().iter() {
|
for &(old_g, new_g) in ccx.statics_to_rauw().borrow().iter() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let bitcast = llvm::LLVMConstPointerCast(new_g, llvm::LLVMTypeOf(old_g));
|
let bitcast = llvm::LLVMConstPointerCast(new_g, llvm::LLVMTypeOf(old_g));
|
||||||
|
@ -2671,6 +2654,26 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
llvm::LLVMDeleteGlobal(old_g);
|
llvm::LLVMDeleteGlobal(old_g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finalize debuginfo
|
||||||
|
if ccx.sess().opts.debuginfo != NoDebugInfo {
|
||||||
|
debuginfo::finalize(&ccx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collector::print_collection_results(&shared_ccx);
|
||||||
|
symbol_names_test::report_symbol_names(&shared_ccx);
|
||||||
|
|
||||||
|
{
|
||||||
|
let ccx = crate_context_list.get_ccx(0);
|
||||||
|
|
||||||
|
// At this point, we only walk the HIR for running
|
||||||
|
// enum_variant_size_lint(). This should arguably be moved somewhere
|
||||||
|
// else
|
||||||
|
{
|
||||||
|
intravisit::walk_mod(&mut TransItemsWithinModVisitor { ccx: &ccx }, &krate.module);
|
||||||
|
krate.visit_all_items(&mut TransModVisitor { ccx: &ccx });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if shared_ccx.sess().trans_stats() {
|
if shared_ccx.sess().trans_stats() {
|
||||||
|
@ -2696,6 +2699,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if shared_ccx.sess().count_llvm_insns() {
|
if shared_ccx.sess().count_llvm_insns() {
|
||||||
for (k, v) in shared_ccx.stats().llvm_insns.borrow().iter() {
|
for (k, v) in shared_ccx.stats().llvm_insns.borrow().iter() {
|
||||||
println!("{:7} {}", *v, *k);
|
println!("{:7} {}", *v, *k);
|
||||||
|
@ -2867,6 +2871,9 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
|
||||||
scx.reachable())
|
scx.reachable())
|
||||||
});
|
});
|
||||||
|
|
||||||
|
assert!(scx.tcx().sess.opts.cg.codegen_units == codegen_units.len() ||
|
||||||
|
scx.tcx().sess.opts.debugging_opts.incremental.is_some());
|
||||||
|
|
||||||
if scx.sess().opts.debugging_opts.print_trans_items.is_some() {
|
if scx.sess().opts.debugging_opts.print_trans_items.is_some() {
|
||||||
let mut item_to_cgus = HashMap::new();
|
let mut item_to_cgus = HashMap::new();
|
||||||
|
|
||||||
|
|
|
@ -19,40 +19,40 @@ use rustc::hir::intravisit::{self, Visitor};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::attr::AttrMetaMethods;
|
use syntax::attr::AttrMetaMethods;
|
||||||
|
|
||||||
use common::CrateContext;
|
use common::SharedCrateContext;
|
||||||
use monomorphize::Instance;
|
use monomorphize::Instance;
|
||||||
|
|
||||||
const SYMBOL_NAME: &'static str = "rustc_symbol_name";
|
const SYMBOL_NAME: &'static str = "rustc_symbol_name";
|
||||||
const ITEM_PATH: &'static str = "rustc_item_path";
|
const ITEM_PATH: &'static str = "rustc_item_path";
|
||||||
|
|
||||||
pub fn report_symbol_names(ccx: &CrateContext) {
|
pub fn report_symbol_names(scx: &SharedCrateContext) {
|
||||||
// if the `rustc_attrs` feature is not enabled, then the
|
// if the `rustc_attrs` feature is not enabled, then the
|
||||||
// attributes we are interested in cannot be present anyway, so
|
// attributes we are interested in cannot be present anyway, so
|
||||||
// skip the walk.
|
// skip the walk.
|
||||||
let tcx = ccx.tcx();
|
let tcx = scx.tcx();
|
||||||
if !tcx.sess.features.borrow().rustc_attrs {
|
if !tcx.sess.features.borrow().rustc_attrs {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ignore = tcx.dep_graph.in_ignore();
|
let _ignore = tcx.dep_graph.in_ignore();
|
||||||
let mut visitor = SymbolNamesTest { ccx: ccx };
|
let mut visitor = SymbolNamesTest { scx: scx };
|
||||||
tcx.map.krate().visit_all_items(&mut visitor);
|
tcx.map.krate().visit_all_items(&mut visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SymbolNamesTest<'a, 'tcx:'a> {
|
struct SymbolNamesTest<'a, 'tcx:'a> {
|
||||||
ccx: &'a CrateContext<'a, 'tcx>,
|
scx: &'a SharedCrateContext<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> {
|
impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> {
|
||||||
fn process_attrs(&mut self,
|
fn process_attrs(&mut self,
|
||||||
node_id: ast::NodeId) {
|
node_id: ast::NodeId) {
|
||||||
let tcx = self.ccx.tcx();
|
let tcx = self.scx.tcx();
|
||||||
let def_id = tcx.map.local_def_id(node_id);
|
let def_id = tcx.map.local_def_id(node_id);
|
||||||
for attr in tcx.get_attrs(def_id).iter() {
|
for attr in tcx.get_attrs(def_id).iter() {
|
||||||
if attr.check_name(SYMBOL_NAME) {
|
if attr.check_name(SYMBOL_NAME) {
|
||||||
// for now, can only use on monomorphic names
|
// for now, can only use on monomorphic names
|
||||||
let instance = Instance::mono(self.ccx.shared(), def_id);
|
let instance = Instance::mono(self.scx, def_id);
|
||||||
let name = instance.symbol_name(self.ccx.shared());
|
let name = instance.symbol_name(self.scx);
|
||||||
tcx.sess.span_err(attr.span, &format!("symbol-name({})", name));
|
tcx.sess.span_err(attr.span, &format!("symbol-name({})", name));
|
||||||
} else if attr.check_name(ITEM_PATH) {
|
} else if attr.check_name(ITEM_PATH) {
|
||||||
let path = tcx.item_path_str(def_id);
|
let path = tcx.item_path_str(def_id);
|
||||||
|
|
Loading…
Reference in New Issue