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