In #186001, I said the last large chunk of downstream PtrAuth code in
LLDB was the expression evaluator support. However, that wasn't
accurate, as we also have changes to thread this through ValueObject.
Currently these functions take a target pointer. In Cross-language
projects this means it's down to chance what typesystem the resulting
value will be in, since the implementation returns the first scratch
type system in the target, which depends on the order of images and
their implementation language.
By passing in an execution context the selected frame is used to
determine the typesystem, which is usually the expected outcome when
using DIL.
This should be entirely NFC for Clang-only LLDBs, but is a necessity for
LLDBs with additional type system plugins such as the Swift plugin.
Assisted by Claude to patch the call sites.
The code was declaring a shared poiner and then immediately trying to
dereference it to initialize it's contents, but the dereference was
giving a seg fault. This fixes that issue.
This makes the constructions of string errors more concise and more
consistent, mainly by removing the `inconvertibleErrorCode()`.
Additional changes replace `createStringError(formatv(...), ...)` with
`createStringErrorV(...)`.
Assisted-by: Claude
Synthetic providers for collection types use a child name format of
"[N]".
This `ValueObjectSynthetic` to automatically convert child names in this
convention to the index embedded in the subscript string. With this
change, synthetic formatters for collections will only need to implement
`GetIndexOfChildWithName` or `get_child_index` for non-indexed
collection children. Some examples of non-indexed children are
`$$dereference$$` support, or "hidden" children.
The automatic conversion applies to N values that are less than the
number of children reported by the synthetic provider.
Adding more supported operators to DIL breaks tests in `DWIMPrint` and
`lldb-dap`, which shouldn't be simply adjusted for new DIL capabilities.
They act as a check for the boundaries of what subset of expressions
`DWIMPrint` and `lldb-dap` expect to be evaluated when using
`GetValueForVariableExpressionPath` function. With this patch, the
caller can now pick a mode that limits the expressions DIL can evaluate,
which ensures the expected preexisting behavior. More operators can now
be safely added to DIL, which can still be evaluated by DIL when using
`frame var` command or the API call with Full mode selected (or not
specified at all).
DIL will only attempt evaluating expressions that contain operations
allowed by a selected mode:
- Simple: identifiers, operators: '.'
- Legacy: identifiers, integers, operators: '.', '->', '*', '&', '[]'
- Full: everything supported by DIL
This patch re-implements `TypeSystemClang::IsFloatingPointType` by
forwarding it to `clang::Type::isFloatingType`. The main difference is
that the latter returns false for float vector types. The motovation
here (apart from implementation simplicity) is that this is currently a
foot-gun because most callsites probably don't consider treating float
vector types. Callers should test for vectors explicitly using
`IsVectorType` (or use `GetTypeInfo`).
This patch makes all the callers of `IsFloatingPointType` now check
`GetTypeInfo() & eTypeIsFloat`. This is set for float vector types too,
so behaviour doesn't change.
To make sure we audit all the call-sites in `ValueObject.cpp`, I added a
helper `HasFloatRepresentation` (named after the
`clang::Type::hasFloatingRepresentation` API), which does the
`GetTypeInfo` check, and added a FIXME to it.
This patch moves ValueImpl and ValueLocker to ValueObject.{h,cpp}. This follows the example set in TypeImpl/SBType, where we have something that SBType uses internally that needs to be exposed in the layer below. In this case, SBValue uses ValueImpl, which wraps ValueObject. The wrapper helps avoid bugs, so we want to keep it, but the script interpreter needs to use it and said interpreter is conceptually *below* the SB layer...which means we can't use methods on SBValue.
This patch is purely the code motion part of that, future patches will actually make use of this moved code.
Corrected various spelling mistakes such as 'occurred', 'receiver',
'initialized', 'length', and others in comments, variable names,
function names, and documentation throughout the project. These
changes improve code readability and maintain consistency in naming
and documentation.
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
Consider the following program:
```
int main() {
int foo[2][3][4];
int (*bar)[3][4] = foo;
return 0;
}
```
If we:
- compile this program
- launch an LLDB debugging session
- launch the process and let it stop at the `return 0;` statement
then the following LLDB command:
```
(lldb) script lldb.frame.FindVariable("bar").GetChildAtIndex(0).get_expr_path()
```
will produce the following output:
```
bar->[0]
```
What we were expecting:
- a valid expression in the C programming language
- that would allow us (in the scope of the `main` function) access the
appropriate object.
What we've got is a string that does not represent a valid expression in
the C programming language.
This pull-request proposes a fix to this problem.
---------
Co-authored-by: Matej Košík <matej.kosik@codasip.com>
This PR implements the actual type casting part. With this, type casting
to builtin types should work. The third PR, which will be put up after
this one is merged, will expand the type name parsing to allow casting
to user-defined types.
1. Every `ASTNodeUP` is asserted before being used in creating another
`ASTNodeUP`.
2. Removed returning `nullptr` in `ParseIntegerLiteral` and
`ParseFloatingPointLiteral` to avoid confusion.
3. All `ASTNodes` are now passed by reference instead of pointer.
Vector registers have synthetic values for display purposes. This causes
SBValue::GetExpressionPath to dispatch
to ValueObjectSynthetic instead of ValueObjectRegister, producing
incorrect results.
Fixes#147144
This is an alternative to
https://github.com/llvm/llvm-project/pull/159500, breaking that PR down
into three separate PRs, to make it easier to review.
This first PR of the three adds the basic framework for doing type
casing to the DIL code, but it does not actually do any casting: In this
PR the DIL parser only recognizes builtin type names, and the DIL
interpreter does not do anything except return the original operand (no
casting). The second and third PRs will add most of the type parsing,
and do the actual type casting, respectively.
NFC patch which moves `DiagnosticsRendering` from `Utility` to `Host`.
This refactoring is needed for
https://github.com/llvm/llvm-project/pull/168603. It adds a method to
check whether the current terminal supports Unicode or not. This will be
OS dependent and a better fit for `Host`. Since `Utility` cannot depend
on `Host`, `DiagnosticsRendering` must live in `Host` instead.
This is a fixed version of #167886.
The build previously failed with `BUILD_SHARED_LIBS=ON`. After trying
that locally, I uncovered a few other instances of lldb non-plugin
libraries depending on clang transitively through lldbValueObject, so I
added the correct clang libraries to their dependencies.
Reverts llvm/llvm-project#167794
This breaks a build with BUILD_SHARED_LIBS=ON:
/usr/bin/ld: lib/liblldbCommands.a(CommandObjectTarget.cpp.o): undefined
reference to symbol '_ZN5clang22PCHContainerOperationsC1Ev
Fixing that issue leads to similar failures due to different symbols.
The ValueObject library doesn't actually depend on any plugins
currently, but it links against the C++ and ObjC language plugins. I
removed those and added NO_PLUGIN_DEPENDENCIES.
However, the build failed initally because the Commands library depends
on clangFrontend and it was previously getting it transitively through
ValueObject -> C++/ObjC Language -> clangFrontend. This makes the
dependency more explicit.
There were a couple of quirks with this parameter:
1. It wasn't being set consistently. E.g., vector types would be of
count `1` but complex types would be `2`. Hence, it wasn't clear what
count was referring to.
2. `count` was not being set if the input type was invalid, possibly
leaving the input reference uninitialized.
3. Only one callsite actually made use of `count`, and that in itself
seems like it could be improved (added a FIXME).
If we ever need a "how many elements does this type represent", we can
implement one with a new `TypeSystem` API that does exactly that.
This adds the ability to recognize (and create ValueObjects for) boolean
literals ("true", "false") to DIL. This is a preliminary step to adding
type casting (and also for the ternary op).
This patch introduces `ScalarLiteralNode` without any uses by other
nodes yet. It also includes lexing and parsing for integer and floating
point numbers.
Reapplies #152308 with a fix.
This patch introduces `ScalarLiteralNode` without any uses by other
nodes yet. It also includes lexing and parsing for integer and floating
point numbers.
This attempts to fix the issues with the original PR (#151605), updating
the DIL code for handling array subscripting to more closely match and
handle all the casees from the original 'frame var' implementation. The
first PR did not include special-case code for objc pointers, which
apparently caused a test failure on the green-dragon buildbot. Hopefully
this PR, which includes the objc pointer special code, fixes that issue.
This updates the DIL code for handling array subscripting to more
closely match and handle all the cases from the original 'frame var'
implementation. Also updates the DIL array subscripting test. This
particularly fixes some issues with handling synthetic children, objc
pointers, and accessing specific bits within scalar data types.
Add `ValueObject::CreateValueObjectFromScalar` function and adjust
`Scalar::GetData` to be able to both extend and truncate the data bytes
in Scalar to the specified size.
`SBType::GetBasicType` fails on typedefs to primitive types. The docs
for `GetBasicType` state:
```
Returns the BasicType value that is most appropriate to this type
```
But, e.g., for `uint64_t` this would currently return
`eBasicTypeInvalid`.
`TypeSystemClang::GetBasicTypeEnumeration` (which is what
`SBType::GetBasicType` uses) doesn't see through typedefs. Inside LLDB
we almost always call `GetBasicTypeEnumeration` on the canonical type.
In the cases we don't I suspect those were just subtle bugs. This patch
gets the canonical type inside of `GetBasicTypeEnumeration` instead.
rdar://155829208
As a preliminary to making DIL the default implementation for
'frame var', ran check-lldb forcing 'frame var' to always use DIL,
and discovered a few failing tests. This fixes most of them. The only
remaining failing test is TestDAP_evaluate.py, which now passes
a test case that the test says should fail (still investigating this).
Changes in this PR:
- Sets correct VariableSP, as well as returning ValueObjectSP (needed
for several watchpoint tests).
- Updates error messages, when looking up members, to match what the
rest of LLDB expects. Also update appropriate DIL tests to expect the
updated error messages.
- Updates DIL parser to look for and accept "(anonymous namespace)::" at
the front of a variable name.
This updates the DIL implementation to handle smart pointers (accessing
field members and dereferencing) in the same way the current 'frame
variable' implementation does. It also adds tests for handling smart
pointers, as well as some additional DIL tests.
If we're not touching them, we don't need to do anything special to pass
them along -- with one important caveat: due to how cmake arguments
work, the implicitly passed arguments need to be specified before
arguments that we handle.
This isn't particularly nice, but the alternative is enumerating all
arguments that can be used by llvm_add_library and the macros it calls
(it also relies on implicit passing of some arguments to
llvm_process_sources).