about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/compiletest/src/common.rs3
-rw-r--r--src/tools/compiletest/src/header.rs25
-rw-r--r--src/tools/compiletest/src/main.rs29
3 files changed, 51 insertions, 6 deletions
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 848bd3a43e8..2f832b53a90 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -261,6 +261,9 @@ pub struct Config {
     /// Path to / name of the Microsoft Console Debugger (CDB) executable
     pub cdb: Option<OsString>,
 
+    /// Version of CDB
+    pub cdb_version: Option<[u16; 4]>,
+
     /// Path to / name of the GDB executable
     pub gdb: Option<String>,
 
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 0efa668ecc8..17649dfab37 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -8,8 +8,8 @@ use std::path::{Path, PathBuf};
 use tracing::*;
 
 use crate::common::{CompareMode, Config, Debugger, FailMode, Mode, PassMode};
-use crate::extract_gdb_version;
 use crate::util;
+use crate::{extract_cdb_version, extract_gdb_version};
 
 #[cfg(test)]
 mod tests;
@@ -105,6 +105,10 @@ impl EarlyProps {
                     props.ignore = true;
                 }
 
+                if config.debugger == Some(Debugger::Cdb) && ignore_cdb(config, ln) {
+                    props.ignore = true;
+                }
+
                 if config.debugger == Some(Debugger::Gdb) && ignore_gdb(config, ln) {
                     props.ignore = true;
                 }
@@ -131,6 +135,21 @@ impl EarlyProps {
 
         return props;
 
+        fn ignore_cdb(config: &Config, line: &str) -> bool {
+            if let Some(actual_version) = config.cdb_version {
+                if let Some(min_version) = line.strip_prefix("min-cdb-version:").map(str::trim) {
+                    let min_version = extract_cdb_version(min_version).unwrap_or_else(|| {
+                        panic!("couldn't parse version range: {:?}", min_version);
+                    });
+
+                    // Ignore if actual version is smaller than the minimum
+                    // required version
+                    return actual_version < min_version;
+                }
+            }
+            false
+        }
+
         fn ignore_gdb(config: &Config, line: &str) -> bool {
             if let Some(actual_version) = config.gdb_version {
                 if let Some(rest) = line.strip_prefix("min-gdb-version:").map(str::trim) {
@@ -142,8 +161,8 @@ impl EarlyProps {
                     if start_ver != end_ver {
                         panic!("Expected single GDB version")
                     }
-                    // Ignore if actual version is smaller the minimum required
-                    // version
+                    // Ignore if actual version is smaller than the minimum
+                    // required version
                     return actual_version < start_ver;
                 } else if let Some(rest) = line.strip_prefix("ignore-gdb-version:").map(str::trim) {
                     let (min_version, max_version) =
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index adf2fa7fd8e..190a9c62210 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -163,7 +163,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
 
     let target = opt_str2(matches.opt_str("target"));
     let android_cross_path = opt_path(matches, "android-cross-path");
-    let cdb = analyze_cdb(matches.opt_str("cdb"), &target);
+    let (cdb, cdb_version) = analyze_cdb(matches.opt_str("cdb"), &target);
     let (gdb, gdb_version, gdb_native_rust) =
         analyze_gdb(matches.opt_str("gdb"), &target, &android_cross_path);
     let (lldb_version, lldb_native_rust) = matches
@@ -216,6 +216,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         target,
         host: opt_str2(matches.opt_str("host")),
         cdb,
+        cdb_version,
         gdb,
         gdb_version,
         gdb_native_rust,
@@ -773,8 +774,30 @@ fn find_cdb(target: &str) -> Option<OsString> {
 }
 
 /// Returns Path to CDB
-fn analyze_cdb(cdb: Option<String>, target: &str) -> Option<OsString> {
-    cdb.map(OsString::from).or_else(|| find_cdb(target))
+fn analyze_cdb(cdb: Option<String>, target: &str) -> (Option<OsString>, Option<[u16; 4]>) {
+    let cdb = cdb.map(OsString::from).or_else(|| find_cdb(target));
+
+    let mut version = None;
+    if let Some(cdb) = cdb.as_ref() {
+        if let Ok(output) = Command::new(cdb).arg("/version").output() {
+            if let Some(first_line) = String::from_utf8_lossy(&output.stdout).lines().next() {
+                version = extract_cdb_version(&first_line);
+            }
+        }
+    }
+
+    (cdb, version)
+}
+
+fn extract_cdb_version(full_version_line: &str) -> Option<[u16; 4]> {
+    // Example full_version_line: "cdb version 10.0.18362.1"
+    let version = full_version_line.rsplit(' ').next()?;
+    let mut components = version.split('.');
+    let major: u16 = components.next().unwrap().parse().unwrap();
+    let minor: u16 = components.next().unwrap().parse().unwrap();
+    let patch: u16 = components.next().unwrap_or("0").parse().unwrap();
+    let build: u16 = components.next().unwrap_or("0").parse().unwrap();
+    Some([major, minor, patch, build])
 }
 
 /// Returns (Path to GDB, GDB Version, GDB has Rust Support)