Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/tools/compiletest/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use build_helper::git::GitConfig;
use camino::{Utf8Path, Utf8PathBuf};
use semver::Version;

use crate::debuggers::LldbVersion;
use crate::edition::Edition;
use crate::fatal;
use crate::util::{Utf8PathBufExt, add_dylib_path, string_enum};
Expand Down Expand Up @@ -597,7 +598,7 @@ pub(crate) struct Config {
/// Version of LLDB.
///
/// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
pub(crate) lldb_version: Option<u32>,
pub(crate) lldb_version: Option<LldbVersion>,

/// Version of LLVM.
///
Expand Down
86 changes: 68 additions & 18 deletions src/tools/compiletest/src/debuggers.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::process::Command;

use camino::Utf8Path;
use semver::Version;

pub(crate) fn query_cdb_version(cdb: &Utf8Path) -> Option<[u16; 4]> {
let mut version = None;
Expand Down Expand Up @@ -86,40 +87,89 @@ pub(crate) fn extract_gdb_version(full_version_line: &str) -> Option<u32> {
Some(((major * 1000) + minor) * 1000 + patch)
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum LldbVersion {
/// LLDB distributed by Apple as part of Xcode. Uses a unique versioning scheme that does not
/// match LLVM's LLDB.
Apple([u64; 4]),
/// LLDB distributed by LLVM, uses traditional semver.
Llvm(Version),
}

impl LldbVersion {
/// Takes a string consisting of 1-4 `.`-separated numbers and returns an `LldbVersion::Apple`.
///
/// If a number fails to parse, that section and any following sections are silently converted
/// to `0` (e.g. `"15.6.asdf.3"` -> `[15, 6, 0, 0]`)
Comment thread
jieyouxu marked this conversation as resolved.
pub(crate) fn apple_from_str(version_num: &str) -> Self {
let mut ver: [u64; 4] = [0; 4];

for (i, val) in version_num.split('.').enumerate().take_while(|(i, _)| *i < 4) {
if let Ok(part) = val.parse::<u64>() {
ver[i] = part;
} else {
eprintln!(
"Warning: Invalid LLDB version format: '{version_num}'. Falling back to version '{ver:?}'"
);
break;
}
}

Self::Apple(ver)
}

/// Takes a string consisting of 1-3 `.`-separated numbers and returns an `LldbVersion::Llvm`.
///
/// If a number fails to parse, that section and any following sections are silently converted
/// to `0` (e.g. `"15.asdf.3"` -> `[15, 0, 0]`)
pub(crate) fn llvm_from_str(version_num: &str) -> Self {
let mut ver: [u64; 3] = [0; 3];

for (i, val) in version_num.split('.').enumerate().take_while(|(i, _)| *i < 3) {
if let Ok(part) = val.parse::<u64>() {
ver[i] = part;
} else {
eprintln!(
"Warning: Invalid LLDB version number format: '{version_num}'. Falling back to version '{ver:?}'"
);
break;
}
}

Self::Llvm(Version::new(ver[0], ver[1], ver[2]))
}
}

/// Returns LLDB version
pub(crate) fn extract_lldb_version(full_version_line: &str) -> Option<u32> {
pub(crate) fn extract_lldb_version(full_version_line: &str) -> Option<LldbVersion> {
// Extract the major LLDB version from the given version string.
// LLDB version strings are different for Apple and non-Apple platforms.
// The Apple variant looks like this:
//
// LLDB-179.5 (older versions)
// lldb-300.2.51 (new versions)
// lldb-1703.0.236.21 (even newer versions)
//
// We are only interested in the major version number, so this function
// will return `Some(179)` and `Some(300)` respectively.
//
// Upstream versions look like:
// LLVM versions look like:
// lldb version 6.0.1
//
// There doesn't seem to be a way to correlate the Apple version
// with the upstream version, and since the tests were originally
// written against Apple versions, we make a fake Apple version by
// multiplying the first number by 100. This is a hack.
// with the upstream version.

let full_version_line = full_version_line.trim();

if let Some(apple_ver) =
if let Some(apple_str) =
full_version_line.strip_prefix("LLDB-").or_else(|| full_version_line.strip_prefix("lldb-"))
{
if let Some(idx) = apple_ver.find(not_a_digit) {
let version: u32 = apple_ver[..idx].parse().unwrap();
return Some(version);
}
} else if let Some(lldb_ver) = full_version_line.strip_prefix("lldb version ") {
if let Some(idx) = lldb_ver.find(not_a_digit) {
let version: u32 = lldb_ver[..idx].parse().ok()?;
return Some(version * 100);
}
let version_str = apple_str.split_whitespace().next()?;

return Some(LldbVersion::apple_from_str(version_str));
}

if let Some(lldb_str) = full_version_line.strip_prefix("lldb version ") {
let version_str = lldb_str.split_whitespace().next()?;

return Some(LldbVersion::llvm_from_str(version_str));
}
None
}
Expand Down
53 changes: 39 additions & 14 deletions src/tools/compiletest/src/directives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use semver::Version;
use tracing::*;

use crate::common::{Config, Debugger, PassFailMode, TestMode};
use crate::debuggers::{extract_cdb_version, extract_gdb_version};
use crate::debuggers::{LldbVersion, extract_cdb_version, extract_gdb_version};
use crate::directives::auxiliary::parse_and_update_aux;
pub(crate) use crate::directives::auxiliary::{AuxCrate, AuxProps};
use crate::directives::directive_names::{
Expand Down Expand Up @@ -1101,21 +1101,46 @@ fn ignore_lldb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
return IgnoreDecision::Continue;
}

if let Some(actual_version) = config.lldb_version {
if line.name == "min-lldb-version"
&& let Some(rest) = line.value_after_colon().map(str::trim)
{
let min_version = rest.parse().unwrap_or_else(|e| {
panic!("Unexpected format of LLDB version string: {}\n{:?}", rest, e);
});
// Ignore if actual version is smaller the minimum required
// version
if actual_version < min_version {
return IgnoreDecision::Ignore {
reason: format!("ignored when the LLDB version is {rest}"),
if let Some(actual_version) = &config.lldb_version {
match (line.name, actual_version) {
("min-apple-lldb-version", LldbVersion::Apple(vers)) => {
let Some(rest) = line.value_after_colon().map(str::trim) else {
return IgnoreDecision::Continue;
};

let LldbVersion::Apple(min_vers) = LldbVersion::apple_from_str(rest) else {
unreachable!()
};

if vers < &min_vers {
return IgnoreDecision::Ignore {
reason: format!(
"ignored when the Apple LLDB version is {}.{}.{}.{}",
vers[0], vers[1], vers[2], vers[3]
),
};
}
}
}
("min-llvm-lldb-version", LldbVersion::Llvm(vers)) => {
let Some(rest) = line.value_after_colon().map(str::trim) else {
return IgnoreDecision::Continue;
};

let LldbVersion::Llvm(min_vers) = LldbVersion::llvm_from_str(rest) else {
unreachable!()
};

if vers < &min_vers {
return IgnoreDecision::Ignore {
reason: format!(
"ignored when the LLDB version is {}.{}.{}",
vers.major, vers.minor, vers.patch
),
};
}
}
_ => {}
};
}
IgnoreDecision::Continue
}
Expand Down
3 changes: 2 additions & 1 deletion src/tools/compiletest/src/directives/directive_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,10 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"lldb-command",
"llvm-cov-flags",
"max-llvm-major-version",
"min-apple-lldb-version",
"min-cdb-version",
"min-gdb-version",
"min-lldb-version",
"min-llvm-lldb-version",
"min-llvm-version",
"min-system-llvm-version",
"minicore-compile-flags",
Expand Down
2 changes: 1 addition & 1 deletion src/tools/compiletest/src/runtest/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ impl TestCx<'_> {
Some(ref version) => {
writeln!(
self.stdout,
"NOTE: compiletest thinks it is using LLDB version {}",
"NOTE: compiletest thinks it is using LLDB version: {:?}",
version
);
}
Expand Down
18 changes: 13 additions & 5 deletions src/tools/compiletest/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::debuggers::{extract_gdb_version, extract_lldb_version};
use semver::Version;

use crate::debuggers::{LldbVersion, extract_gdb_version, extract_lldb_version};
use crate::is_test;

#[test]
Expand Down Expand Up @@ -48,12 +50,18 @@ fn test_extract_gdb_version() {
#[test]
fn test_extract_lldb_version() {
// Apple variants
assert_eq!(extract_lldb_version("LLDB-179.5"), Some(179));
assert_eq!(extract_lldb_version("lldb-300.2.51"), Some(300));
assert_eq!(extract_lldb_version("LLDB-179.5"), Some(LldbVersion::Apple([179, 5, 0, 0])));
assert_eq!(extract_lldb_version("lldb-300.2.51"), Some(LldbVersion::Apple([300, 2, 51, 0])));

// Upstream versions
assert_eq!(extract_lldb_version("lldb version 6.0.1"), Some(600));
assert_eq!(extract_lldb_version("lldb version 9.0.0"), Some(900));
assert_eq!(
extract_lldb_version("lldb version 6.0.1"),
Some(LldbVersion::Llvm(Version::new(6, 0, 1)))
);
assert_eq!(
extract_lldb_version("lldb version 9.0.0"),
Some(LldbVersion::Llvm(Version::new(9, 0, 0)))
);
}

#[test]
Expand Down
4 changes: 3 additions & 1 deletion tests/debuginfo/captured-fields-1.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//@ compile-flags:-g
//@ edition:2021
//@ ignore-backends: gcc
//@ min-lldb-version: 2100
//@ min-apple-lldb-version: 2210
//@ min-llvm-lldb-version: 21.0.0

// === GDB TESTS ===================================================================================

//@ gdb-command:run
Expand Down
3 changes: 2 additions & 1 deletion tests/debuginfo/constant-ordering-prologue.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//@ min-lldb-version: 310
//@ min-apple-lldb-version: 310
//@ min-llvm-lldb-version: 3.1.0

//@ compile-flags:-g
//@ ignore-backends: gcc
Expand Down
3 changes: 2 additions & 1 deletion tests/debuginfo/dummy_span.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//@ min-lldb-version: 310
//@ min-apple-lldb-version: 310
//@ min-llvm-lldb-version: 3.1.0

//@ compile-flags:-g
// FIXME: Investigate why test fails without SimplifyComparisonIntegral pass.
Expand Down
3 changes: 2 additions & 1 deletion tests/debuginfo/lexical-scope-in-match.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//@ compile-flags:-g
//@ disable-gdb-pretty-printers
//@ ignore-backends: gcc
//@ min-lldb-version: 2100
//@ min-apple-lldb-version: 2100
//@ min-llvm-lldb-version: 21.0.0

// === GDB TESTS ===================================================================================

Expand Down
3 changes: 2 additions & 1 deletion tests/debuginfo/zst-interferes-with-prologue.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//@ min-lldb-version: 310
//@ min-apple-lldb-version: 310
//@ min-llvm-lldb-version: 3.1.0

//@ compile-flags:-g
//@ ignore-backends: gcc
Expand Down
Loading