about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/bootstrap/test.rs20
-rw-r--r--src/test/debuginfo/lexical-scope-with-macro.rs2
-rw-r--r--src/tools/compiletest/src/common.rs3
-rw-r--r--src/tools/compiletest/src/header.rs157
-rw-r--r--src/tools/compiletest/src/main.rs34
-rw-r--r--src/tools/compiletest/src/runtest.rs29
6 files changed, 183 insertions, 62 deletions
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 633c15b54b9..80c89b9ff38 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -812,8 +812,7 @@ default_test!(Incremental {
 
 default_test!(Debuginfo {
     path: "src/test/debuginfo",
-    // What this runs varies depending on the native platform being apple
-    mode: "debuginfo-XXX",
+    mode: "debuginfo",
     suite: "debuginfo"
 });
 
@@ -950,18 +949,11 @@ impl Step for Compiletest {
                 return;
             }
 
-            if mode == "debuginfo-XXX" {
-                return if builder.config.build.contains("apple") {
-                    builder.ensure(Compiletest {
-                        mode: "debuginfo-lldb",
-                        ..self
-                    });
-                } else {
-                    builder.ensure(Compiletest {
-                        mode: "debuginfo-gdb",
-                        ..self
-                    });
-                };
+            if mode == "debuginfo" {
+                return builder.ensure(Compiletest {
+                    mode: "debuginfo-both",
+                    ..self
+                });
             }
 
             builder.ensure(dist::DebuggerScripts {
diff --git a/src/test/debuginfo/lexical-scope-with-macro.rs b/src/test/debuginfo/lexical-scope-with-macro.rs
index 4e88f65ad1d..d11a42bb0ed 100644
--- a/src/test/debuginfo/lexical-scope-with-macro.rs
+++ b/src/test/debuginfo/lexical-scope-with-macro.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // min-lldb-version: 310
-// ignore-macos FIXME #48807
+// ignore-lldb FIXME #48807
 
 // compile-flags:-g -Zdebug-macros
 
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 7006fb9427e..fab2ea7ba6c 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -25,6 +25,7 @@ pub enum Mode {
     RunPass,
     RunPassValgrind,
     Pretty,
+    DebugInfoBoth,
     DebugInfoGdb,
     DebugInfoLldb,
     Codegen,
@@ -60,6 +61,7 @@ impl FromStr for Mode {
             "run-pass" => Ok(RunPass),
             "run-pass-valgrind" => Ok(RunPassValgrind),
             "pretty" => Ok(Pretty),
+            "debuginfo-both" => Ok(DebugInfoBoth),
             "debuginfo-lldb" => Ok(DebugInfoLldb),
             "debuginfo-gdb" => Ok(DebugInfoGdb),
             "codegen" => Ok(Codegen),
@@ -83,6 +85,7 @@ impl fmt::Display for Mode {
             RunPass => "run-pass",
             RunPassValgrind => "run-pass-valgrind",
             Pretty => "pretty",
+            DebugInfoBoth => "debuginfo-both",
             DebugInfoGdb => "debuginfo-gdb",
             DebugInfoLldb => "debuginfo-lldb",
             Codegen => "codegen",
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 688f2babe6e..06eeef61a19 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -19,10 +19,62 @@ use util;
 
 use extract_gdb_version;
 
+/// Whether to ignore the test.
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub enum Ignore {
+    /// Run it.
+    Run,
+    /// Ignore it totally.
+    Ignore,
+    /// Ignore only the gdb test, but run the lldb test.
+    IgnoreGdb,
+    /// Ignore only the lldb test, but run the gdb test.
+    IgnoreLldb,
+}
+
+impl Ignore {
+    pub fn can_run_gdb(&self) -> bool {
+        *self == Ignore::Run || *self == Ignore::IgnoreLldb
+    }
+
+    pub fn can_run_lldb(&self) -> bool {
+        *self == Ignore::Run || *self == Ignore::IgnoreGdb
+    }
+
+    pub fn no_gdb(&self) -> Ignore {
+        match *self {
+            Ignore::Run => Ignore::IgnoreGdb,
+            Ignore::IgnoreGdb => Ignore::IgnoreGdb,
+            _ => Ignore::Ignore,
+        }
+    }
+
+    pub fn no_lldb(&self) -> Ignore {
+        match *self {
+            Ignore::Run => Ignore::IgnoreLldb,
+            Ignore::IgnoreLldb => Ignore::IgnoreLldb,
+            _ => Ignore::Ignore,
+        }
+    }
+}
+
+/// The result of parse_cfg_name_directive.
+#[derive(Clone, Copy, PartialEq, Debug)]
+enum ParsedNameDirective {
+    /// No match.
+    NoMatch,
+    /// Match.
+    Match,
+    /// Mode was DebugInfoBoth and this matched gdb.
+    MatchGdb,
+    /// Mode was DebugInfoBoth and this matched lldb.
+    MatchLldb,
+}
+
 /// Properties which must be known very early, before actually running
 /// the test.
 pub struct EarlyProps {
-    pub ignore: bool,
+    pub ignore: Ignore,
     pub should_fail: bool,
     pub aux: Vec<String>,
     pub revisions: Vec<String>,
@@ -31,20 +83,55 @@ pub struct EarlyProps {
 impl EarlyProps {
     pub fn from_file(config: &Config, testfile: &Path) -> Self {
         let mut props = EarlyProps {
-            ignore: false,
+            ignore: Ignore::Run,
             should_fail: false,
             aux: Vec::new(),
             revisions: vec![],
         };
 
+        if config.mode == common::DebugInfoBoth {
+            if config.lldb_python_dir.is_none() {
+                props.ignore = props.ignore.no_lldb();
+            }
+            if config.gdb_version.is_none() {
+                props.ignore = props.ignore.no_gdb();
+            }
+        }
+
         iter_header(testfile, None, &mut |ln| {
             // we should check if any only-<platform> exists and if it exists
             // and does not matches the current platform, skip the test
-            props.ignore = props.ignore || config.parse_cfg_name_directive(ln, "ignore")
-                || (config.has_cfg_prefix(ln, "only")
-                    && !config.parse_cfg_name_directive(ln, "only"))
-                || ignore_gdb(config, ln) || ignore_lldb(config, ln)
-                || ignore_llvm(config, ln);
+            if props.ignore != Ignore::Ignore {
+                props.ignore = match config.parse_cfg_name_directive(ln, "ignore") {
+                    ParsedNameDirective::Match => Ignore::Ignore,
+                    ParsedNameDirective::NoMatch => props.ignore,
+                    ParsedNameDirective::MatchGdb => props.ignore.no_gdb(),
+                    ParsedNameDirective::MatchLldb => props.ignore.no_lldb(),
+                };
+
+                if config.has_cfg_prefix(ln, "only") {
+                    props.ignore = match config.parse_cfg_name_directive(ln, "only") {
+                        ParsedNameDirective::Match => props.ignore,
+                        ParsedNameDirective::NoMatch => Ignore::Ignore,
+                        ParsedNameDirective::MatchLldb => props.ignore.no_gdb(),
+                        ParsedNameDirective::MatchGdb => props.ignore.no_lldb(),
+                    };
+                }
+
+                if ignore_llvm(config, ln) {
+                    props.ignore = Ignore::Ignore;
+                }
+            }
+
+            if (config.mode == common::DebugInfoGdb || config.mode == common::DebugInfoBoth) &&
+                props.ignore.can_run_gdb() && ignore_gdb(config, ln) {
+                props.ignore = props.ignore.no_gdb();
+            }
+
+            if (config.mode == common::DebugInfoLldb || config.mode == common::DebugInfoBoth) &&
+                props.ignore.can_run_lldb() && ignore_lldb(config, ln) {
+                props.ignore = props.ignore.no_lldb();
+            }
 
             if let Some(s) = config.parse_aux_build(ln) {
                 props.aux.push(s);
@@ -60,10 +147,6 @@ impl EarlyProps {
         return props;
 
         fn ignore_gdb(config: &Config, line: &str) -> bool {
-            if config.mode != common::DebugInfoGdb {
-                return false;
-            }
-
             if let Some(actual_version) = config.gdb_version {
                 if line.starts_with("min-gdb-version") {
                     let (start_ver, end_ver) = extract_gdb_version_range(line);
@@ -120,10 +203,6 @@ impl EarlyProps {
         }
 
         fn ignore_lldb(config: &Config, line: &str) -> bool {
-            if config.mode != common::DebugInfoLldb {
-                return false;
-            }
-
             if let Some(ref actual_version) = config.lldb_version {
                 if line.starts_with("min-lldb-version") {
                     let min_version = line.trim_right()
@@ -604,7 +683,7 @@ impl Config {
     }
 
     fn parse_custom_normalization(&self, mut line: &str, prefix: &str) -> Option<(String, String)> {
-        if self.parse_cfg_name_directive(line, prefix) {
+        if self.parse_cfg_name_directive(line, prefix) == ParsedNameDirective::Match {
             let from = match parse_normalization_string(&mut line) {
                 Some(s) => s,
                 None => return None,
@@ -620,35 +699,59 @@ impl Config {
     }
 
     /// Parses a name-value directive which contains config-specific information, e.g. `ignore-x86`
-    /// or `normalize-stderr-32bit`. Returns `true` if the line matches it.
-    fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> bool {
+    /// or `normalize-stderr-32bit`.
+    fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> ParsedNameDirective {
         if line.starts_with(prefix) && line.as_bytes().get(prefix.len()) == Some(&b'-') {
             let name = line[prefix.len() + 1..]
                 .split(&[':', ' '][..])
                 .next()
                 .unwrap();
 
-            name == "test" ||
+            if name == "test" ||
                 util::matches_os(&self.target, name) ||             // target
                 name == util::get_arch(&self.target) ||             // architecture
                 name == util::get_pointer_width(&self.target) ||    // pointer width
                 name == self.stage_id.split('-').next().unwrap() || // stage
                 Some(name) == util::get_env(&self.target) ||        // env
-                match self.mode {
-                    common::DebugInfoGdb => name == "gdb",
-                    common::DebugInfoLldb => name == "lldb",
-                    common::Pretty => name == "pretty",
-                    _ => false,
-                } ||
                 (self.target != self.host && name == "cross-compile") ||
                 match self.compare_mode {
                     Some(CompareMode::Nll) => name == "compare-mode-nll",
                     Some(CompareMode::Polonius) => name == "compare-mode-polonius",
                     None => false,
                 } ||
-                (cfg!(debug_assertions) && name == "debug")
+                (cfg!(debug_assertions) && name == "debug") {
+                ParsedNameDirective::Match
+            } else {
+                match self.mode {
+                    common::DebugInfoBoth => {
+                        if name == "gdb" {
+                            ParsedNameDirective::MatchGdb
+                        } else if name == "lldb" {
+                            ParsedNameDirective::MatchLldb
+                        } else {
+                            ParsedNameDirective::NoMatch
+                        }
+                    },
+                    common::DebugInfoGdb => if name == "gdb" {
+                        ParsedNameDirective::Match
+                    } else {
+                        ParsedNameDirective::NoMatch
+                    },
+                    common::DebugInfoLldb => if name == "lldb" {
+                        ParsedNameDirective::Match
+                    } else {
+                        ParsedNameDirective::NoMatch
+                    },
+                    common::Pretty => if name == "pretty" {
+                        ParsedNameDirective::Match
+                    } else {
+                        ParsedNameDirective::NoMatch
+                    },
+                    _ => ParsedNameDirective::NoMatch,
+                }
+            }
         } else {
-            false
+            ParsedNameDirective::NoMatch
         }
     }
 
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index f46e031d768..c931d3c0e30 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -32,7 +32,7 @@ extern crate rustfix;
 use common::CompareMode;
 use common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS};
 use common::{Config, TestPaths};
-use common::{DebugInfoGdb, DebugInfoLldb, Mode, Pretty};
+use common::{DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Mode, Pretty};
 use filetime::FileTime;
 use getopts::Options;
 use std::env;
@@ -44,7 +44,7 @@ use std::process::Command;
 use test::ColorConfig;
 use util::logv;
 
-use self::header::EarlyProps;
+use self::header::{EarlyProps, Ignore};
 
 pub mod common;
 pub mod errors;
@@ -425,7 +425,7 @@ pub fn opt_str2(maybestr: Option<String>) -> String {
 
 pub fn run_tests(config: &Config) {
     if config.target.contains("android") {
-        if let DebugInfoGdb = config.mode {
+        if config.mode == DebugInfoGdb || config.mode == DebugInfoBoth {
             println!(
                 "{} debug-info test uses tcp 5039 port.\
                  please reserve it",
@@ -443,7 +443,9 @@ pub fn run_tests(config: &Config) {
     }
 
     match config.mode {
-        DebugInfoLldb => {
+        // Note that we don't need to emit the gdb warning when
+        // DebugInfoBoth, so it is ok to list that here.
+        DebugInfoBoth | DebugInfoLldb => {
             if let Some(lldb_version) = config.lldb_version.as_ref() {
                 if is_blacklisted_lldb_version(&lldb_version[..]) {
                     println!(
@@ -647,15 +649,18 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> Vec<test::TestDescAn
         .into_iter()
         .map(|revision| {
             // Debugging emscripten code doesn't make sense today
-            let ignore = early_props.ignore
+            let ignore = early_props.ignore == Ignore::Ignore
                 || !up_to_date(
                     config,
                     testpaths,
                     &early_props,
                     revision.map(|s| s.as_str()),
                 )
-                || (config.mode == DebugInfoGdb || config.mode == DebugInfoLldb)
-                    && config.target.contains("emscripten");
+                || ((config.mode == DebugInfoBoth ||
+                     config.mode == DebugInfoGdb || config.mode == DebugInfoLldb)
+                    && config.target.contains("emscripten"))
+                || (config.mode == DebugInfoGdb && !early_props.ignore.can_run_gdb())
+                || (config.mode == DebugInfoLldb && !early_props.ignore.can_run_lldb());
             test::TestDescAndFn {
                 desc: test::TestDesc {
                     name: make_test_name(config, testpaths, revision),
@@ -663,7 +668,7 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> Vec<test::TestDescAn
                     should_panic,
                     allow_fail: false,
                 },
-                testfn: make_test_closure(config, testpaths, revision),
+                testfn: make_test_closure(config, early_props.ignore, testpaths, revision),
             }
         })
         .collect()
@@ -774,10 +779,21 @@ fn make_test_name(
 
 fn make_test_closure(
     config: &Config,
+    ignore: Ignore,
     testpaths: &TestPaths,
     revision: Option<&String>,
 ) -> test::TestFn {
-    let config = config.clone();
+    let mut config = config.clone();
+    if config.mode == DebugInfoBoth {
+        // If both gdb and lldb were ignored, then the test as a whole
+        // would be ignored.
+        if !ignore.can_run_gdb() {
+            config.mode = DebugInfoLldb;
+        } else if !ignore.can_run_lldb() {
+            config.mode = DebugInfoGdb;
+        }
+    }
+
     let testpaths = testpaths.clone();
     let revision = revision.cloned();
     test::DynTestFn(Box::new(move || {
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index c69956030c0..8c3b1bb4df3 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -11,7 +11,7 @@
 use common::CompareMode;
 use common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT};
 use common::{output_base_dir, output_base_name, output_testname_unique};
-use common::{Codegen, CodegenUnits, DebugInfoGdb, DebugInfoLldb, Rustdoc};
+use common::{Codegen, CodegenUnits, DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Rustdoc};
 use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
 use common::{Config, TestPaths};
 use common::{Incremental, MirOpt, RunMake, Ui};
@@ -225,19 +225,20 @@ pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
 pub fn compute_stamp_hash(config: &Config) -> String {
     let mut hash = DefaultHasher::new();
     config.stage_id.hash(&mut hash);
-    match config.mode {
-        DebugInfoGdb => match config.gdb {
+
+    if config.mode == DebugInfoGdb || config.mode == DebugInfoBoth {
+        match config.gdb {
             None => env::var_os("PATH").hash(&mut hash),
             Some(ref s) if s.is_empty() => env::var_os("PATH").hash(&mut hash),
             Some(ref s) => s.hash(&mut hash),
-        },
-        DebugInfoLldb => {
-            env::var_os("PATH").hash(&mut hash);
-            env::var_os("PYTHONPATH").hash(&mut hash);
-        },
+        };
+    }
+
+    if config.mode == DebugInfoLldb || config.mode == DebugInfoBoth {
+        env::var_os("PATH").hash(&mut hash);
+        env::var_os("PYTHONPATH").hash(&mut hash);
+    }
 
-        _ => {},
-    };
     format!("{:x}", hash.finish())
 }
 
@@ -268,6 +269,10 @@ impl<'test> TestCx<'test> {
             RunFail => self.run_rfail_test(),
             RunPassValgrind => self.run_valgrind_test(),
             Pretty => self.run_pretty_test(),
+            DebugInfoBoth => {
+                self.run_debuginfo_gdb_test();
+                self.run_debuginfo_lldb_test();
+            },
             DebugInfoGdb => self.run_debuginfo_gdb_test(),
             DebugInfoLldb => self.run_debuginfo_lldb_test(),
             Codegen => self.run_codegen_test(),
@@ -640,6 +645,7 @@ impl<'test> TestCx<'test> {
         let config = Config {
             target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
             host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
+            mode: DebugInfoGdb,
             ..self.config.clone()
         };
 
@@ -910,6 +916,7 @@ impl<'test> TestCx<'test> {
         let config = Config {
             target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
             host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
+            mode: DebugInfoLldb,
             ..self.config.clone()
         };
 
@@ -1774,7 +1781,7 @@ impl<'test> TestCx<'test> {
 
                 rustc.arg(dir_opt);
             }
-            RunFail | RunPassValgrind | Pretty | DebugInfoGdb | DebugInfoLldb
+            RunFail | RunPassValgrind | Pretty | DebugInfoBoth | DebugInfoGdb | DebugInfoLldb
             | Codegen | Rustdoc | RunMake | CodegenUnits => {
                 // do not use JSON output
             }