// 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 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! # Note //! //! This API is completely unstable and subject to change. #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] #![deny(warnings)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(custom_attribute)] #![allow(unused_attributes)] #![feature(i128_type)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(slice_patterns)] #![feature(conservative_impl_trait)] extern crate ar; extern crate flate2; #[macro_use] extern crate log; #[macro_use] extern crate rustc; extern crate rustc_back; extern crate rustc_mir; extern crate rustc_incremental; #[macro_use] extern crate syntax; extern crate syntax_pos; extern crate rustc_data_structures; pub extern crate rustc as __rustc; use rustc::ty::{TyCtxt, Instance}; use rustc::hir; use rustc::hir::def_id::LOCAL_CRATE; use rustc::hir::map as hir_map; use rustc::util::nodemap::NodeSet; pub mod diagnostics; pub mod link; pub mod trans_crate; pub mod symbol_names; pub mod symbol_names_test; /// 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. pub fn check_for_rustc_errors_attr(tcx: TyCtxt) { if let Some((id, span)) = *tcx.sess.entry_fn.borrow() { let main_def_id = tcx.hir.local_def_id(id); if tcx.has_attr(main_def_id, "rustc_error") { tcx.sess.span_fatal(span, "compilation successful"); } } } /// The context provided lists a set of reachable ids as calculated by /// middle::reachable, but this contains far more ids and symbols than we're /// actually exposing from the object file. This function will filter the set in /// the context to the set of ids which correspond to symbols that are exposed /// from the object file being generated. /// /// This list is later used by linkers to determine the set of symbols needed to /// be exposed from a dynamic library and it's also encoded into the metadata. pub fn find_exported_symbols<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> NodeSet { tcx.reachable_set(LOCAL_CRATE).0.iter().cloned().filter(|&id| { // Next, we want to ignore some FFI functions that are not exposed from // this crate. Reachable FFI functions can be lumped into two // categories: // // 1. Those that are included statically via a static library // 2. Those included otherwise (e.g. dynamically or via a framework) // // Although our LLVM module is not literally emitting code for the // statically included symbols, it's an export of our library which // needs to be passed on to the linker and encoded in the metadata. // // As a result, if this id is an FFI item (foreign item) then we only // let it through if it's included statically. match tcx.hir.get(id) { hir_map::NodeForeignItem(..) => { let def_id = tcx.hir.local_def_id(id); tcx.is_statically_included_foreign_item(def_id) } // Only consider nodes that actually have exported symbols. hir_map::NodeItem(&hir::Item { node: hir::ItemStatic(..), .. }) | hir_map::NodeItem(&hir::Item { node: hir::ItemFn(..), .. }) | hir_map::NodeImplItem(&hir::ImplItem { node: hir::ImplItemKind::Method(..), .. }) => { let def_id = tcx.hir.local_def_id(id); let generics = tcx.generics_of(def_id); (generics.parent_types == 0 && generics.types.is_empty()) && // Functions marked with #[inline] are only ever translated // with "internal" linkage and are never exported. !Instance::mono(tcx, def_id).def.requires_local(tcx) } _ => false } }).collect() } #[cfg(not(stage0))] // remove after the next snapshot __build_diagnostic_array! { librustc_trans_utils, DIAGNOSTICS }