]>
Commit | Line | Data |
---|---|---|
9fa01778 | 1 | #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] |
60c5eb7d | 2 | #![feature(bool_to_option)] |
a1dfa0c6 | 3 | #![feature(box_patterns)] |
532ac7d7 | 4 | #![feature(try_blocks)] |
a1dfa0c6 | 5 | #![feature(in_band_lifetimes)] |
a1dfa0c6 | 6 | #![feature(nll)] |
ba9703b0 | 7 | #![feature(or_patterns)] |
532ac7d7 | 8 | #![feature(trusted_len)] |
416331ca | 9 | #![feature(associated_type_bounds)] |
dfeec247 | 10 | #![recursion_limit = "256"] |
0731742a | 11 | |
a1dfa0c6 XL |
12 | //! This crate contains codegen code that is used by all codegen backends (LLVM and others). |
13 | //! The backend-agnostic functions of this crate use functions defined in various traits that | |
14 | //! have to be implemented by each backends. | |
15 | ||
dfeec247 XL |
16 | #[macro_use] |
17 | extern crate log; | |
18 | #[macro_use] | |
ba9703b0 | 19 | extern crate rustc_middle; |
a1dfa0c6 | 20 | |
a1dfa0c6 | 21 | use rustc_data_structures::fx::{FxHashMap, FxHashSet}; |
a1dfa0c6 | 22 | use rustc_data_structures::svh::Svh; |
dfeec247 XL |
23 | use rustc_data_structures::sync::Lrc; |
24 | use rustc_hir::def_id::CrateNum; | |
ba9703b0 XL |
25 | use rustc_hir::LangItem; |
26 | use rustc_middle::dep_graph::WorkProduct; | |
f9f354fc | 27 | use rustc_middle::middle::cstore::{CrateSource, LibSource, NativeLib}; |
ba9703b0 XL |
28 | use rustc_middle::middle::dependency_format::Dependencies; |
29 | use rustc_middle::ty::query::Providers; | |
30 | use rustc_session::config::{OutputFilenames, OutputType, RUST_CGU_EXT}; | |
dfeec247 XL |
31 | use rustc_span::symbol::Symbol; |
32 | use std::path::{Path, PathBuf}; | |
a1dfa0c6 | 33 | |
dfeec247 XL |
34 | pub mod back; |
35 | pub mod base; | |
a1dfa0c6 | 36 | pub mod common; |
f035d41b | 37 | pub mod coverageinfo; |
a1dfa0c6 | 38 | pub mod debuginfo; |
a1dfa0c6 XL |
39 | pub mod glue; |
40 | pub mod meth; | |
dfeec247 | 41 | pub mod mir; |
a1dfa0c6 | 42 | pub mod mono_item; |
dfeec247 | 43 | pub mod traits; |
a1dfa0c6 XL |
44 | |
45 | pub struct ModuleCodegen<M> { | |
46 | /// The name of the module. When the crate may be saved between | |
47 | /// compilations, incremental compilation requires that name be | |
9fa01778 | 48 | /// unique amongst **all** crates. Therefore, it should contain |
a1dfa0c6 XL |
49 | /// something unique to this crate (e.g., a module path) as well |
50 | /// as the crate name and disambiguator. | |
51 | /// We currently generate these names via CodegenUnit::build_cgu_name(). | |
52 | pub name: String, | |
53 | pub module_llvm: M, | |
54 | pub kind: ModuleKind, | |
55 | } | |
56 | ||
60c5eb7d XL |
57 | // FIXME(eddyb) maybe include the crate name in this? |
58 | pub const METADATA_FILENAME: &str = "lib.rmeta"; | |
a1dfa0c6 XL |
59 | |
60 | impl<M> ModuleCodegen<M> { | |
dfeec247 XL |
61 | pub fn into_compiled_module( |
62 | self, | |
63 | emit_obj: bool, | |
64 | emit_bc: bool, | |
dfeec247 XL |
65 | outputs: &OutputFilenames, |
66 | ) -> CompiledModule { | |
67 | let object = emit_obj.then(|| outputs.temp_path(OutputType::Object, Some(&self.name))); | |
68 | let bytecode = emit_bc.then(|| outputs.temp_path(OutputType::Bitcode, Some(&self.name))); | |
a1dfa0c6 | 69 | |
f9f354fc | 70 | CompiledModule { name: self.name.clone(), kind: self.kind, object, bytecode } |
a1dfa0c6 XL |
71 | } |
72 | } | |
73 | ||
dfeec247 | 74 | #[derive(Debug, RustcEncodable, RustcDecodable)] |
a1dfa0c6 XL |
75 | pub struct CompiledModule { |
76 | pub name: String, | |
77 | pub kind: ModuleKind, | |
78 | pub object: Option<PathBuf>, | |
79 | pub bytecode: Option<PathBuf>, | |
a1dfa0c6 XL |
80 | } |
81 | ||
82 | pub struct CachedModuleCodegen { | |
83 | pub name: String, | |
84 | pub source: WorkProduct, | |
85 | } | |
86 | ||
dfeec247 | 87 | #[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)] |
a1dfa0c6 XL |
88 | pub enum ModuleKind { |
89 | Regular, | |
90 | Metadata, | |
91 | Allocator, | |
92 | } | |
93 | ||
9fa01778 | 94 | bitflags::bitflags! { |
a1dfa0c6 XL |
95 | pub struct MemFlags: u8 { |
96 | const VOLATILE = 1 << 0; | |
97 | const NONTEMPORAL = 1 << 1; | |
98 | const UNALIGNED = 1 << 2; | |
99 | } | |
100 | } | |
101 | ||
9fa01778 | 102 | /// Misc info we load from metadata to persist beyond the tcx. |
dfeec247 XL |
103 | /// |
104 | /// Note: though `CrateNum` is only meaningful within the same tcx, information within `CrateInfo` | |
105 | /// is self-contained. `CrateNum` can be viewed as a unique identifier within a `CrateInfo`, where | |
106 | /// `used_crate_source` contains all `CrateSource` of the dependents, and maintains a mapping from | |
107 | /// identifiers (`CrateNum`) to `CrateSource`. The other fields map `CrateNum` to the crate's own | |
108 | /// additional properties, so that effectively we can retrieve each dependent crate's `CrateSource` | |
109 | /// and the corresponding properties without referencing information outside of a `CrateInfo`. | |
110 | #[derive(Debug, RustcEncodable, RustcDecodable)] | |
a1dfa0c6 XL |
111 | pub struct CrateInfo { |
112 | pub panic_runtime: Option<CrateNum>, | |
113 | pub compiler_builtins: Option<CrateNum>, | |
114 | pub profiler_runtime: Option<CrateNum>, | |
a1dfa0c6 | 115 | pub is_no_builtins: FxHashSet<CrateNum>, |
f9f354fc | 116 | pub native_libraries: FxHashMap<CrateNum, Lrc<Vec<NativeLib>>>, |
a1dfa0c6 | 117 | pub crate_name: FxHashMap<CrateNum, String>, |
f9f354fc | 118 | pub used_libraries: Lrc<Vec<NativeLib>>, |
a1dfa0c6 XL |
119 | pub link_args: Lrc<Vec<String>>, |
120 | pub used_crate_source: FxHashMap<CrateNum, Lrc<CrateSource>>, | |
121 | pub used_crates_static: Vec<(CrateNum, LibSource)>, | |
122 | pub used_crates_dynamic: Vec<(CrateNum, LibSource)>, | |
a1dfa0c6 XL |
123 | pub lang_item_to_crate: FxHashMap<LangItem, CrateNum>, |
124 | pub missing_lang_items: FxHashMap<CrateNum, Vec<LangItem>>, | |
e74abb32 | 125 | pub dependency_formats: Lrc<Dependencies>, |
a1dfa0c6 XL |
126 | } |
127 | ||
dfeec247 | 128 | #[derive(RustcEncodable, RustcDecodable)] |
a1dfa0c6 XL |
129 | pub struct CodegenResults { |
130 | pub crate_name: Symbol, | |
131 | pub modules: Vec<CompiledModule>, | |
132 | pub allocator_module: Option<CompiledModule>, | |
48663c56 | 133 | pub metadata_module: Option<CompiledModule>, |
a1dfa0c6 | 134 | pub crate_hash: Svh, |
ba9703b0 | 135 | pub metadata: rustc_middle::middle::cstore::EncodedMetadata, |
a1dfa0c6 XL |
136 | pub windows_subsystem: Option<String>, |
137 | pub linker_info: back::linker::LinkerInfo, | |
138 | pub crate_info: CrateInfo, | |
139 | } | |
e74abb32 | 140 | |
f035d41b | 141 | pub fn provide(providers: &mut Providers) { |
e74abb32 XL |
142 | crate::back::symbol_export::provide(providers); |
143 | crate::base::provide_both(providers); | |
144 | } | |
145 | ||
f035d41b | 146 | pub fn provide_extern(providers: &mut Providers) { |
e74abb32 XL |
147 | crate::back::symbol_export::provide_extern(providers); |
148 | crate::base::provide_both(providers); | |
149 | } | |
150 | ||
151 | /// Checks if the given filename ends with the `.rcgu.o` extension that `rustc` | |
152 | /// uses for the object files it generates. | |
153 | pub fn looks_like_rust_object_file(filename: &str) -> bool { | |
154 | let path = Path::new(filename); | |
155 | let ext = path.extension().and_then(|s| s.to_str()); | |
156 | if ext != Some(OutputType::Object.extension()) { | |
157 | // The file name does not end with ".o", so it can't be an object file. | |
dfeec247 | 158 | return false; |
e74abb32 XL |
159 | } |
160 | ||
161 | // Strip the ".o" at the end | |
dfeec247 | 162 | let ext2 = path.file_stem().and_then(|s| Path::new(s).extension()).and_then(|s| s.to_str()); |
e74abb32 XL |
163 | |
164 | // Check if the "inner" extension | |
165 | ext2 == Some(RUST_CGU_EXT) | |
166 | } |