2017-08-05 16:55:23 +02:00
|
|
|
// 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.
|
|
|
|
|
|
|
|
|
|
//! # 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)]
|
|
|
|
|
|
2017-09-18 18:12:07 +02:00
|
|
|
extern crate ar;
|
|
|
|
|
extern crate flate2;
|
2017-08-13 18:53:50 +02:00
|
|
|
#[macro_use]
|
|
|
|
|
extern crate log;
|
2017-09-18 18:12:07 +02:00
|
|
|
|
|
|
|
|
#[macro_use]
|
2017-08-05 16:55:23 +02:00
|
|
|
extern crate rustc;
|
2017-09-18 18:12:07 +02:00
|
|
|
extern crate rustc_back;
|
2017-10-30 18:42:21 +01:00
|
|
|
extern crate rustc_mir;
|
|
|
|
|
extern crate rustc_incremental;
|
|
|
|
|
#[macro_use]
|
2017-08-05 16:55:23 +02:00
|
|
|
extern crate syntax;
|
|
|
|
|
extern crate syntax_pos;
|
2017-12-18 16:59:26 +01:00
|
|
|
extern crate rustc_data_structures;
|
2017-08-05 16:55:23 +02:00
|
|
|
|
2017-10-30 18:49:56 +01:00
|
|
|
use rustc::ty::{TyCtxt, Instance};
|
2017-08-13 18:53:50 +02:00
|
|
|
use rustc::hir;
|
2017-09-23 14:46:15 +02:00
|
|
|
use rustc::hir::def_id::LOCAL_CRATE;
|
2017-08-13 18:53:50 +02:00
|
|
|
use rustc::hir::map as hir_map;
|
|
|
|
|
use rustc::util::nodemap::NodeSet;
|
|
|
|
|
|
2017-10-30 18:42:21 +01:00
|
|
|
pub mod diagnostics;
|
2017-08-05 16:55:23 +02:00
|
|
|
pub mod link;
|
2017-09-18 18:12:07 +02:00
|
|
|
pub mod trans_crate;
|
2017-10-30 18:42:21 +01:00
|
|
|
pub mod symbol_names;
|
|
|
|
|
pub mod symbol_names_test;
|
2017-08-13 18:53:50 +02:00
|
|
|
|
2017-09-23 18:15:58 +02:00
|
|
|
/// 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");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-13 18:53:50 +02:00
|
|
|
/// 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.
|
2017-10-30 18:49:56 +01:00
|
|
|
pub fn find_exported_symbols<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> NodeSet {
|
2017-09-23 14:46:15 +02:00
|
|
|
tcx.reachable_set(LOCAL_CRATE).0.iter().cloned().filter(|&id| {
|
2017-08-13 18:53:50 +02:00
|
|
|
// 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);
|
2017-09-10 14:17:54 +02:00
|
|
|
tcx.is_statically_included_foreign_item(def_id)
|
2017-08-13 18:53:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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.
|
2017-10-30 08:36:03 +01:00
|
|
|
!Instance::mono(tcx, def_id).def.requires_local(tcx)
|
2017-08-13 18:53:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_ => false
|
|
|
|
|
}
|
|
|
|
|
}).collect()
|
|
|
|
|
}
|
2017-10-30 18:42:21 +01:00
|
|
|
|
|
|
|
|
__build_diagnostic_array! { librustc_trans_utils, DIAGNOSTICS }
|