Merge remote-tracking branch 'origin/master' into frewsxcv-san
This commit is contained in:
commit
d482de30ea
1600 changed files with 29527 additions and 21534 deletions
|
@ -221,6 +221,23 @@ pub enum DebugInfo {
|
|||
Full,
|
||||
}
|
||||
|
||||
/// Some debuginfo requires link-time relocation and some does not. LLVM can partition the debuginfo
|
||||
/// into sections depending on whether or not it requires link-time relocation. Split DWARF
|
||||
/// provides a mechanism which allows the linker to skip the sections which don't require link-time
|
||||
/// relocation - either by putting those sections into DWARF object files, or keeping them in the
|
||||
/// object file in such a way that the linker will skip them.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Hash)]
|
||||
pub enum SplitDwarfKind {
|
||||
/// Disabled.
|
||||
None,
|
||||
/// Sections which do not require relocation are written into the object file but ignored
|
||||
/// by the linker.
|
||||
Single,
|
||||
/// Sections which do not require relocation are written into a DWARF object (`.dwo`) file,
|
||||
/// which is skipped by the linker by virtue of being a different file.
|
||||
Split,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
|
||||
#[derive(Encodable, Decodable)]
|
||||
pub enum OutputType {
|
||||
|
@ -533,6 +550,7 @@ impl_stable_hash_via_hash!(OutputFilenames);
|
|||
|
||||
pub const RLINK_EXT: &str = "rlink";
|
||||
pub const RUST_CGU_EXT: &str = "rcgu";
|
||||
pub const DWARF_OBJECT_EXT: &str = "dwo";
|
||||
|
||||
impl OutputFilenames {
|
||||
pub fn new(
|
||||
|
@ -566,7 +584,12 @@ impl OutputFilenames {
|
|||
self.temp_path_ext(extension, codegen_unit_name)
|
||||
}
|
||||
|
||||
/// Like temp_path, but also supports things where there is no corresponding
|
||||
/// Like `temp_path`, but specifically for dwarf objects.
|
||||
pub fn temp_path_dwo(&self, codegen_unit_name: Option<&str>) -> PathBuf {
|
||||
self.temp_path_ext(DWARF_OBJECT_EXT, codegen_unit_name)
|
||||
}
|
||||
|
||||
/// Like `temp_path`, but also supports things where there is no corresponding
|
||||
/// OutputType, like noopt-bitcode or lto-bitcode.
|
||||
pub fn temp_path_ext(&self, ext: &str, codegen_unit_name: Option<&str>) -> PathBuf {
|
||||
let mut extension = String::new();
|
||||
|
@ -593,6 +616,37 @@ impl OutputFilenames {
|
|||
path.set_extension(extension);
|
||||
path
|
||||
}
|
||||
|
||||
/// Returns the name of the Split DWARF file - this can differ depending on which Split DWARF
|
||||
/// mode is being used, which is the logic that this function is intended to encapsulate.
|
||||
pub fn split_dwarf_filename(
|
||||
&self,
|
||||
split_dwarf_kind: SplitDwarfKind,
|
||||
cgu_name: Option<&str>,
|
||||
) -> Option<PathBuf> {
|
||||
self.split_dwarf_path(split_dwarf_kind, cgu_name)
|
||||
.map(|path| path.strip_prefix(&self.out_directory).unwrap_or(&path).to_path_buf())
|
||||
}
|
||||
|
||||
/// Returns the path for the Split DWARF file - this can differ depending on which Split DWARF
|
||||
/// mode is being used, which is the logic that this function is intended to encapsulate.
|
||||
pub fn split_dwarf_path(
|
||||
&self,
|
||||
split_dwarf_kind: SplitDwarfKind,
|
||||
cgu_name: Option<&str>,
|
||||
) -> Option<PathBuf> {
|
||||
let obj_out = self.temp_path(OutputType::Object, cgu_name);
|
||||
let dwo_out = self.temp_path_dwo(cgu_name);
|
||||
match split_dwarf_kind {
|
||||
SplitDwarfKind::None => None,
|
||||
// Single mode doesn't change how DWARF is emitted, but does add Split DWARF attributes
|
||||
// (pointing at the path which is being determined here). Use the path to the current
|
||||
// object file.
|
||||
SplitDwarfKind::Single => Some(obj_out),
|
||||
// Split mode emits the DWARF into a different file, use that path.
|
||||
SplitDwarfKind::Split => Some(dwo_out),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn host_triple() -> &'static str {
|
||||
|
@ -692,6 +746,10 @@ impl DebuggingOptions {
|
|||
deduplicate_diagnostics: self.deduplicate_diagnostics,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
|
||||
self.symbol_mangling_version.unwrap_or(SymbolManglingVersion::Legacy)
|
||||
}
|
||||
}
|
||||
|
||||
// The type of entry function, so users can have their own entry functions
|
||||
|
@ -1296,8 +1354,10 @@ fn parse_output_types(
|
|||
if !debugging_opts.parse_only {
|
||||
for list in matches.opt_strs("emit") {
|
||||
for output_type in list.split(',') {
|
||||
let mut parts = output_type.splitn(2, '=');
|
||||
let shorthand = parts.next().unwrap();
|
||||
let (shorthand, path) = match output_type.split_once('=') {
|
||||
None => (output_type, None),
|
||||
Some((shorthand, path)) => (shorthand, Some(PathBuf::from(path))),
|
||||
};
|
||||
let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
|
||||
early_error(
|
||||
error_format,
|
||||
|
@ -1308,7 +1368,6 @@ fn parse_output_types(
|
|||
),
|
||||
)
|
||||
});
|
||||
let path = parts.next().map(PathBuf::from);
|
||||
output_types.insert(output_type, path);
|
||||
}
|
||||
}
|
||||
|
@ -1432,7 +1491,7 @@ fn parse_target_triple(matches: &getopts::Matches, error_format: ErrorOutputType
|
|||
early_error(error_format, &format!("target file {:?} does not exist", path))
|
||||
})
|
||||
}
|
||||
Some(target) => TargetTriple::TargetTriple(target),
|
||||
Some(target) => TargetTriple::from_alias(target),
|
||||
_ => TargetTriple::from_triple(host_triple()),
|
||||
}
|
||||
}
|
||||
|
@ -1452,11 +1511,10 @@ fn parse_opt_level(
|
|||
let max_c = matches
|
||||
.opt_strs_pos("C")
|
||||
.into_iter()
|
||||
.flat_map(
|
||||
|(i, s)| {
|
||||
if let Some("opt-level") = s.splitn(2, '=').next() { Some(i) } else { None }
|
||||
},
|
||||
)
|
||||
.flat_map(|(i, s)| {
|
||||
// NB: This can match a string without `=`.
|
||||
if let Some("opt-level") = s.splitn(2, '=').next() { Some(i) } else { None }
|
||||
})
|
||||
.max();
|
||||
if max_o > max_c {
|
||||
OptLevel::Default
|
||||
|
@ -1491,11 +1549,10 @@ fn select_debuginfo(
|
|||
let max_c = matches
|
||||
.opt_strs_pos("C")
|
||||
.into_iter()
|
||||
.flat_map(
|
||||
|(i, s)| {
|
||||
if let Some("debuginfo") = s.splitn(2, '=').next() { Some(i) } else { None }
|
||||
},
|
||||
)
|
||||
.flat_map(|(i, s)| {
|
||||
// NB: This can match a string without `=`.
|
||||
if let Some("debuginfo") = s.splitn(2, '=').next() { Some(i) } else { None }
|
||||
})
|
||||
.max();
|
||||
if max_g > max_c {
|
||||
DebugInfo::Full
|
||||
|
@ -1528,23 +1585,26 @@ fn parse_libs(
|
|||
.map(|s| {
|
||||
// Parse string of the form "[KIND=]lib[:new_name]",
|
||||
// where KIND is one of "dylib", "framework", "static".
|
||||
let mut parts = s.splitn(2, '=');
|
||||
let kind = parts.next().unwrap();
|
||||
let (name, kind) = match (parts.next(), kind) {
|
||||
(None, name) => (name, NativeLibKind::Unspecified),
|
||||
(Some(name), "dylib") => (name, NativeLibKind::Dylib),
|
||||
(Some(name), "framework") => (name, NativeLibKind::Framework),
|
||||
(Some(name), "static") => (name, NativeLibKind::StaticBundle),
|
||||
(Some(name), "static-nobundle") => (name, NativeLibKind::StaticNoBundle),
|
||||
(_, s) => {
|
||||
early_error(
|
||||
error_format,
|
||||
&format!(
|
||||
"unknown library kind `{}`, expected \
|
||||
one of dylib, framework, or static",
|
||||
s
|
||||
),
|
||||
);
|
||||
let (name, kind) = match s.split_once('=') {
|
||||
None => (s, NativeLibKind::Unspecified),
|
||||
Some((kind, name)) => {
|
||||
let kind = match kind {
|
||||
"dylib" => NativeLibKind::Dylib,
|
||||
"framework" => NativeLibKind::Framework,
|
||||
"static" => NativeLibKind::StaticBundle,
|
||||
"static-nobundle" => NativeLibKind::StaticNoBundle,
|
||||
s => {
|
||||
early_error(
|
||||
error_format,
|
||||
&format!(
|
||||
"unknown library kind `{}`, expected \
|
||||
one of dylib, framework, or static",
|
||||
s
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
(name.to_string(), kind)
|
||||
}
|
||||
};
|
||||
if kind == NativeLibKind::StaticNoBundle
|
||||
|
@ -1556,10 +1616,11 @@ fn parse_libs(
|
|||
accepted on the nightly compiler",
|
||||
);
|
||||
}
|
||||
let mut name_parts = name.splitn(2, ':');
|
||||
let name = name_parts.next().unwrap();
|
||||
let new_name = name_parts.next();
|
||||
(name.to_owned(), new_name.map(|n| n.to_owned()), kind)
|
||||
let (name, new_name) = match name.split_once(':') {
|
||||
None => (name, None),
|
||||
Some((name, new_name)) => (name.to_string(), Some(new_name.to_owned())),
|
||||
};
|
||||
(name, new_name, kind)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
@ -1580,20 +1641,13 @@ pub fn parse_externs(
|
|||
let is_unstable_enabled = debugging_opts.unstable_options;
|
||||
let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
|
||||
for arg in matches.opt_strs("extern") {
|
||||
let mut parts = arg.splitn(2, '=');
|
||||
let name = parts
|
||||
.next()
|
||||
.unwrap_or_else(|| early_error(error_format, "--extern value must not be empty"));
|
||||
let path = parts.next().map(|s| s.to_string());
|
||||
|
||||
let mut name_parts = name.splitn(2, ':');
|
||||
let first_part = name_parts.next();
|
||||
let second_part = name_parts.next();
|
||||
let (options, name) = match (first_part, second_part) {
|
||||
(Some(opts), Some(name)) => (Some(opts), name),
|
||||
(Some(name), None) => (None, name),
|
||||
(None, None) => early_error(error_format, "--extern name must not be empty"),
|
||||
_ => unreachable!(),
|
||||
let (name, path) = match arg.split_once('=') {
|
||||
None => (arg, None),
|
||||
Some((name, path)) => (name.to_string(), Some(path.to_string())),
|
||||
};
|
||||
let (options, name) = match name.split_once(':') {
|
||||
None => (None, name),
|
||||
Some((opts, name)) => (Some(opts), name.to_string()),
|
||||
};
|
||||
|
||||
let entry = externs.entry(name.to_owned());
|
||||
|
@ -1682,17 +1736,12 @@ fn parse_remap_path_prefix(
|
|||
matches
|
||||
.opt_strs("remap-path-prefix")
|
||||
.into_iter()
|
||||
.map(|remap| {
|
||||
let mut parts = remap.rsplitn(2, '='); // reverse iterator
|
||||
let to = parts.next();
|
||||
let from = parts.next();
|
||||
match (from, to) {
|
||||
(Some(from), Some(to)) => (PathBuf::from(from), PathBuf::from(to)),
|
||||
_ => early_error(
|
||||
error_format,
|
||||
"--remap-path-prefix must contain '=' between FROM and TO",
|
||||
),
|
||||
}
|
||||
.map(|remap| match remap.rsplit_once('=') {
|
||||
None => early_error(
|
||||
error_format,
|
||||
"--remap-path-prefix must contain '=' between FROM and TO",
|
||||
),
|
||||
Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
@ -1766,7 +1815,30 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||
// and reversible name mangling. Note, LLVM coverage tools can analyze coverage over
|
||||
// multiple runs, including some changes to source code; so mangled names must be consistent
|
||||
// across compilations.
|
||||
debugging_opts.symbol_mangling_version = SymbolManglingVersion::V0;
|
||||
match debugging_opts.symbol_mangling_version {
|
||||
None => {
|
||||
debugging_opts.symbol_mangling_version = Some(SymbolManglingVersion::V0);
|
||||
}
|
||||
Some(SymbolManglingVersion::Legacy) => {
|
||||
early_warn(
|
||||
error_format,
|
||||
"-Z instrument-coverage requires symbol mangling version `v0`, \
|
||||
but `-Z symbol-mangling-version=legacy` was specified",
|
||||
);
|
||||
}
|
||||
Some(SymbolManglingVersion::V0) => {}
|
||||
}
|
||||
|
||||
if debugging_opts.mir_opt_level > 1 {
|
||||
early_warn(
|
||||
error_format,
|
||||
&format!(
|
||||
"`-Z mir-opt-level={}` (any level > 1) enables function inlining, which \
|
||||
limits the effectiveness of `-Z instrument-coverage`.",
|
||||
debugging_opts.mir_opt_level,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(graphviz_font) = std::env::var("RUSTC_GRAPHVIZ_FONT") {
|
||||
|
@ -2171,7 +2243,7 @@ crate mod dep_tracking {
|
|||
impl_dep_tracking_hash_via_hash!(Edition);
|
||||
impl_dep_tracking_hash_via_hash!(LinkerPluginLto);
|
||||
impl_dep_tracking_hash_via_hash!(SwitchWithOptPath);
|
||||
impl_dep_tracking_hash_via_hash!(SymbolManglingVersion);
|
||||
impl_dep_tracking_hash_via_hash!(Option<SymbolManglingVersion>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<SourceFileHashAlgorithm>);
|
||||
impl_dep_tracking_hash_via_hash!(TrimmedDefPaths);
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ impl<'a> FileSearch<'a> {
|
|||
pub fn new(
|
||||
sysroot: &'a Path,
|
||||
triple: &'a str,
|
||||
search_paths: &'a Vec<SearchPath>,
|
||||
search_paths: &'a [SearchPath],
|
||||
tlib_path: &'a SearchPath,
|
||||
kind: PathKind,
|
||||
) -> FileSearch<'a> {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(once_cell)]
|
||||
#![feature(or_patterns)]
|
||||
#![feature(str_split_once)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
|
|
|
@ -179,9 +179,10 @@ macro_rules! options {
|
|||
{
|
||||
let mut op = $defaultfn();
|
||||
for option in matches.opt_strs($prefix) {
|
||||
let mut iter = option.splitn(2, '=');
|
||||
let key = iter.next().unwrap();
|
||||
let value = iter.next();
|
||||
let (key, value) = match option.split_once('=') {
|
||||
None => (option, None),
|
||||
Some((k, v)) => (k.to_string(), Some(v)),
|
||||
};
|
||||
let option_to_lookup = key.replace("-", "_");
|
||||
let mut found = false;
|
||||
for &(candidate, setter, type_desc, _) in $stat {
|
||||
|
@ -268,6 +269,7 @@ macro_rules! options {
|
|||
pub const parse_switch_with_opt_path: &str =
|
||||
"an optional path to the profiling data output directory";
|
||||
pub const parse_merge_functions: &str = "one of: `disabled`, `trampolines`, or `aliases`";
|
||||
pub const parse_split_dwarf_kind: &str = "one of: `none`, `single` or `split`";
|
||||
pub const parse_symbol_mangling_version: &str = "either `legacy` or `v0` (RFC 2603)";
|
||||
pub const parse_src_file_hash: &str = "either `md5` or `sha1`";
|
||||
pub const parse_relocation_model: &str =
|
||||
|
@ -675,13 +677,26 @@ macro_rules! options {
|
|||
true
|
||||
}
|
||||
|
||||
fn parse_symbol_mangling_version(
|
||||
slot: &mut SymbolManglingVersion,
|
||||
fn parse_split_dwarf_kind(
|
||||
slot: &mut SplitDwarfKind,
|
||||
v: Option<&str>,
|
||||
) -> bool {
|
||||
*slot = match v {
|
||||
Some("legacy") => SymbolManglingVersion::Legacy,
|
||||
Some("v0") => SymbolManglingVersion::V0,
|
||||
Some("none") => SplitDwarfKind::None,
|
||||
Some("split") => SplitDwarfKind::Split,
|
||||
Some("single") => SplitDwarfKind::Single,
|
||||
_ => return false,
|
||||
};
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_symbol_mangling_version(
|
||||
slot: &mut Option<SymbolManglingVersion>,
|
||||
v: Option<&str>,
|
||||
) -> bool {
|
||||
*slot = match v {
|
||||
Some("legacy") => Some(SymbolManglingVersion::Legacy),
|
||||
Some("v0") => Some(SymbolManglingVersion::V0),
|
||||
_ => return false,
|
||||
};
|
||||
true
|
||||
|
@ -1087,9 +1102,14 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
|||
"hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"),
|
||||
strip: Strip = (Strip::None, parse_strip, [UNTRACKED],
|
||||
"tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"),
|
||||
symbol_mangling_version: SymbolManglingVersion = (SymbolManglingVersion::Legacy,
|
||||
split_dwarf: SplitDwarfKind = (SplitDwarfKind::None, parse_split_dwarf_kind, [UNTRACKED],
|
||||
"enable generation of split dwarf"),
|
||||
split_dwarf_inlining: bool = (true, parse_bool, [UNTRACKED],
|
||||
"provide minimal debug info in the object/executable to facilitate online \
|
||||
symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF"),
|
||||
symbol_mangling_version: Option<SymbolManglingVersion> = (None,
|
||||
parse_symbol_mangling_version, [TRACKED],
|
||||
"which mangling version to use for symbol names"),
|
||||
"which mangling version to use for symbol names ('legacy' (default) or 'v0')"),
|
||||
teach: bool = (false, parse_bool, [TRACKED],
|
||||
"show extended diagnostic help (default: no)"),
|
||||
terminal_width: Option<usize> = (None, parse_opt_uint, [UNTRACKED],
|
||||
|
|
|
@ -119,6 +119,7 @@ pub struct ParseSess {
|
|||
pub unstable_features: UnstableFeatures,
|
||||
pub config: CrateConfig,
|
||||
pub edition: Edition,
|
||||
pub missing_fragment_specifiers: Lock<FxHashMap<Span, NodeId>>,
|
||||
/// Places where raw identifiers were used. This is used for feature-gating raw identifiers.
|
||||
pub raw_identifier_spans: Lock<Vec<Span>>,
|
||||
/// Used to determine and report recursive module inclusions.
|
||||
|
@ -152,6 +153,7 @@ impl ParseSess {
|
|||
unstable_features: UnstableFeatures::from_environment(None),
|
||||
config: FxHashSet::default(),
|
||||
edition: ExpnId::root().expn_data().edition,
|
||||
missing_fragment_specifiers: Default::default(),
|
||||
raw_identifier_spans: Lock::new(Vec::new()),
|
||||
included_mod_stack: Lock::new(vec![]),
|
||||
source_map,
|
||||
|
|
|
@ -1109,10 +1109,7 @@ impl Session {
|
|||
}
|
||||
|
||||
pub fn link_dead_code(&self) -> bool {
|
||||
match self.opts.cg.link_dead_code {
|
||||
Some(explicitly_set) => explicitly_set,
|
||||
None => false,
|
||||
}
|
||||
self.opts.cg.link_dead_code.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn mark_attr_known(&self, attr: &Attribute) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue