Add docs for dump-sem-ir-ranges (#5598)

This commit is contained in:
Jon Ross-Perkins
2025-06-03 21:15:09 +00:00
committed by GitHub
parent 26093656de
commit c0cdc712e9
+99 -8
View File
@@ -21,10 +21,14 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- [Running tests](#running-tests)
- [Updating tests](#updating-tests)
- [Reviewing test deltas](#reviewing-test-deltas)
- [Minimal Core prelude](#minimal-core-prelude)
- [Verbose output](#verbose-output)
- [Stack traces](#stack-traces)
- [Dumping objects in interactive debuggers](#dumping-objects-in-interactive-debuggers)
- [Test patterns](#test-patterns)
- [Minimal Core prelude](#minimal-core-prelude)
- [SemIR dumps and ranges](#semir-dumps-and-ranges)
- [Example uses](#example-uses)
- [Debugging errors](#debugging-errors)
- [Verbose output](#verbose-output)
- [Stack traces](#stack-traces)
- [Dumping objects in interactive debuggers](#dumping-objects-in-interactive-debuggers)
<!-- tocstop -->
@@ -487,7 +491,9 @@ Using `autoupdate_testdata.py` can be useful to produce deltas during the
development process because it allows `git status` and `git diff` to be used to
examine what changed.
### Minimal Core prelude
### Test patterns
#### Minimal Core prelude
For most file tests in `check/`, very little of the `Core` package is used, and
the test is not intentionally testing the `Core` package itself. Compiling the
@@ -508,20 +514,105 @@ We have a set of minimal `Core` preludes for testing different compiler feature
areas in `//toolchain/testing/min_prelude/`. Each file begins with the line
`package Core library "prelude";` to make it provide a prelude.
### Verbose output
#### SemIR dumps and ranges
In `check/` tests, we use ranges to help reduce SemIR output in golden files and
focus on the most interesting parts. This is done with special
`//@dump-sem-ir-begin` and `//@dump-sem-ir-end` markers; note these are not
valid comments because they have no space after `//`. As rules of thumb:
- Put ranges around code relevant to the feature under test.
- When testing similar code in multiple different ways, focus on what's
expected to be unique.
- Try to keep ranges small.
- We try to structure tests to use type checking to validate correctness;
extra code for type checking might be possible to put outside a range.
- For example, when passing an argument to a function call, think about
whether the function call needs to be included, or if a range can focus
on the argument.
- Don't put markers around most failures.
- A lot of failures will print similar SemIR; we're trying to balance
review costs with the value of SemIR in golden files.
When a range is printed, referenced constants and import_refs will be
automatically included as well. A small amount of SemIR may include a number of
related instructions, such as an in-range instruction referencing an import_ref
referencing a constant referencing another constant.
> NOTE: In a test, if full SemIR is desired for files, add
> `// EXTRA-ARGS: --dump-sem-ir-ranges=if-present` with an explanation why.
##### Example uses
The range markers can be placed anywhere in code, and formatting will try to
print only the relevant SemIR. In the example below, the `Foo` entity will be
printed because it contains a range; its body will include `LogicUnderTest()`,
but `SetUp()` and `TearDown()` will be omitted.
```carbon
fn Foo() {
SetUp();
//@dump-sem-ir-begin
LogicUnderTest();
//@dump-sem-ir-end
TearDown();
}
```
The ranges are token-based, and entity declarations with an overlapping range
should be included. Ranges can span entity declarations in order to have only
part of an entity included in output. In the example below, `Bar` and
`Bar::ImportantCall` will be printed, but `Bar::UnimportantCall` will be
omitted.
```
//@dump-sem-ir-begin
class Bar {
fn ImportantCall[self: Self] { ... }
//@dump-sem-ir-end
fn UnimportantCall[self: Self]() { ... }
}
```
Out-of-line definitions can be used to print a nested entity without printing
the entity that contains it. In the example below, `Baz::Interesting` will be
printed because of the range in its body; `Baz` will be omitted because its
definition doesn't contain a range.
```
class Baz {
fn Interesting();
}
fn Baz::Interesting() {
//@dump-sem-ir-begin
...
//@dump-sem-ir-end
}
```
Normally, files with no range markers will be excluded from output. For example,
we'll often exclude failing tests from output: passing SemIR is typically more
interesting, and failing tests only need to fail gracefully. However, sometimes
output can help check that an error is correctly propagated in SemIR.
### Debugging errors
#### Verbose output
The `-v` flag can be passed to trace state, and should be specified before the
subcommand name: `carbon -v compile ...`. `CARBON_VLOG` is used to print output
in this mode. There is currently no control over the degree of verbosity.
### Stack traces
#### Stack traces
While the iterative processing pattern means function stack traces will have
minimal context for how the current function is reached, we use LLVM's
`PrettyStackTrace` to include details about the state stack. The state stack
will be above the function stack in crash output.
### Dumping objects in interactive debuggers
#### Dumping objects in interactive debuggers
We provide namespace-scoped `Dump` functions in several components, such as
[check/dump.cpp](/toolchain/check/dump.cpp). These `Dump` functions will print