]>
Commit | Line | Data |
---|---|---|
dfeec247 XL |
1 | use crate::config::*; |
2 | ||
3 | use crate::early_error; | |
4 | use crate::lint; | |
5 | use crate::search_paths::SearchPath; | |
f9f354fc | 6 | use crate::utils::NativeLibKind; |
dfeec247 | 7 | |
f9f354fc XL |
8 | use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy}; |
9 | use rustc_target::spec::{RelocModel, RelroLevel, TargetTriple, TlsModel}; | |
dfeec247 XL |
10 | |
11 | use rustc_feature::UnstableFeatures; | |
12 | use rustc_span::edition::Edition; | |
ba9703b0 | 13 | use rustc_span::SourceFileHashAlgorithm; |
dfeec247 | 14 | |
dfeec247 XL |
15 | use std::collections::BTreeMap; |
16 | ||
17 | use std::collections::hash_map::DefaultHasher; | |
18 | use std::hash::Hasher; | |
19 | use std::path::PathBuf; | |
20 | use std::str; | |
21 | ||
22 | macro_rules! hash_option { | |
23 | ($opt_name:ident, $opt_expr:expr, $sub_hashes:expr, [UNTRACKED]) => {{}}; | |
24 | ($opt_name:ident, $opt_expr:expr, $sub_hashes:expr, [TRACKED]) => {{ | |
25 | if $sub_hashes | |
26 | .insert(stringify!($opt_name), $opt_expr as &dyn dep_tracking::DepTrackingHash) | |
27 | .is_some() | |
28 | { | |
29 | panic!("duplicate key in CLI DepTrackingHash: {}", stringify!($opt_name)) | |
30 | } | |
31 | }}; | |
32 | } | |
33 | ||
34 | macro_rules! top_level_options { | |
35 | (pub struct Options { $( | |
36 | $opt:ident : $t:ty [$dep_tracking_marker:ident $($warn_val:expr, $warn_text:expr)*], | |
37 | )* } ) => ( | |
38 | #[derive(Clone)] | |
39 | pub struct Options { | |
40 | $(pub $opt: $t),* | |
41 | } | |
42 | ||
43 | impl Options { | |
44 | pub fn dep_tracking_hash(&self) -> u64 { | |
45 | let mut sub_hashes = BTreeMap::new(); | |
46 | $({ | |
47 | hash_option!($opt, | |
48 | &self.$opt, | |
49 | &mut sub_hashes, | |
50 | [$dep_tracking_marker $($warn_val, | |
51 | $warn_text, | |
52 | self.error_format)*]); | |
53 | })* | |
54 | let mut hasher = DefaultHasher::new(); | |
55 | dep_tracking::stable_hash(sub_hashes, | |
56 | &mut hasher, | |
57 | self.error_format); | |
58 | hasher.finish() | |
59 | } | |
60 | } | |
61 | ); | |
62 | } | |
63 | ||
64 | // The top-level command-line options struct. | |
65 | // | |
66 | // For each option, one has to specify how it behaves with regard to the | |
67 | // dependency tracking system of incremental compilation. This is done via the | |
68 | // square-bracketed directive after the field type. The options are: | |
69 | // | |
70 | // [TRACKED] | |
71 | // A change in the given field will cause the compiler to completely clear the | |
72 | // incremental compilation cache before proceeding. | |
73 | // | |
74 | // [UNTRACKED] | |
75 | // Incremental compilation is not influenced by this option. | |
76 | // | |
77 | // If you add a new option to this struct or one of the sub-structs like | |
78 | // `CodegenOptions`, think about how it influences incremental compilation. If in | |
79 | // doubt, specify [TRACKED], which is always "correct" but might lead to | |
80 | // unnecessary re-compilation. | |
81 | top_level_options!( | |
82 | pub struct Options { | |
83 | // The crate config requested for the session, which may be combined | |
84 | // with additional crate configurations during the compile process. | |
85 | crate_types: Vec<CrateType> [TRACKED], | |
86 | optimize: OptLevel [TRACKED], | |
87 | // Include the `debug_assertions` flag in dependency tracking, since it | |
88 | // can influence whether overflow checks are done or not. | |
89 | debug_assertions: bool [TRACKED], | |
90 | debuginfo: DebugInfo [TRACKED], | |
91 | lint_opts: Vec<(String, lint::Level)> [TRACKED], | |
92 | lint_cap: Option<lint::Level> [TRACKED], | |
93 | describe_lints: bool [UNTRACKED], | |
94 | output_types: OutputTypes [TRACKED], | |
95 | search_paths: Vec<SearchPath> [UNTRACKED], | |
f9f354fc | 96 | libs: Vec<(String, Option<String>, NativeLibKind)> [TRACKED], |
dfeec247 XL |
97 | maybe_sysroot: Option<PathBuf> [UNTRACKED], |
98 | ||
99 | target_triple: TargetTriple [TRACKED], | |
100 | ||
101 | test: bool [TRACKED], | |
102 | error_format: ErrorOutputType [UNTRACKED], | |
103 | ||
104 | // If `Some`, enable incremental compilation, using the given | |
105 | // directory to store intermediate results. | |
106 | incremental: Option<PathBuf> [UNTRACKED], | |
107 | ||
108 | debugging_opts: DebuggingOptions [TRACKED], | |
109 | prints: Vec<PrintRequest> [UNTRACKED], | |
110 | // Determines which borrow checker(s) to run. This is the parsed, sanitized | |
111 | // version of `debugging_opts.borrowck`, which is just a plain string. | |
112 | borrowck_mode: BorrowckMode [UNTRACKED], | |
113 | cg: CodegenOptions [TRACKED], | |
114 | externs: Externs [UNTRACKED], | |
115 | crate_name: Option<String> [TRACKED], | |
116 | // An optional name to use as the crate for std during std injection, | |
117 | // written `extern crate name as std`. Defaults to `std`. Used by | |
118 | // out-of-tree drivers. | |
119 | alt_std_name: Option<String> [TRACKED], | |
120 | // Indicates how the compiler should treat unstable features. | |
121 | unstable_features: UnstableFeatures [TRACKED], | |
122 | ||
123 | // Indicates whether this run of the compiler is actually rustdoc. This | |
124 | // is currently just a hack and will be removed eventually, so please | |
125 | // try to not rely on this too much. | |
126 | actually_rustdoc: bool [TRACKED], | |
127 | ||
1b1a35ee XL |
128 | // Control path trimming. |
129 | trimmed_def_paths: TrimmedDefPaths [TRACKED], | |
130 | ||
dfeec247 XL |
131 | // Specifications of codegen units / ThinLTO which are forced as a |
132 | // result of parsing command line options. These are not necessarily | |
133 | // what rustc was invoked with, but massaged a bit to agree with | |
134 | // commands like `--emit llvm-ir` which they're often incompatible with | |
135 | // if we otherwise use the defaults of rustc. | |
136 | cli_forced_codegen_units: Option<usize> [UNTRACKED], | |
137 | cli_forced_thinlto_off: bool [UNTRACKED], | |
138 | ||
139 | // Remap source path prefixes in all output (messages, object files, debug, etc.). | |
140 | remap_path_prefix: Vec<(PathBuf, PathBuf)> [UNTRACKED], | |
141 | ||
142 | edition: Edition [TRACKED], | |
143 | ||
144 | // `true` if we're emitting JSON blobs about each artifact produced | |
145 | // by the compiler. | |
146 | json_artifact_notifications: bool [TRACKED], | |
147 | ||
148 | pretty: Option<PpMode> [UNTRACKED], | |
149 | } | |
150 | ); | |
151 | ||
152 | /// Defines all `CodegenOptions`/`DebuggingOptions` fields and parsers all at once. The goal of this | |
153 | /// macro is to define an interface that can be programmatically used by the option parser | |
154 | /// to initialize the struct without hardcoding field names all over the place. | |
155 | /// | |
156 | /// The goal is to invoke this macro once with the correct fields, and then this macro generates all | |
157 | /// necessary code. The main gotcha of this macro is the `cgsetters` module which is a bunch of | |
158 | /// generated code to parse an option into its respective field in the struct. There are a few | |
159 | /// hand-written parsers for parsing specific types of values in this module. | |
160 | macro_rules! options { | |
161 | ($struct_name:ident, $setter_name:ident, $defaultfn:ident, | |
162 | $buildfn:ident, $prefix:expr, $outputname:expr, | |
163 | $stat:ident, $mod_desc:ident, $mod_set:ident, | |
164 | $($opt:ident : $t:ty = ( | |
165 | $init:expr, | |
166 | $parse:ident, | |
167 | [$dep_tracking_marker:ident $(($dep_warn_val:expr, $dep_warn_text:expr))*], | |
168 | $desc:expr) | |
169 | ),* ,) => | |
170 | ( | |
171 | #[derive(Clone)] | |
172 | pub struct $struct_name { $(pub $opt: $t),* } | |
173 | ||
174 | pub fn $defaultfn() -> $struct_name { | |
175 | $struct_name { $($opt: $init),* } | |
176 | } | |
177 | ||
178 | pub fn $buildfn(matches: &getopts::Matches, error_format: ErrorOutputType) -> $struct_name | |
179 | { | |
180 | let mut op = $defaultfn(); | |
181 | for option in matches.opt_strs($prefix) { | |
182 | let mut iter = option.splitn(2, '='); | |
183 | let key = iter.next().unwrap(); | |
184 | let value = iter.next(); | |
185 | let option_to_lookup = key.replace("-", "_"); | |
186 | let mut found = false; | |
ba9703b0 | 187 | for &(candidate, setter, type_desc, _) in $stat { |
dfeec247 XL |
188 | if option_to_lookup != candidate { continue } |
189 | if !setter(&mut op, value) { | |
ba9703b0 XL |
190 | match value { |
191 | None => { | |
dfeec247 XL |
192 | early_error(error_format, &format!("{0} option `{1}` requires \ |
193 | {2} ({3} {1}=<value>)", | |
194 | $outputname, key, | |
195 | type_desc, $prefix)) | |
196 | } | |
ba9703b0 | 197 | Some(value) => { |
dfeec247 XL |
198 | early_error(error_format, &format!("incorrect value `{}` for {} \ |
199 | option `{}` - {} was expected", | |
200 | value, $outputname, | |
201 | key, type_desc)) | |
202 | } | |
dfeec247 XL |
203 | } |
204 | } | |
205 | found = true; | |
206 | break; | |
207 | } | |
208 | if !found { | |
209 | early_error(error_format, &format!("unknown {} option: `{}`", | |
210 | $outputname, key)); | |
211 | } | |
212 | } | |
213 | return op; | |
214 | } | |
215 | ||
216 | impl dep_tracking::DepTrackingHash for $struct_name { | |
217 | fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) { | |
218 | let mut sub_hashes = BTreeMap::new(); | |
219 | $({ | |
220 | hash_option!($opt, | |
221 | &self.$opt, | |
222 | &mut sub_hashes, | |
223 | [$dep_tracking_marker $($dep_warn_val, | |
224 | $dep_warn_text, | |
225 | error_format)*]); | |
226 | })* | |
227 | dep_tracking::stable_hash(sub_hashes, hasher, error_format); | |
228 | } | |
229 | } | |
230 | ||
231 | pub type $setter_name = fn(&mut $struct_name, v: Option<&str>) -> bool; | |
ba9703b0 | 232 | pub const $stat: &[(&str, $setter_name, &str, &str)] = |
dfeec247 XL |
233 | &[ $( (stringify!($opt), $mod_set::$opt, $mod_desc::$parse, $desc) ),* ]; |
234 | ||
235 | #[allow(non_upper_case_globals, dead_code)] | |
236 | mod $mod_desc { | |
ba9703b0 XL |
237 | pub const parse_no_flag: &str = "no value"; |
238 | pub const parse_bool: &str = "one of: `y`, `yes`, `on`, `n`, `no`, or `off`"; | |
239 | pub const parse_opt_bool: &str = parse_bool; | |
240 | pub const parse_string: &str = "a string"; | |
241 | pub const parse_opt_string: &str = parse_string; | |
242 | pub const parse_string_push: &str = parse_string; | |
243 | pub const parse_opt_pathbuf: &str = "a path"; | |
244 | pub const parse_pathbuf_push: &str = parse_opt_pathbuf; | |
245 | pub const parse_list: &str = "a space-separated list of strings"; | |
246 | pub const parse_opt_list: &str = parse_list; | |
247 | pub const parse_opt_comma_list: &str = "a comma-separated list of strings"; | |
248 | pub const parse_uint: &str = "a number"; | |
249 | pub const parse_opt_uint: &str = parse_uint; | |
250 | pub const parse_threads: &str = parse_uint; | |
251 | pub const parse_passes: &str = "a space-separated list of passes, or `all`"; | |
252 | pub const parse_panic_strategy: &str = "either `unwind` or `abort`"; | |
253 | pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; | |
f035d41b | 254 | pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `leak`, `memory` or `thread`"; |
ba9703b0 | 255 | pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2"; |
f035d41b XL |
256 | pub const parse_cfguard: &str = |
257 | "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`"; | |
f9f354fc | 258 | pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`"; |
ba9703b0 XL |
259 | pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavor::one_of(); |
260 | pub const parse_optimization_fuel: &str = "crate=integer"; | |
1b1a35ee | 261 | pub const parse_mir_spanview: &str = "`statement` (default), `terminator`, or `block`"; |
ba9703b0 XL |
262 | pub const parse_unpretty: &str = "`string` or `string=string`"; |
263 | pub const parse_treat_err_as_bug: &str = "either no value or a number bigger than 0"; | |
264 | pub const parse_lto: &str = | |
265 | "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted"; | |
266 | pub const parse_linker_plugin_lto: &str = | |
267 | "either a boolean (`yes`, `no`, `on`, `off`, etc), or the path to the linker plugin"; | |
268 | pub const parse_switch_with_opt_path: &str = | |
269 | "an optional path to the profiling data output directory"; | |
270 | pub const parse_merge_functions: &str = "one of: `disabled`, `trampolines`, or `aliases`"; | |
271 | pub const parse_symbol_mangling_version: &str = "either `legacy` or `v0` (RFC 2603)"; | |
272 | pub const parse_src_file_hash: &str = "either `md5` or `sha1`"; | |
f9f354fc XL |
273 | pub const parse_relocation_model: &str = |
274 | "one of supported relocation models (`rustc --print relocation-models`)"; | |
275 | pub const parse_code_model: &str = | |
276 | "one of supported code models (`rustc --print code-models`)"; | |
277 | pub const parse_tls_model: &str = | |
278 | "one of supported TLS models (`rustc --print tls-models`)"; | |
279 | pub const parse_target_feature: &str = parse_string; | |
dfeec247 XL |
280 | } |
281 | ||
282 | #[allow(dead_code)] | |
283 | mod $mod_set { | |
f9f354fc | 284 | use super::*; |
dfeec247 XL |
285 | use std::str::FromStr; |
286 | ||
ba9703b0 XL |
287 | // Sometimes different options need to build a common structure. |
288 | // That structure can kept in one of the options' fields, the others become dummy. | |
289 | macro_rules! redirect_field { | |
290 | ($cg:ident.link_arg) => { $cg.link_args }; | |
291 | ($cg:ident.pre_link_arg) => { $cg.pre_link_args }; | |
292 | ($cg:ident.$field:ident) => { $cg.$field }; | |
293 | } | |
294 | ||
dfeec247 XL |
295 | $( |
296 | pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool { | |
ba9703b0 | 297 | $parse(&mut redirect_field!(cg.$opt), v) |
dfeec247 XL |
298 | } |
299 | )* | |
300 | ||
ba9703b0 XL |
301 | /// This is for boolean options that don't take a value and start with |
302 | /// `no-`. This style of option is deprecated. | |
303 | fn parse_no_flag(slot: &mut bool, v: Option<&str>) -> bool { | |
dfeec247 | 304 | match v { |
dfeec247 | 305 | None => { *slot = true; true } |
ba9703b0 | 306 | Some(_) => false, |
dfeec247 XL |
307 | } |
308 | } | |
309 | ||
ba9703b0 XL |
310 | /// Use this for any boolean option that has a static default. |
311 | fn parse_bool(slot: &mut bool, v: Option<&str>) -> bool { | |
dfeec247 | 312 | match v { |
ba9703b0 XL |
313 | Some("y") | Some("yes") | Some("on") | None => { *slot = true; true } |
314 | Some("n") | Some("no") | Some("off") => { *slot = false; true } | |
315 | _ => false, | |
316 | } | |
317 | } | |
dfeec247 | 318 | |
ba9703b0 XL |
319 | /// Use this for any boolean option that lacks a static default. (The |
320 | /// actions taken when such an option is not specified will depend on | |
321 | /// other factors, such as other options, or target options.) | |
322 | fn parse_opt_bool(slot: &mut Option<bool>, v: Option<&str>) -> bool { | |
323 | match v { | |
324 | Some("y") | Some("yes") | Some("on") | None => { *slot = Some(true); true } | |
325 | Some("n") | Some("no") | Some("off") => { *slot = Some(false); true } | |
326 | _ => false, | |
dfeec247 XL |
327 | } |
328 | } | |
329 | ||
ba9703b0 XL |
330 | /// Use this for any string option that has a static default. |
331 | fn parse_string(slot: &mut String, v: Option<&str>) -> bool { | |
dfeec247 | 332 | match v { |
ba9703b0 | 333 | Some(s) => { *slot = s.to_string(); true }, |
dfeec247 XL |
334 | None => false, |
335 | } | |
336 | } | |
337 | ||
ba9703b0 XL |
338 | /// Use this for any string option that lacks a static default. |
339 | fn parse_opt_string(slot: &mut Option<String>, v: Option<&str>) -> bool { | |
dfeec247 | 340 | match v { |
ba9703b0 | 341 | Some(s) => { *slot = Some(s.to_string()); true }, |
dfeec247 XL |
342 | None => false, |
343 | } | |
344 | } | |
345 | ||
ba9703b0 | 346 | fn parse_opt_pathbuf(slot: &mut Option<PathBuf>, v: Option<&str>) -> bool { |
dfeec247 | 347 | match v { |
ba9703b0 | 348 | Some(s) => { *slot = Some(PathBuf::from(s)); true }, |
dfeec247 XL |
349 | None => false, |
350 | } | |
351 | } | |
352 | ||
353 | fn parse_string_push(slot: &mut Vec<String>, v: Option<&str>) -> bool { | |
354 | match v { | |
355 | Some(s) => { slot.push(s.to_string()); true }, | |
356 | None => false, | |
357 | } | |
358 | } | |
359 | ||
360 | fn parse_pathbuf_push(slot: &mut Vec<PathBuf>, v: Option<&str>) -> bool { | |
361 | match v { | |
362 | Some(s) => { slot.push(PathBuf::from(s)); true }, | |
363 | None => false, | |
364 | } | |
365 | } | |
366 | ||
367 | fn parse_list(slot: &mut Vec<String>, v: Option<&str>) | |
368 | -> bool { | |
369 | match v { | |
370 | Some(s) => { | |
371 | slot.extend(s.split_whitespace().map(|s| s.to_string())); | |
372 | true | |
373 | }, | |
374 | None => false, | |
375 | } | |
376 | } | |
377 | ||
378 | fn parse_opt_list(slot: &mut Option<Vec<String>>, v: Option<&str>) | |
379 | -> bool { | |
380 | match v { | |
381 | Some(s) => { | |
382 | let v = s.split_whitespace().map(|s| s.to_string()).collect(); | |
383 | *slot = Some(v); | |
384 | true | |
385 | }, | |
386 | None => false, | |
387 | } | |
388 | } | |
389 | ||
390 | fn parse_opt_comma_list(slot: &mut Option<Vec<String>>, v: Option<&str>) | |
391 | -> bool { | |
392 | match v { | |
393 | Some(s) => { | |
394 | let v = s.split(',').map(|s| s.to_string()).collect(); | |
395 | *slot = Some(v); | |
396 | true | |
397 | }, | |
398 | None => false, | |
399 | } | |
400 | } | |
401 | ||
402 | fn parse_threads(slot: &mut usize, v: Option<&str>) -> bool { | |
403 | match v.and_then(|s| s.parse().ok()) { | |
404 | Some(0) => { *slot = ::num_cpus::get(); true }, | |
405 | Some(i) => { *slot = i; true }, | |
406 | None => false | |
407 | } | |
408 | } | |
409 | ||
ba9703b0 | 410 | /// Use this for any uint option that has a static default. |
dfeec247 XL |
411 | fn parse_uint(slot: &mut usize, v: Option<&str>) -> bool { |
412 | match v.and_then(|s| s.parse().ok()) { | |
413 | Some(i) => { *slot = i; true }, | |
414 | None => false | |
415 | } | |
416 | } | |
417 | ||
ba9703b0 | 418 | /// Use this for any uint option that lacks a static default. |
dfeec247 XL |
419 | fn parse_opt_uint(slot: &mut Option<usize>, v: Option<&str>) -> bool { |
420 | match v { | |
421 | Some(s) => { *slot = s.parse().ok(); slot.is_some() } | |
ba9703b0 | 422 | None => false |
dfeec247 XL |
423 | } |
424 | } | |
425 | ||
426 | fn parse_passes(slot: &mut Passes, v: Option<&str>) -> bool { | |
427 | match v { | |
428 | Some("all") => { | |
429 | *slot = Passes::All; | |
430 | true | |
431 | } | |
432 | v => { | |
433 | let mut passes = vec![]; | |
434 | if parse_list(&mut passes, v) { | |
435 | *slot = Passes::Some(passes); | |
436 | true | |
437 | } else { | |
438 | false | |
439 | } | |
440 | } | |
441 | } | |
442 | } | |
443 | ||
444 | fn parse_panic_strategy(slot: &mut Option<PanicStrategy>, v: Option<&str>) -> bool { | |
445 | match v { | |
446 | Some("unwind") => *slot = Some(PanicStrategy::Unwind), | |
447 | Some("abort") => *slot = Some(PanicStrategy::Abort), | |
448 | _ => return false | |
449 | } | |
450 | true | |
451 | } | |
452 | ||
453 | fn parse_relro_level(slot: &mut Option<RelroLevel>, v: Option<&str>) -> bool { | |
454 | match v { | |
455 | Some(s) => { | |
456 | match s.parse::<RelroLevel>() { | |
457 | Ok(level) => *slot = Some(level), | |
458 | _ => return false | |
459 | } | |
460 | }, | |
461 | _ => return false | |
462 | } | |
463 | true | |
464 | } | |
465 | ||
f035d41b | 466 | fn parse_sanitizers(slot: &mut SanitizerSet, v: Option<&str>) -> bool { |
dfeec247 | 467 | if let Some(v) = v { |
f035d41b XL |
468 | for s in v.split(',') { |
469 | *slot |= match s { | |
470 | "address" => SanitizerSet::ADDRESS, | |
471 | "leak" => SanitizerSet::LEAK, | |
472 | "memory" => SanitizerSet::MEMORY, | |
473 | "thread" => SanitizerSet::THREAD, | |
474 | _ => return false, | |
dfeec247 XL |
475 | } |
476 | } | |
477 | true | |
478 | } else { | |
479 | false | |
480 | } | |
481 | } | |
482 | ||
483 | fn parse_sanitizer_memory_track_origins(slot: &mut usize, v: Option<&str>) -> bool { | |
ba9703b0 XL |
484 | match v { |
485 | Some("2") | None => { *slot = 2; true } | |
486 | Some("1") => { *slot = 1; true } | |
487 | Some("0") => { *slot = 0; true } | |
488 | Some(_) => false, | |
dfeec247 XL |
489 | } |
490 | } | |
491 | ||
f9f354fc XL |
492 | fn parse_strip(slot: &mut Strip, v: Option<&str>) -> bool { |
493 | match v { | |
494 | Some("none") => *slot = Strip::None, | |
495 | Some("debuginfo") => *slot = Strip::Debuginfo, | |
496 | Some("symbols") => *slot = Strip::Symbols, | |
497 | _ => return false, | |
498 | } | |
499 | true | |
500 | } | |
501 | ||
74b04a01 | 502 | fn parse_cfguard(slot: &mut CFGuard, v: Option<&str>) -> bool { |
f035d41b XL |
503 | if v.is_some() { |
504 | let mut bool_arg = None; | |
505 | if parse_opt_bool(&mut bool_arg, v) { | |
506 | *slot = if bool_arg.unwrap() { | |
507 | CFGuard::Checks | |
508 | } else { | |
509 | CFGuard::Disabled | |
510 | }; | |
511 | return true | |
512 | } | |
74b04a01 | 513 | } |
f035d41b XL |
514 | |
515 | *slot = match v { | |
516 | None => CFGuard::Checks, | |
517 | Some("checks") => CFGuard::Checks, | |
518 | Some("nochecks") => CFGuard::NoChecks, | |
519 | Some(_) => return false, | |
520 | }; | |
74b04a01 XL |
521 | true |
522 | } | |
523 | ||
dfeec247 XL |
524 | fn parse_linker_flavor(slote: &mut Option<LinkerFlavor>, v: Option<&str>) -> bool { |
525 | match v.and_then(LinkerFlavor::from_str) { | |
526 | Some(lf) => *slote = Some(lf), | |
527 | _ => return false, | |
528 | } | |
529 | true | |
530 | } | |
531 | ||
532 | fn parse_optimization_fuel(slot: &mut Option<(String, u64)>, v: Option<&str>) -> bool { | |
533 | match v { | |
534 | None => false, | |
535 | Some(s) => { | |
536 | let parts = s.split('=').collect::<Vec<_>>(); | |
537 | if parts.len() != 2 { return false; } | |
538 | let crate_name = parts[0].to_string(); | |
539 | let fuel = parts[1].parse::<u64>(); | |
540 | if fuel.is_err() { return false; } | |
541 | *slot = Some((crate_name, fuel.unwrap())); | |
542 | true | |
543 | } | |
544 | } | |
545 | } | |
546 | ||
547 | fn parse_unpretty(slot: &mut Option<String>, v: Option<&str>) -> bool { | |
548 | match v { | |
549 | None => false, | |
550 | Some(s) if s.split('=').count() <= 2 => { | |
551 | *slot = Some(s.to_string()); | |
552 | true | |
553 | } | |
554 | _ => false, | |
555 | } | |
556 | } | |
557 | ||
1b1a35ee XL |
558 | fn parse_mir_spanview(slot: &mut Option<MirSpanview>, v: Option<&str>) -> bool { |
559 | if v.is_some() { | |
560 | let mut bool_arg = None; | |
561 | if parse_opt_bool(&mut bool_arg, v) { | |
562 | *slot = if bool_arg.unwrap() { | |
563 | Some(MirSpanview::Statement) | |
564 | } else { | |
565 | None | |
566 | }; | |
567 | return true | |
568 | } | |
569 | } | |
570 | ||
571 | let v = match v { | |
572 | None => { | |
573 | *slot = Some(MirSpanview::Statement); | |
574 | return true; | |
575 | } | |
576 | Some(v) => v, | |
577 | }; | |
578 | ||
579 | *slot = Some(match v.trim_end_matches("s") { | |
580 | "statement" | "stmt" => MirSpanview::Statement, | |
581 | "terminator" | "term" => MirSpanview::Terminator, | |
582 | "block" | "basicblock" => MirSpanview::Block, | |
583 | _ => return false, | |
584 | }); | |
585 | true | |
586 | } | |
587 | ||
dfeec247 XL |
588 | fn parse_treat_err_as_bug(slot: &mut Option<usize>, v: Option<&str>) -> bool { |
589 | match v { | |
590 | Some(s) => { *slot = s.parse().ok().filter(|&x| x != 0); slot.unwrap_or(0) != 0 } | |
591 | None => { *slot = Some(1); true } | |
592 | } | |
593 | } | |
594 | ||
595 | fn parse_lto(slot: &mut LtoCli, v: Option<&str>) -> bool { | |
596 | if v.is_some() { | |
597 | let mut bool_arg = None; | |
598 | if parse_opt_bool(&mut bool_arg, v) { | |
599 | *slot = if bool_arg.unwrap() { | |
600 | LtoCli::Yes | |
601 | } else { | |
602 | LtoCli::No | |
603 | }; | |
604 | return true | |
605 | } | |
606 | } | |
607 | ||
608 | *slot = match v { | |
609 | None => LtoCli::NoParam, | |
610 | Some("thin") => LtoCli::Thin, | |
611 | Some("fat") => LtoCli::Fat, | |
612 | Some(_) => return false, | |
613 | }; | |
614 | true | |
615 | } | |
616 | ||
617 | fn parse_linker_plugin_lto(slot: &mut LinkerPluginLto, v: Option<&str>) -> bool { | |
618 | if v.is_some() { | |
619 | let mut bool_arg = None; | |
620 | if parse_opt_bool(&mut bool_arg, v) { | |
621 | *slot = if bool_arg.unwrap() { | |
622 | LinkerPluginLto::LinkerPluginAuto | |
623 | } else { | |
624 | LinkerPluginLto::Disabled | |
625 | }; | |
626 | return true | |
627 | } | |
628 | } | |
629 | ||
630 | *slot = match v { | |
631 | None => LinkerPluginLto::LinkerPluginAuto, | |
632 | Some(path) => LinkerPluginLto::LinkerPlugin(PathBuf::from(path)), | |
633 | }; | |
634 | true | |
635 | } | |
636 | ||
637 | fn parse_switch_with_opt_path(slot: &mut SwitchWithOptPath, v: Option<&str>) -> bool { | |
638 | *slot = match v { | |
639 | None => SwitchWithOptPath::Enabled(None), | |
640 | Some(path) => SwitchWithOptPath::Enabled(Some(PathBuf::from(path))), | |
641 | }; | |
642 | true | |
643 | } | |
644 | ||
645 | fn parse_merge_functions(slot: &mut Option<MergeFunctions>, v: Option<&str>) -> bool { | |
646 | match v.and_then(|s| MergeFunctions::from_str(s).ok()) { | |
647 | Some(mergefunc) => *slot = Some(mergefunc), | |
648 | _ => return false, | |
649 | } | |
650 | true | |
651 | } | |
652 | ||
f9f354fc XL |
653 | fn parse_relocation_model(slot: &mut Option<RelocModel>, v: Option<&str>) -> bool { |
654 | match v.and_then(|s| RelocModel::from_str(s).ok()) { | |
655 | Some(relocation_model) => *slot = Some(relocation_model), | |
656 | None if v == Some("default") => *slot = None, | |
657 | _ => return false, | |
658 | } | |
659 | true | |
660 | } | |
661 | ||
662 | fn parse_code_model(slot: &mut Option<CodeModel>, v: Option<&str>) -> bool { | |
663 | match v.and_then(|s| CodeModel::from_str(s).ok()) { | |
664 | Some(code_model) => *slot = Some(code_model), | |
665 | _ => return false, | |
666 | } | |
667 | true | |
668 | } | |
669 | ||
670 | fn parse_tls_model(slot: &mut Option<TlsModel>, v: Option<&str>) -> bool { | |
671 | match v.and_then(|s| TlsModel::from_str(s).ok()) { | |
672 | Some(tls_model) => *slot = Some(tls_model), | |
673 | _ => return false, | |
674 | } | |
675 | true | |
676 | } | |
677 | ||
dfeec247 XL |
678 | fn parse_symbol_mangling_version( |
679 | slot: &mut SymbolManglingVersion, | |
680 | v: Option<&str>, | |
681 | ) -> bool { | |
682 | *slot = match v { | |
683 | Some("legacy") => SymbolManglingVersion::Legacy, | |
684 | Some("v0") => SymbolManglingVersion::V0, | |
685 | _ => return false, | |
686 | }; | |
687 | true | |
688 | } | |
ba9703b0 XL |
689 | |
690 | fn parse_src_file_hash(slot: &mut Option<SourceFileHashAlgorithm>, v: Option<&str>) -> bool { | |
691 | match v.and_then(|s| SourceFileHashAlgorithm::from_str(s).ok()) { | |
692 | Some(hash_kind) => *slot = Some(hash_kind), | |
693 | _ => return false, | |
694 | } | |
695 | true | |
696 | } | |
f9f354fc XL |
697 | |
698 | fn parse_target_feature(slot: &mut String, v: Option<&str>) -> bool { | |
699 | match v { | |
700 | Some(s) => { | |
701 | if !slot.is_empty() { | |
702 | slot.push_str(","); | |
703 | } | |
704 | slot.push_str(s); | |
705 | true | |
706 | } | |
707 | None => false, | |
708 | } | |
709 | } | |
dfeec247 XL |
710 | } |
711 | ) } | |
712 | ||
713 | options! {CodegenOptions, CodegenSetter, basic_codegen_options, | |
714 | build_codegen_options, "C", "codegen", | |
715 | CG_OPTIONS, cg_type_desc, cgsetters, | |
f9f354fc XL |
716 | |
717 | // This list is in alphabetical order. | |
718 | // | |
719 | // If you add a new option, please update: | |
29967ef6 | 720 | // - compiler/rustc_interface/src/tests.rs |
f9f354fc XL |
721 | // - src/doc/rustc/src/codegen-options/index.md |
722 | ||
ba9703b0 | 723 | ar: String = (String::new(), parse_string, [UNTRACKED], |
dfeec247 | 724 | "this option is deprecated and does nothing"), |
f9f354fc XL |
725 | code_model: Option<CodeModel> = (None, parse_code_model, [TRACKED], |
726 | "choose the code model to use (`rustc --print code-models` for details)"), | |
727 | codegen_units: Option<usize> = (None, parse_opt_uint, [UNTRACKED], | |
728 | "divide crate into N units to optimize in parallel"), | |
3dfed10e XL |
729 | control_flow_guard: CFGuard = (CFGuard::Disabled, parse_cfguard, [TRACKED], |
730 | "use Windows Control Flow Guard (default: no)"), | |
f9f354fc XL |
731 | debug_assertions: Option<bool> = (None, parse_opt_bool, [TRACKED], |
732 | "explicitly enable the `cfg(debug_assertions)` directive"), | |
733 | debuginfo: usize = (0, parse_uint, [TRACKED], | |
734 | "debug info emission level (0 = no debug info, 1 = line tables only, \ | |
735 | 2 = full debug info with variable and type information; default: 0)"), | |
736 | default_linker_libraries: bool = (false, parse_bool, [UNTRACKED], | |
737 | "allow the linker to link its default libraries (default: no)"), | |
738 | embed_bitcode: bool = (true, parse_bool, [TRACKED], | |
739 | "emit bitcode in rlibs (default: yes)"), | |
740 | extra_filename: String = (String::new(), parse_string, [UNTRACKED], | |
741 | "extra data to put in each output filename"), | |
742 | force_frame_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED], | |
743 | "force use of the frame pointers"), | |
744 | force_unwind_tables: Option<bool> = (None, parse_opt_bool, [TRACKED], | |
745 | "force use of unwind tables"), | |
746 | incremental: Option<String> = (None, parse_opt_string, [UNTRACKED], | |
747 | "enable incremental compilation"), | |
748 | inline_threshold: Option<usize> = (None, parse_opt_uint, [TRACKED], | |
749 | "set the threshold for inlining a function"), | |
ba9703b0 | 750 | link_arg: (/* redirected to link_args */) = ((), parse_string_push, [UNTRACKED], |
dfeec247 | 751 | "a single extra argument to append to the linker invocation (can be used several times)"), |
ba9703b0 | 752 | link_args: Vec<String> = (Vec::new(), parse_list, [UNTRACKED], |
dfeec247 | 753 | "extra arguments to append to the linker invocation (space separated)"), |
3dfed10e | 754 | link_dead_code: Option<bool> = (None, parse_opt_bool, [UNTRACKED], |
ba9703b0 | 755 | "keep dead code at link time (useful for code coverage) (default: no)"), |
1b1a35ee XL |
756 | link_self_contained: Option<bool> = (None, parse_opt_bool, [UNTRACKED], |
757 | "control whether to link Rust provided C objects/libraries or rely | |
758 | on C toolchain installed in the system"), | |
f9f354fc XL |
759 | linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED], |
760 | "system linker to link outputs with"), | |
761 | linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED], | |
762 | "linker flavor"), | |
763 | linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled, | |
764 | parse_linker_plugin_lto, [TRACKED], | |
765 | "generate build artifacts that are compatible with linker-based LTO"), | |
dfeec247 XL |
766 | llvm_args: Vec<String> = (Vec::new(), parse_list, [TRACKED], |
767 | "a list of arguments to pass to LLVM (space separated)"), | |
f9f354fc XL |
768 | lto: LtoCli = (LtoCli::Unspecified, parse_lto, [TRACKED], |
769 | "perform LLVM link-time optimizations"), | |
770 | metadata: Vec<String> = (Vec::new(), parse_list, [TRACKED], | |
771 | "metadata to mangle symbol names with"), | |
ba9703b0 XL |
772 | no_prepopulate_passes: bool = (false, parse_no_flag, [TRACKED], |
773 | "give an empty list of passes to the pass manager"), | |
dfeec247 XL |
774 | no_redzone: Option<bool> = (None, parse_opt_bool, [TRACKED], |
775 | "disable the use of the redzone"), | |
ba9703b0 XL |
776 | no_stack_check: bool = (false, parse_no_flag, [UNTRACKED], |
777 | "this option is deprecated and does nothing"), | |
f9f354fc XL |
778 | no_vectorize_loops: bool = (false, parse_no_flag, [TRACKED], |
779 | "disable loop vectorization optimization passes"), | |
780 | no_vectorize_slp: bool = (false, parse_no_flag, [TRACKED], | |
781 | "disable LLVM's SLP vectorization pass"), | |
ba9703b0 XL |
782 | opt_level: String = ("0".to_string(), parse_string, [TRACKED], |
783 | "optimization level (0-3, s, or z; default: 0)"), | |
f9f354fc XL |
784 | overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED], |
785 | "use overflow checks for integer arithmetic"), | |
786 | panic: Option<PanicStrategy> = (None, parse_panic_strategy, [TRACKED], | |
787 | "panic strategy to compile crate with"), | |
788 | passes: Vec<String> = (Vec::new(), parse_list, [TRACKED], | |
789 | "a list of extra LLVM passes to run (space separated)"), | |
790 | prefer_dynamic: bool = (false, parse_bool, [TRACKED], | |
791 | "prefer dynamic linking to static linking (default: no)"), | |
dfeec247 XL |
792 | profile_generate: SwitchWithOptPath = (SwitchWithOptPath::Disabled, |
793 | parse_switch_with_opt_path, [TRACKED], | |
794 | "compile the program with profiling instrumentation"), | |
795 | profile_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED], | |
796 | "use the given `.profdata` file for profile-guided optimization"), | |
f9f354fc XL |
797 | relocation_model: Option<RelocModel> = (None, parse_relocation_model, [TRACKED], |
798 | "control generation of position-independent code (PIC) \ | |
799 | (`rustc --print relocation-models` for details)"), | |
800 | remark: Passes = (Passes::Some(Vec::new()), parse_passes, [UNTRACKED], | |
801 | "print remarks for these optimization passes (space separated, or \"all\")"), | |
802 | rpath: bool = (false, parse_bool, [UNTRACKED], | |
803 | "set rpath values in libs/exes (default: no)"), | |
804 | save_temps: bool = (false, parse_bool, [UNTRACKED], | |
805 | "save all temporary output files during compilation (default: no)"), | |
806 | soft_float: bool = (false, parse_bool, [TRACKED], | |
807 | "use soft float ABI (*eabihf targets only) (default: no)"), | |
808 | target_cpu: Option<String> = (None, parse_opt_string, [TRACKED], | |
809 | "select target processor (`rustc --print target-cpus` for details)"), | |
810 | target_feature: String = (String::new(), parse_target_feature, [TRACKED], | |
811 | "target specific attributes. (`rustc --print target-features` for details). \ | |
812 | This feature is unsafe."), | |
813 | ||
814 | // This list is in alphabetical order. | |
815 | // | |
816 | // If you add a new option, please update: | |
29967ef6 | 817 | // - compiler/rustc_interface/src/tests.rs |
f9f354fc | 818 | // - src/doc/rustc/src/codegen-options/index.md |
dfeec247 XL |
819 | } |
820 | ||
821 | options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, | |
822 | build_debugging_options, "Z", "debugging", | |
823 | DB_OPTIONS, db_type_desc, dbsetters, | |
f9f354fc XL |
824 | |
825 | // This list is in alphabetical order. | |
826 | // | |
827 | // If you add a new option, please update: | |
29967ef6 | 828 | // - compiler/rustc_interface/src/tests.rs |
f9f354fc XL |
829 | |
830 | allow_features: Option<Vec<String>> = (None, parse_opt_comma_list, [TRACKED], | |
831 | "only allow the listed language features to be enabled in code (space separated)"), | |
832 | always_encode_mir: bool = (false, parse_bool, [TRACKED], | |
833 | "encode MIR of all functions into the crate metadata (default: no)"), | |
dfeec247 | 834 | asm_comments: bool = (false, parse_bool, [TRACKED], |
ba9703b0 | 835 | "generate comments into the assembly (may change behavior) (default: no)"), |
dfeec247 | 836 | ast_json: bool = (false, parse_bool, [UNTRACKED], |
ba9703b0 | 837 | "print the AST as JSON and halt (default: no)"), |
dfeec247 | 838 | ast_json_noexpand: bool = (false, parse_bool, [UNTRACKED], |
ba9703b0 | 839 | "print the pre-expansion AST as JSON and halt (default: no)"), |
f9f354fc XL |
840 | binary_dep_depinfo: bool = (false, parse_bool, [TRACKED], |
841 | "include artifacts (sysroot, crate dependencies) used during compilation in dep-info \ | |
842 | (default: no)"), | |
843 | borrowck: String = ("migrate".to_string(), parse_string, [UNTRACKED], | |
844 | "select which borrowck is used (`mir` or `migrate`) (default: `migrate`)"), | |
845 | borrowck_stats: bool = (false, parse_bool, [UNTRACKED], | |
846 | "gather borrowck statistics (default: no)"), | |
3dfed10e XL |
847 | cgu_partitioning_strategy: Option<String> = (None, parse_opt_string, [TRACKED], |
848 | "the codegen unit partitioning strategy to use"), | |
f9f354fc XL |
849 | chalk: bool = (false, parse_bool, [TRACKED], |
850 | "enable the experimental Chalk-based trait solving engine"), | |
851 | codegen_backend: Option<String> = (None, parse_opt_string, [TRACKED], | |
852 | "the backend to use"), | |
1b1a35ee XL |
853 | combine_cgu: bool = (false, parse_bool, [TRACKED], |
854 | "combine CGUs into a single one"), | |
f9f354fc XL |
855 | crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED], |
856 | "inject the given attribute in the crate"), | |
857 | debug_macros: bool = (false, parse_bool, [TRACKED], | |
858 | "emit line numbers debug info inside macros (default: no)"), | |
859 | deduplicate_diagnostics: bool = (true, parse_bool, [UNTRACKED], | |
860 | "deduplicate identical diagnostics (default: yes)"), | |
861 | dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED], | |
862 | "in dep-info output, omit targets for tracking dependencies of the dep-info files \ | |
863 | themselves (default: no)"), | |
dfeec247 | 864 | dep_tasks: bool = (false, parse_bool, [UNTRACKED], |
ba9703b0 XL |
865 | "print tasks that execute and the color their dep node gets (requires debug build) \ |
866 | (default: no)"), | |
f9f354fc XL |
867 | dont_buffer_diagnostics: bool = (false, parse_bool, [UNTRACKED], |
868 | "emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) \ | |
ba9703b0 | 869 | (default: no)"), |
f9f354fc XL |
870 | dual_proc_macros: bool = (false, parse_bool, [TRACKED], |
871 | "load proc macros for both target and host, but only link to the target (default: no)"), | |
dfeec247 | 872 | dump_dep_graph: bool = (false, parse_bool, [UNTRACKED], |
ba9703b0 XL |
873 | "dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) \ |
874 | (default: no)"), | |
dfeec247 XL |
875 | dump_mir: Option<String> = (None, parse_opt_string, [UNTRACKED], |
876 | "dump MIR state to file. | |
877 | `val` is used to select which passes and functions to dump. For example: | |
878 | `all` matches all passes and functions, | |
879 | `foo` matches all passes for functions whose name contains 'foo', | |
880 | `foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo', | |
881 | `foo | bar` all passes for function names containing 'foo' or 'bar'."), | |
f9f354fc XL |
882 | dump_mir_dataflow: bool = (false, parse_bool, [UNTRACKED], |
883 | "in addition to `.mir` files, create graphviz `.dot` files with dataflow results \ | |
884 | (default: no)"), | |
ba9703b0 XL |
885 | dump_mir_dir: String = ("mir_dump".to_string(), parse_string, [UNTRACKED], |
886 | "the directory the MIR is dumped into (default: `mir_dump`)"), | |
dfeec247 | 887 | dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED], |
ba9703b0 | 888 | "exclude the pass number when dumping MIR (used in tests) (default: no)"), |
f9f354fc | 889 | dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED], |
29967ef6 XL |
890 | "in addition to `.mir` files, create graphviz `.dot` files (and with \ |
891 | `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived \ | |
892 | coverage graph) (default: no)"), | |
1b1a35ee XL |
893 | dump_mir_spanview: Option<MirSpanview> = (None, parse_mir_spanview, [UNTRACKED], |
894 | "in addition to `.mir` files, create `.html` files to view spans for \ | |
895 | all `statement`s (including terminators), only `terminator` spans, or \ | |
896 | computed `block` spans (one span encompassing a block's terminator and \ | |
29967ef6 XL |
897 | all statements). If `-Z instrument-coverage` is also enabled, create \ |
898 | an additional `.html` file showing the computed coverage spans."), | |
899 | emit_future_incompat_report: bool = (false, parse_bool, [UNTRACKED], | |
900 | "emits a future-incompatibility report for lints (RFC 2834)"), | |
f9f354fc XL |
901 | emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED], |
902 | "emit a section containing stack size metadata (default: no)"), | |
903 | fewer_names: bool = (false, parse_bool, [TRACKED], | |
904 | "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \ | |
ba9703b0 | 905 | (default: no)"), |
f9f354fc XL |
906 | force_overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED], |
907 | "force overflow checks on or off"), | |
908 | force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED], | |
909 | "force all crates to be `rustc_private` unstable (default: no)"), | |
910 | fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED], | |
911 | "set the optimization fuel quota for a crate"), | |
29967ef6 XL |
912 | function_sections: Option<bool> = (None, parse_opt_bool, [TRACKED], |
913 | "whether each function should go in its own section"), | |
1b1a35ee XL |
914 | graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED], |
915 | "use dark-themed colors in graphviz output (default: no)"), | |
916 | graphviz_font: String = ("Courier, monospace".to_string(), parse_string, [UNTRACKED], | |
917 | "use the given `fontname` in graphviz output; can be overridden by setting \ | |
918 | environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"), | |
dfeec247 | 919 | hir_stats: bool = (false, parse_bool, [UNTRACKED], |
ba9703b0 | 920 | "print some statistics about AST and HIR (default: no)"), |
f9f354fc XL |
921 | human_readable_cgu_names: bool = (false, parse_bool, [TRACKED], |
922 | "generate human-readable, predictable names for codegen units (default: no)"), | |
923 | identify_regions: bool = (false, parse_bool, [UNTRACKED], | |
924 | "display unnamed regions as `'<id>`, using a non-ident unique id (default: no)"), | |
925 | incremental_ignore_spans: bool = (false, parse_bool, [UNTRACKED], | |
926 | "ignore spans during ICH computation -- used for testing (default: no)"), | |
927 | incremental_info: bool = (false, parse_bool, [UNTRACKED], | |
928 | "print high-level information about incremental reuse (or the lack thereof) \ | |
929 | (default: no)"), | |
930 | incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED], | |
931 | "verify incr. comp. hashes of green query instances (default: no)"), | |
29967ef6 XL |
932 | inline_mir_threshold: usize = (50, parse_uint, [TRACKED], |
933 | "a default MIR inlining threshold (default: 50)"), | |
934 | inline_mir_hint_threshold: usize = (100, parse_uint, [TRACKED], | |
935 | "inlining threshold for functions with inline hint (default: 100)"), | |
f9f354fc XL |
936 | inline_in_all_cgus: Option<bool> = (None, parse_opt_bool, [TRACKED], |
937 | "control whether `#[inline]` functions are in all CGUs"), | |
938 | input_stats: bool = (false, parse_bool, [UNTRACKED], | |
939 | "gather statistics about the input (default: no)"), | |
940 | insert_sideeffect: bool = (false, parse_bool, [TRACKED], | |
941 | "fix undefined behavior when a thread doesn't eventually make progress \ | |
942 | (such as entering an empty infinite loop) by inserting llvm.sideeffect \ | |
943 | (default: no)"), | |
f035d41b | 944 | instrument_coverage: bool = (false, parse_bool, [TRACKED], |
3dfed10e XL |
945 | "instrument the generated code to support LLVM source-based code coverage \ |
946 | reports (note, the compiler build config must include `profiler = true`, \ | |
947 | and is mutually exclusive with `-C profile-generate`/`-C profile-use`); \ | |
1b1a35ee XL |
948 | implies `-C link-dead-code` (unless targeting MSVC, or explicitly disabled) \ |
949 | and `-Z symbol-mangling-version=v0`; disables/overrides some Rust \ | |
950 | optimizations (default: no)"), | |
f9f354fc XL |
951 | instrument_mcount: bool = (false, parse_bool, [TRACKED], |
952 | "insert function instrument code for mcount-based tracing (default: no)"), | |
953 | keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED], | |
954 | "keep hygiene data after analysis (default: no)"), | |
955 | link_native_libraries: bool = (true, parse_bool, [UNTRACKED], | |
956 | "link native libraries in the linker invocation (default: yes)"), | |
957 | link_only: bool = (false, parse_bool, [TRACKED], | |
958 | "link the `.rlink` file generated by `-Z no-link` (default: no)"), | |
959 | llvm_time_trace: bool = (false, parse_bool, [UNTRACKED], | |
960 | "generate JSON tracing data file from LLVM data (default: no)"), | |
961 | ls: bool = (false, parse_bool, [UNTRACKED], | |
962 | "list the symbols defined by a library crate (default: no)"), | |
963 | macro_backtrace: bool = (false, parse_bool, [UNTRACKED], | |
964 | "show macro backtraces (default: no)"), | |
965 | merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED], | |
966 | "control the operation of the MergeFunctions LLVM pass, taking \ | |
967 | the same values as the target option of the same name"), | |
968 | meta_stats: bool = (false, parse_bool, [UNTRACKED], | |
969 | "gather metadata statistics (default: no)"), | |
970 | mir_emit_retag: bool = (false, parse_bool, [TRACKED], | |
971 | "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \ | |
972 | (default: no)"), | |
973 | mir_opt_level: usize = (1, parse_uint, [TRACKED], | |
974 | "MIR optimization level (0-3; default: 1)"), | |
975 | mutable_noalias: bool = (false, parse_bool, [TRACKED], | |
976 | "emit noalias metadata for mutable references (default: no)"), | |
977 | new_llvm_pass_manager: bool = (false, parse_bool, [TRACKED], | |
978 | "use new LLVM pass manager (default: no)"), | |
979 | nll_facts: bool = (false, parse_bool, [UNTRACKED], | |
980 | "dump facts from NLL analysis into side files (default: no)"), | |
29967ef6 XL |
981 | nll_facts_dir: String = ("nll-facts".to_string(), parse_string, [UNTRACKED], |
982 | "the directory the NLL facts are dumped into (default: `nll-facts`)"), | |
f9f354fc XL |
983 | no_analysis: bool = (false, parse_no_flag, [UNTRACKED], |
984 | "parse and expand the source, but run no analysis"), | |
985 | no_codegen: bool = (false, parse_no_flag, [TRACKED], | |
986 | "run all passes except codegen; no output"), | |
987 | no_generate_arange_section: bool = (false, parse_no_flag, [TRACKED], | |
988 | "omit DWARF address ranges that give faster lookups"), | |
989 | no_interleave_lints: bool = (false, parse_no_flag, [UNTRACKED], | |
990 | "execute lints separately; allows benchmarking individual lints"), | |
991 | no_leak_check: bool = (false, parse_no_flag, [UNTRACKED], | |
992 | "disable the 'leak check' for subtyping; unsound, but useful for tests"), | |
993 | no_link: bool = (false, parse_no_flag, [TRACKED], | |
994 | "compile without linking"), | |
995 | no_parallel_llvm: bool = (false, parse_no_flag, [UNTRACKED], | |
996 | "run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"), | |
997 | no_profiler_runtime: bool = (false, parse_no_flag, [TRACKED], | |
998 | "prevent automatic injection of the profiler_builtins crate"), | |
dfeec247 | 999 | osx_rpath_install_name: bool = (false, parse_bool, [TRACKED], |
ba9703b0 | 1000 | "pass `-install_name @rpath/...` to the macOS linker (default: no)"), |
f9f354fc XL |
1001 | panic_abort_tests: bool = (false, parse_bool, [TRACKED], |
1002 | "support compiling tests with panic=abort (default: no)"), | |
1003 | parse_only: bool = (false, parse_bool, [UNTRACKED], | |
1004 | "parse only; do not compile, assemble, or link (default: no)"), | |
1005 | perf_stats: bool = (false, parse_bool, [UNTRACKED], | |
1006 | "print some performance-related statistics (default: no)"), | |
1007 | plt: Option<bool> = (None, parse_opt_bool, [TRACKED], | |
1008 | "whether to use the PLT when calling into shared libraries; | |
1009 | only has effect for PIC code on systems with ELF binaries | |
1010 | (default: PLT is disabled if full relro is enabled)"), | |
1011 | polonius: bool = (false, parse_bool, [UNTRACKED], | |
1012 | "enable polonius-based borrow-checker (default: no)"), | |
3dfed10e XL |
1013 | polymorphize: bool = (false, parse_bool, [TRACKED], |
1014 | "perform polymorphization analysis"), | |
ba9703b0 | 1015 | pre_link_arg: (/* redirected to pre_link_args */) = ((), parse_string_push, [UNTRACKED], |
dfeec247 | 1016 | "a single extra argument to prepend the linker invocation (can be used several times)"), |
ba9703b0 | 1017 | pre_link_args: Vec<String> = (Vec::new(), parse_list, [UNTRACKED], |
dfeec247 | 1018 | "extra arguments to prepend to the linker invocation (space separated)"), |
1b1a35ee XL |
1019 | precise_enum_drop_elaboration: bool = (true, parse_bool, [TRACKED], |
1020 | "use a more precise version of drop elaboration for matches on enums (default: yes). \ | |
1021 | This results in better codegen, but has caused miscompilations on some tier 2 platforms. \ | |
1022 | See #77382 and #74551."), | |
f9f354fc XL |
1023 | print_fuel: Option<String> = (None, parse_opt_string, [TRACKED], |
1024 | "make rustc print the total optimization fuel used by a crate"), | |
1025 | print_link_args: bool = (false, parse_bool, [UNTRACKED], | |
1026 | "print the arguments passed to the linker (default: no)"), | |
1027 | print_llvm_passes: bool = (false, parse_bool, [UNTRACKED], | |
1028 | "print the LLVM optimization passes being run (default: no)"), | |
1029 | print_mono_items: Option<String> = (None, parse_opt_string, [UNTRACKED], | |
1030 | "print the result of the monomorphization collection pass"), | |
f9f354fc XL |
1031 | print_type_sizes: bool = (false, parse_bool, [UNTRACKED], |
1032 | "print layout information for each type encountered (default: no)"), | |
1b1a35ee XL |
1033 | proc_macro_backtrace: bool = (false, parse_bool, [UNTRACKED], |
1034 | "show backtraces for panics during proc-macro execution (default: no)"), | |
dfeec247 | 1035 | profile: bool = (false, parse_bool, [TRACKED], |
ba9703b0 | 1036 | "insert profiling code (default: no)"), |
f9f354fc XL |
1037 | profile_emit: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED], |
1038 | "file path to emit profiling data at runtime when using 'profile' \ | |
1039 | (default based on relative source path)"), | |
1040 | query_dep_graph: bool = (false, parse_bool, [UNTRACKED], | |
1041 | "enable queries of the dependency graph for regression testing (default: no)"), | |
1042 | query_stats: bool = (false, parse_bool, [UNTRACKED], | |
1043 | "print some statistics about the query system (default: no)"), | |
29967ef6 XL |
1044 | relax_elf_relocations: Option<bool> = (None, parse_opt_bool, [TRACKED], |
1045 | "whether ELF relocations can be relaxed"), | |
dfeec247 XL |
1046 | relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED], |
1047 | "choose which RELRO level to use"), | |
f9f354fc XL |
1048 | report_delayed_bugs: bool = (false, parse_bool, [TRACKED], |
1049 | "immediately print bugs registered with `delay_span_bug` (default: no)"), | |
ba9703b0 XL |
1050 | // The default historical behavior was to always run dsymutil, so we're |
1051 | // preserving that temporarily, but we're likely to switch the default | |
1052 | // soon. | |
1053 | run_dsymutil: bool = (true, parse_bool, [TRACKED], | |
1054 | "if on Mac, run `dsymutil` and delete intermediate object files (default: yes)"), | |
f035d41b | 1055 | sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED], |
f9f354fc XL |
1056 | "use a sanitizer"), |
1057 | sanitizer_memory_track_origins: usize = (0, parse_sanitizer_memory_track_origins, [TRACKED], | |
1058 | "enable origins tracking in MemorySanitizer"), | |
f035d41b | 1059 | sanitizer_recover: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED], |
f9f354fc XL |
1060 | "enable recovery for selected sanitizers"), |
1061 | saturating_float_casts: Option<bool> = (None, parse_opt_bool, [TRACKED], | |
1062 | "make float->int casts UB-free: numbers outside the integer type's range are clipped to \ | |
1063 | the max/min integer respectively, and NaN is mapped to 0 (default: yes)"), | |
1064 | save_analysis: bool = (false, parse_bool, [UNTRACKED], | |
1065 | "write syntax and type analysis (in JSON format) information, in \ | |
1066 | addition to normal output (default: no)"), | |
dfeec247 XL |
1067 | self_profile: SwitchWithOptPath = (SwitchWithOptPath::Disabled, |
1068 | parse_switch_with_opt_path, [UNTRACKED], | |
1069 | "run the self profiler and output the raw event data"), | |
1070 | // keep this in sync with the event filter names in librustc_data_structures/profiling.rs | |
1071 | self_profile_events: Option<Vec<String>> = (None, parse_opt_comma_list, [UNTRACKED], | |
ba9703b0 | 1072 | "specify the events recorded by the self profiler; |
dfeec247 XL |
1073 | for example: `-Z self-profile-events=default,query-keys` |
1074 | all options: none, all, default, generic-activity, query-provider, query-cache-hit | |
74b04a01 | 1075 | query-blocked, incr-cache-load, query-keys, function-args, args, llvm"), |
f9f354fc XL |
1076 | share_generics: Option<bool> = (None, parse_opt_bool, [TRACKED], |
1077 | "make the current crate share its generic instantiations"), | |
1078 | show_span: Option<String> = (None, parse_opt_string, [TRACKED], | |
1079 | "show spans for compiler debugging (expr|pat|ty)"), | |
f035d41b XL |
1080 | span_debug: bool = (false, parse_bool, [UNTRACKED], |
1081 | "forward proc_macro::Span's `Debug` impl to `Span`"), | |
f9f354fc XL |
1082 | // o/w tests have closure@path |
1083 | span_free_formats: bool = (false, parse_bool, [UNTRACKED], | |
1084 | "exclude spans when debug-printing compiler state (default: no)"), | |
1085 | src_hash_algorithm: Option<SourceFileHashAlgorithm> = (None, parse_src_file_hash, [TRACKED], | |
29967ef6 | 1086 | "hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"), |
f9f354fc XL |
1087 | strip: Strip = (Strip::None, parse_strip, [UNTRACKED], |
1088 | "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"), | |
dfeec247 XL |
1089 | symbol_mangling_version: SymbolManglingVersion = (SymbolManglingVersion::Legacy, |
1090 | parse_symbol_mangling_version, [TRACKED], | |
1091 | "which mangling version to use for symbol names"), | |
f9f354fc XL |
1092 | teach: bool = (false, parse_bool, [TRACKED], |
1093 | "show extended diagnostic help (default: no)"), | |
1094 | terminal_width: Option<usize> = (None, parse_opt_uint, [UNTRACKED], | |
1095 | "set the current terminal width"), | |
29967ef6 XL |
1096 | tune_cpu: Option<String> = (None, parse_opt_string, [TRACKED], |
1097 | "select processor to schedule for (`rustc --print target-cpus` for details)"), | |
f9f354fc XL |
1098 | thinlto: Option<bool> = (None, parse_opt_bool, [TRACKED], |
1099 | "enable ThinLTO when possible"), | |
1100 | // We default to 1 here since we want to behave like | |
1101 | // a sequential compiler for now. This'll likely be adjusted | |
1102 | // in the future. Note that -Zthreads=0 is the way to get | |
1103 | // the num_cpus behavior. | |
1104 | threads: usize = (1, parse_threads, [UNTRACKED], | |
1105 | "use a thread pool with N threads"), | |
1106 | time: bool = (false, parse_bool, [UNTRACKED], | |
1107 | "measure time of rustc processes (default: no)"), | |
1108 | time_llvm_passes: bool = (false, parse_bool, [UNTRACKED], | |
1109 | "measure time of each LLVM pass (default: no)"), | |
1110 | time_passes: bool = (false, parse_bool, [UNTRACKED], | |
1111 | "measure time of each rustc pass (default: no)"), | |
1112 | tls_model: Option<TlsModel> = (None, parse_tls_model, [TRACKED], | |
1113 | "choose the TLS model to use (`rustc --print tls-models` for details)"), | |
1114 | trace_macros: bool = (false, parse_bool, [UNTRACKED], | |
1115 | "for every macro invocation, print its name and arguments (default: no)"), | |
1116 | treat_err_as_bug: Option<usize> = (None, parse_treat_err_as_bug, [TRACKED], | |
1117 | "treat error number `val` that occurs as bug"), | |
1b1a35ee XL |
1118 | trim_diagnostic_paths: bool = (true, parse_bool, [UNTRACKED], |
1119 | "in diagnostics, use heuristics to shorten paths referring to items"), | |
f9f354fc XL |
1120 | ui_testing: bool = (false, parse_bool, [UNTRACKED], |
1121 | "emit compiler diagnostics in a form suitable for UI testing (default: no)"), | |
1122 | unleash_the_miri_inside_of_you: bool = (false, parse_bool, [TRACKED], | |
1123 | "take the brakes off const evaluation. NOTE: this is unsound (default: no)"), | |
1124 | unpretty: Option<String> = (None, parse_unpretty, [UNTRACKED], | |
1125 | "present the input source, unstable (and less-pretty) variants; | |
1126 | valid types are any of the types for `--pretty`, as well as: | |
1127 | `expanded`, `expanded,identified`, | |
1128 | `expanded,hygiene` (with internal representations), | |
1129 | `everybody_loops` (all function bodies replaced with `loop {}`), | |
1130 | `hir` (the HIR), `hir,identified`, | |
1131 | `hir,typed` (HIR with types for each node), | |
1132 | `hir-tree` (dump the raw HIR), | |
1133 | `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)"), | |
1b1a35ee XL |
1134 | unsound_mir_opts: bool = (false, parse_bool, [TRACKED], |
1135 | "enable unsound and buggy MIR optimizations (default: no)"), | |
f9f354fc XL |
1136 | unstable_options: bool = (false, parse_bool, [UNTRACKED], |
1137 | "adds unstable command line options to rustc interface (default: no)"), | |
1138 | use_ctors_section: Option<bool> = (None, parse_opt_bool, [TRACKED], | |
1139 | "use legacy .ctors section for initializers rather than .init_array"), | |
1140 | validate_mir: bool = (false, parse_bool, [UNTRACKED], | |
1141 | "validate MIR after each transformation"), | |
1142 | verbose: bool = (false, parse_bool, [UNTRACKED], | |
1143 | "in general, enable more debug printouts (default: no)"), | |
1144 | verify_llvm_ir: bool = (false, parse_bool, [TRACKED], | |
1145 | "verify LLVM IR (default: no)"), | |
1146 | ||
1147 | // This list is in alphabetical order. | |
1148 | // | |
1149 | // If you add a new option, please update: | |
1150 | // - src/librustc_interface/tests.rs | |
dfeec247 | 1151 | } |