about summary refs log tree commit diff
path: root/src/tools/compiletest
diff options
context:
space:
mode:
authorDaniel Paoliello <danpao@microsoft.com>2021-06-24 10:36:28 -0700
committerDaniel Paoliello <danpao@microsoft.com>2021-06-30 11:10:29 -0700
commitaac8a885520854e4b60ea5733b8b06f9e0cc1fcc (patch)
tree197ee4eeb5aab523079e095ab2f8dd02ba906fa4 /src/tools/compiletest
parent868c702d0c9a471a28fb55f0148eb1e3e8b1dcc5 (diff)
downloadrust-aac8a885520854e4b60ea5733b8b06f9e0cc1fcc.tar.gz
rust-aac8a885520854e4b60ea5733b8b06f9e0cc1fcc.zip
Improve debug symbol names to avoid ambiguity and work better with MSVC's debugger
There are several cases where names of types and functions in the debug info are either ambiguous, or not helpful, such as including ambiguous placeholders (e.g., `{{impl}}`, `{{closure}}` or `dyn _'`) or dropping qualifications (e.g., for dynamic types).

Instead, each debug symbol name should be unique and useful:
* Include disambiguators for anonymous `DefPathDataName` (closures and generators), and unify their formatting when used as a path-qualifier vs item being qualified.
* Qualify the principal trait for dynamic types.
* If there is no principal trait for a dynamic type, emit all other traits instead.
* Respect the `qualified` argument when emitting ref and pointer types.
* For implementations, emit the disambiguator.
* Print const generics when emitting generic parameters or arguments.

Additionally, when targeting MSVC, its debugger treats many command arguments as C++ expressions, even when the argument is defined to be a symbol name. As such names in the debug info need to be more C++-like to be parsed correctly:
* Avoid characters with special meaning (`#`, `[`, `"`, `+`).
* Never start a name with `<` or `{` as this is treated as an operator.
* `>>` is always treated as a right-shift, even when parsing generic arguments (so add a space to avoid this).
* Emit function declarations using C/C++ style syntax (e.g., leading return type).
* Emit arrays as a synthetic `array$<type, size>` type.
* Include a `$` in all synthetic types as this is a legal character for C++, but not Rust (thus we avoid collisions with user types).
Diffstat (limited to 'src/tools/compiletest')
-rw-r--r--src/tools/compiletest/src/runtest.rs26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 6a1faee1d8e..49731b2d7dc 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -778,6 +778,14 @@ impl<'test> TestCx<'test> {
         script_str.push_str("version\n"); // List CDB (and more) version info in test output
         script_str.push_str(".nvlist\n"); // List loaded `*.natvis` files, bulk of custom MSVC debug
 
+        // If a .js file exists next to the source file being tested, then this is a JavaScript
+        // debugging extension that needs to be loaded.
+        let mut js_extension = self.testpaths.file.clone();
+        js_extension.set_extension("cdb.js");
+        if js_extension.exists() {
+            script_str.push_str(&format!(".scriptload \"{}\"\n", js_extension.to_string_lossy()));
+        }
+
         // Set breakpoints on every line that contains the string "#break"
         let source_file_name = self.testpaths.file.file_name().unwrap().to_string_lossy();
         for line in &breakpoint_lines {
@@ -2329,13 +2337,17 @@ impl<'test> TestCx<'test> {
         // useful flag.
         //
         // For now, though…
-        if let Some(rev) = self.revision {
-            let prefixes = format!("CHECK,{}", rev);
-            if self.config.llvm_version.unwrap_or(0) >= 130000 {
-                filecheck.args(&["--allow-unused-prefixes", "--check-prefixes", &prefixes]);
-            } else {
-                filecheck.args(&["--check-prefixes", &prefixes]);
-            }
+        let prefix_for_target =
+            if self.config.target.contains("msvc") { "MSVC" } else { "NONMSVC" };
+        let prefixes = if let Some(rev) = self.revision {
+            format!("CHECK,{},{}", prefix_for_target, rev)
+        } else {
+            format!("CHECK,{}", prefix_for_target)
+        };
+        if self.config.llvm_version.unwrap_or(0) >= 130000 {
+            filecheck.args(&["--allow-unused-prefixes", "--check-prefixes", &prefixes]);
+        } else {
+            filecheck.args(&["--check-prefixes", &prefixes]);
         }
         self.compose_and_run(filecheck, "", None, None)
     }