Updates the `@fmt` selector, by adding support for Python f-strings to
the Python to bytecode compiler, and updating the evaluation of `@fmt`
by improved interfacing with `llvm::formatv`.
Changes to `@fmt`:
* Consume the arguments, leaving only the resulting string on the stack.
Previously, the arguments were left on the stack, unlike what the docs
describe and what the interpreter does.
* In version 2 formatters, replacements are automatically indexed.
Explicit indexes,such as `{0}`, are an error. This makes the stack
effect of `@fmt` clear from the format string: the number of arguments
is the number of replacements, and each argument is used once, in stack
order. Arguments can be reordered or reused with the stack operations.
* In version 2 formatters, layouts and options (`{,8}`, `{:x}`) are
accepted, but are currently ignored. They are treated as best effort
hints, so that support for them can be added later without changing the
ABI.
* In version 2 formatters, the format string is checked by LLDB before
it reaches `formatv`, which is given only literal text, escaped braces,
and `{}`. Format strings come from the binary being debugged, and
`formatv` asserts on malformed input. Layouts with a very large width,
such as `{,4000000000}`, would also build a very large string, even in
release builds.
Version 1 formatters are unchanged, except for consuming their
arguments.
Changes to formatter_bytecode.py:
* f-strings are compiled to `@fmt`. Conversions (`{x!r}`) and format
specs (`{x:>8}`) are not supported, and are a compile error.
* String literals, including f-strings, escape quotes and backslashes
when emitting assembly.
* The interpreter's `@fmt` matches the C++ interpreter. It now passes
arguments in stack order, supports `{}`, and follows the `formatv` rules
for braces (`{{` is a literal `{`, and a lone `}` is a literal).
Assisted-by: claude
First this changes how "self" is represented. Previously, self was the
combined stack values after conclusion of `@init` and `@update`. With
this change, self is represented as a Dictionary (see #225955). The self
dictionary is passed to each method. This will aide
`formatter_bytecode.Compiler`, allowing the stack space to be used only
for computation and local variables.
While making calling convention changes, I updated the builtin selector
signatures to use `Integer` instead of `Int`/`UInt` (see #220665)
Assisted-by: claude
Add a dictionary data type to formatter bytecode.
This addition will help in two ways:
1. A subsequent change will use dictionaries to model "self" ("this")
2. Many formatters internal use a dictionary as an implementation
detail, and this will allow such formatters to be compiled/ported to
formatter bytecode
Assisted-by: claude
Adopt a single representation for integers in the formatter bytecode
interpreter. This simplifies code generation, where the (now deprecated)
distinction of `uint64_t` and `int64_t` types could make conditionals
and other operations more complicated, by having to have code paths for
signed and unsigned.
Depends on https://github.com/llvm/llvm-project/pull/218801
Assisted-by: claude
Currently, formatv erases types using a base class and calls the virtual
function format() to format the objects. To avoid these vtables,
refactor formatv to instead store function_refs to a functor (struct
with overloaded operator()). This saves ~5kiB in vtables.
Additionally, add a static assertion that a formatter is present instead
of relying on errors due to missing templates. This requires a little
change to MLIR's tgfmt to use a different name -- previously, the
substitution failure on ArrayRef<> would cause the variadic function to
be skipped, but a static assertion failure is not a substitution error.
Also, simplify the code in FormatVariadicDetails to use if constexpr
instead of template overloads with enable_if, making the code shorter
and easier to read.
`AddressSize` parameter is not used by `DataExtractor` and will be
removed in the future. See #190519 for more context.
This also removes two of the four related methods:
```
DataExtractor::GetAsLLVM()
DataExtractor::GetAsLLVMDWARF() - removed as unused
DWARFDataExtractor::GetAsLLVM() - removed as redundant, it hid the equivalent method of DataExtractor
DWARFDataExtractor::GetAsLLVMDWARF()
```
That is, now we have:
```
DataExtractor::GetAsLLVM()
DWARFDataExtractor::GetAsLLVMDWARF()
```
lldb had three preprocessor defines for logging,
LLDB_LOG - formatv style argument
LLDB_LOGF - printf style argument
LLDB_LOGV - formatv style argument, only when verbose enabled
If you weren't looking at Log.h and the definition of these three, and
wanted to log something with formatv, it was easy to use LLDB_LOGV by
accident. We just had a situation where an important log statement
wasn't logging and it turned out to be this. This is fragile if you
aren't looking at the header directly, so I'd like to make this more
explicit. My proposal:
LLDB_LOG - formatv style argument
LLDB_LOG_VERBOSE - formatv style argument, only when verbose enabled
LLDB_LOGF - printf style argument
LLDB_LOGF_VERBOSE - printf style argument, only when verbose enabled
The new fouth one is to remove several places where we do `if (log &&
log->GetVerbose()) LLDB_LOGF (...)` in the sources today, and make both
styles consistent.
This PR implements that change, mechanically changing all LLDB_LOGV's to
LLDB_LOG_VERBOSE.
It also updates many of the `if (log && log->GetVerbose()) LLDB_LOGF`'s.
Some uses of this conditional expression do extra calculations in
addition to logging, and so those were left as-is so we're not doing
throwaway work when running without verbose logging.
There were many instances throughout lldb where callers are still doing
`if (log) LLDB_LOG*(...)`, a remnant of when all calls were to the `Log`
object's `Printf()` method, and you had to check if your local Log*
pointer was non-nullptr before calling the method. I removed those,
again keeping ones where work for logging is done in the block of code.
The code changes are all mechanical and uninteresting, but the question
of whether this naming change is widely agreed on is maybe worth
discussing.
`GetSyntheticValue` in synthetic providers which need to operate on raw
root values, but will often want to use the synthetic value of children,
or nested children.
Compared to the python version, this also does type checking and error
handling, so it's slightly longer, however, it's still comfortably
under 500 lines.
Relanding with more explicit type conversions.
This reverts commit f6012a209d.
Revert "[lldb] Add cast to fix compile error on 32-but platforms"
This reverts commit d300337e93.
Revert "[lldb] Improve log message to include missing strings"
This reverts commit 0be3348485.
Revert "[lldb] Add comment"
This reverts commit e2bb47443d.
Revert "[lldb] Implement a formatter bytecode interpreter in C++"
This reverts commit 9a9c1d4a61.
Compared to the python version, this also does type checking and error
handling, so it's slightly longer, however, it's still comfortably
under 500 lines.