There was a bug in both the GNU and libc++ library synthetic child
providers when a typedef was used in the type of the variable. Previous
code was looking at the top level typename to try and determine if
std::unordered_ was a map or set and this failed when typedefs were
being used. This patch fixes both C++ library synthetic child providers
with updated tests.
ValueObject is part of lldbCore for historical reasons, but conceptually
it deserves to be its own library. This does introduce a (link-time) circular
dependency between lldbCore and lldbValueObject, which is unfortunate
but probably unavoidable because so many things in LLDB rely on
ValueObject. We already have cycles and these libraries are never built
as dylibs so while this doesn't improve the situation, it also doesn't
make things worse.
The header includes were updated with the following command:
```
find . -type f -exec sed -i.bak "s%include \"lldb/Core/ValueObject%include \"lldb/ValueObject/ValueObject%" '{}' \;
```
This patch is in preparation for the `__compressed_pair` refactor in
https://github.com/llvm/llvm-project/pull/76756.
This is mostly reviewable now. With the new layout we no longer need to
unwrap the `__compressed_pair`. Instead, we just need to look for child
members. E.g., to get to the underlying pointer of `std::unique_ptr` we
no longer do,
```
GetFirstValueOfCXXCompressedPair(GetChildMemberWithName("__ptr_"))
```
but instead do
```
GetChildMemberWithName("__ptr_")
```
We need to be slightly careful because previously the
`__compressed_pair` had a member called `__value_`, whereas now
`__value_` might be a member of the class that used to hold the
`__compressed_pair`. So before unwrapping the pair, we added checks for
`isOldCompressedLayout` (not sure yet whether folding this check into
`GetFirstValueOfCXXCompressedPair` is better).
Depends on:
* https://github.com/llvm/llvm-project/pull/97544
* https://github.com/llvm/llvm-project/pull/97549
* https://github.com/llvm/llvm-project/pull/97551
This patch tries to simplify the way in which the `std::map` formatter
goes from the root `__tree` pointer to a specific key/value pair.
Previously we would:
1. synthesize a structure that mimicked what `__iter_pointer` looked
like in memory
2. call `GetChildCompilerTypeAtIndex` on it to find the byte offset at
which the pair was located in the synthesized structure
3. finally, use that offset through a call to
`GetSyntheticChildAtOffset` to retrieve the key/value pair
Not only was this logic hard to follow, and encoded the libc++ layout in
non-obvious ways, it was also fragile to alignment miscalculations
(https://github.com/llvm/llvm-project/pull/97443); this would break once
the new layout of std::map landed as part of
https://github.com/https://github.com/llvm/llvm-project/issues/93069.
Instead, this patch simply casts the `__iter_pointer` to the
`__node_pointer` and uses a straightforward
`GetChildMemberWithName("__value_")` to get to the key/value we care
about. This allows us to get rid of some support infrastructure/class
state.
Ideally we would fix the underlying alignment issue, but this unblocks
the libc++ refactor in the interim, while also benefitting the formatter
in terms of readability (in my opinion).
Depends on https://github.com/llvm/llvm-project/pull/97687
Similar to https://github.com/llvm/llvm-project/pull/97579, this patch
simplifies the way in which we retrieve the key/value pair of a
`std::map` (in this case of the `std::map::iterator`).
We do this for the same reason: not only was the old logic hard to
follow, and encoded the libc++ layout in non-obvious ways, it was also
fragile to alignment miscalculations
(https://github.com/llvm/llvm-project/pull/97443); this would break once
the new layout of std::map landed as part of
https://github.com/llvm/llvm-project/issues/93069.
Instead, this patch simply casts the `__iter_pointer` to the
`__node_pointer` and uses a straightforward
`GetChildMemberWithName("__value_")` to get to the key/value we care
about.
We can eventually re-use the core-part of the `std::map` and
`std::map::iterator` formatters. But it will be an easier to change to
review once both simplifications landed.
Depends on https://github.com/llvm/llvm-project/pull/97752
This patch changes the way we retrieve the key/value pair in the
`std::unordered_map::iterator` formatter (similar to how we are changing
it for `std::map::iterator` in
https://github.com/llvm/llvm-project/pull/97713, the motivations being
the same).
The old logic was not very easy to follow, and encoded the libc++ layout
in non-obvious ways. But mainly it was also fragile to alignment
miscalculations (https://github.com/llvm/llvm-project/pull/97443); this
would break once the new layout of `std::unordered_map` landed as part
of https://github.com/llvm/llvm-project/issues/93069.
Instead, this patch simply casts the `__hash_iterator` to a
`__node_pointer` (which is what libc++ does too) and uses a
straightforward `GetChildMemberWithName("__value_")` to get to the
key/value we care about.
The `std::unordered_map` already does it this way, so we align the
iterator counterpart to do the same. We can eventually re-use the
core-part of the `std::unordered_map` and `std::unordered_map::iterator`
formatters. But it will be an easier to change to review once both
simplifications landed.
Similar to how we moved the `std::map::iterator` formatter in
https://github.com/llvm/llvm-project/pull/97687, do the same for
`std::unordered_map::iterator`.
Again the `unordered_map` and `unordered_map::iterator` formatters try
to do very similar things: retrieve data out of the map. The iterator
formatter does this in a fragile way (similar to how `std::map` does it,
see https://github.com/llvm/llvm-project/pull/97579). Thus we will be
refactoring the `std::unordered_map::iterator` in upcoming patches.
Having it in `LibCxxUnorderedMap` will allow us to re-use some of the
logic (and we won't have to repeat some of the clarification comments).
We currently supported the layout from pre-2016 (before the layout
change in
[14caaddd3f08e798dcd9ac0ddfc](https://github.com/llvm/llvm-project/commit/14caaddd3f08e798dcd9ac0ddfc)).
We have another upcoming layout change in `__tree` and `map` (as part of
https://github.com/llvm/llvm-project/issues/93069) which will likely
require rewriting parts of this formatter. Removing the support for the
pre-2016 layout will make those changes more straightforward to
review/maintain.
Being backward compatible would be great but we have no tests that
actually verify that the old layout still works (and our oldest matrix
bot tests clang-15). If anyone feels strongly about keeping this layout,
we could possibly factor out that logic and keep it around.
The two formatters follow very similar techniques to retrieve data out
of the map. We're changing this for `std::map` in
https://github.com/llvm/llvm-project/pull/97579 and plan to change it in
the same way for the iterator formatter. Having them in the same place
will allow us to re-use some of the logic (and we won't have to repeat
some of the clarification comments).
This patch factors all the logic for advancing the `MapIterator` out of
`GetChildAtIndex`. This, in my opinion, helps readability, and will be
useful for upcoming cleanups in this area.
While here, some drive-by changes:
* added a couple of clarification comments
* fixed a variable name typo
* turned the `return lldb::ValueObjectSP()` into `return nullptr`
* added an assertion to make sure we keep the iterator cache in a valid
state
Redundant since:
```
commit be3be28b5d
Author: Enrico Granata <egranata@apple.com>
Date: Mon Oct 3 23:33:00 2016 +0000
Changes to the std::multimap formatter to make it work against trunk libc++
Fixes rdar://28237486
llvm-svn: 283160
```
Found while skimming this code. Don't have a reproducible test case for
this but the nullptr check should clearly occur before we try to
dereference `location_sp`.
These proxies are returned by operator[](...). These proxies all
"behave" the same. They store a pointer to the data of the valarray they
are a proxy for and they have an internal array of indices. This
internal array is considered its contents.
This is another step towards supporting DWARF5 checksums and inline
source code in LLDB. This is a reland of #85468 but without the
functional change of storing the support file from the line table (yet).
This caused following warnings in an LLDB build:
```
[237/1072] Building CXX object tools/l...lusLanguage.dir/LibCxxSliceArray.cpp.o
/Volumes/Data/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp:38:53: warning: format specifies type 'unsigned long long' but the argument has type 'size_t' (aka 'unsigned long') [-Wformat]
38 | stream.Printf("stride=%" PRIu64 " size=%" PRIu64, stride, size);
| ~~~~~~~~~ ^~~~~~
/Volumes/Data/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp:38:61: warning: format specifies type 'unsigned long long' but the argument has type 'size_t' (aka 'unsigned long') [-Wformat]
38 | stream.Printf("stride=%" PRIu64 " size=%" PRIu64, stride, size);
| ~~~~~~~~~ ^~~~
2 warnings generated.
```
This patch simply changes the format specifiers to use the `%zu` for
`size_t`s.
Change GetNumChildren()/CalculateNumChildren() methods return
llvm::Expected
This is an NFC change that does not yet add any error handling or change
any code to return any errors.
This is the second big change in the patch series started with
https://github.com/llvm/llvm-project/pull/83501
A follow-up PR will wire up error handling.
Change GetNumChildren()/CalculateNumChildren() methods return
llvm::Expected
This is an NFC change that does not yet add any error handling or change
any code to return any errors.
This is the second big change in the patch series started with
https://github.com/llvm/llvm-project/pull/83501
A follow-up PR will wire up error handling.
This formatter
https://github.com/llvm/llvm-project/pull/78609
was originally passing the signed seconds (which can refer to times in
the past) with an unsigned printf formatter, and had tests that expected
to see negative values from the printf which always failed on macOS. I'm
not clear how they ever passed on any platform.
Fix the printf to print seconds as a signed value, and re-enable the
tests.
This avoids duplicating the logic to get the first
element of a libc++ `__compressed_pair`. This will
be useful in supporting upcoming changes to the layout
of `__compressed_pair`.
Drive-by changes:
* Renamed `m_item` to `size_node` for readability;
`m_item` suggests it's a member variable, which it
is not.
The `(( )?&)?` appears to match types which are references. However lldb
can load the
correct data formatters without having to pattern match against a `&`
suffix.
The suffix may have been needed at one point, but it's no longer needed.
This patch fixes:
lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp:1108:39: error:
format specifies type 'long long' but the argument has type
'std::time_t' (aka 'long') [-Werror,-Wformat]
lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp:1116:64: error:
format specifies type 'long long' but the argument has type
'std::time_t' (aka 'long') [-Werror,-Wformat]
This fixes:
```
[6331/7452] Building CXX object tools\lldb\source\Plugins\Language\CPlusPlus\CMakeFiles\lldbPluginCPlusPlusLanguage.dir\LibCxx.cpp.obj
C:\git\llvm-project\lldb\source\Plugins\Language\CPlusPlus\LibCxx.cpp(1108,38): warning: format specifies type 'long' but the argument has type 'std::time_t' (aka 'long long') [-Wformat]
1108 | stream.Printf("timestamp=%ld s", seconds);
| ~~~ ^~~~~~~
| %lld
C:\git\llvm-project\lldb\source\Plugins\Language\CPlusPlus\LibCxx.cpp(1116,63): warning: format specifies type 'long' but the argument has type 'std::time_t' (aka 'long long') [-Wformat]
1116 | stream.Printf("date/time=%s timestamp=%ld s", str.data(), seconds);
| ~~~ ^~~~~~~
| %lld
2 warnings generated.
```
This fixes missing inlined function names when formatting frame and the
`Block` in `SymbolContext` is a lexical block (e.g.
`DW_TAG_lexical_block` in Dwarf).
This is a followup of #76983 and adds the libc++ data formatters for
- weekday,
- weekday_indexed,
- weekday_last,
- month_weekday,
- month_weekday_last,
- year_month,
- year_month_day_last
- year_month_weekday, and
- year_month_weekday_last.
This adds a subset of the C++20 calendar data formatters:
- day,
- month,
- year,
- month_day,
- month_day_last, and
- year_month_day.
A followup patch will add the missing calendar data formatters:
- weekday,
- weekday_indexed,
- weekday_last,
- month_weekday,
- month_weekday_last,
- year_month,
- year_month_day_last
- year_month_weekday, and
- year_month_weekday_last.
This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.
I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
Add the ability to get a C++ vtable ValueObject from another
ValueObject.
This patch adds the ability to ask a ValueObject for a ValueObject that
represents the virtual function table for a C++ class. If the
ValueObject is not a C++ class with a vtable, a valid ValueObject value
will be returned that contains an appropriate error. If it is successful
a valid ValueObject that represents vtable will be returned. The
ValueObject that is returned will have a name that matches the demangled
value for a C++ vtable mangled name like "vtable for <class-name>". It
will have N children, one for each virtual function pointer. Each
child's value is the function pointer itself, the summary is the
symbolication of this function pointer, and the type will be a valid
function pointer from the debug info if there is debug information
corresponding to the virtual function pointer.
The vtable SBValue will have the following:
- SBValue::GetName() returns "vtable for <class>"
- SBValue::GetValue() returns a string representation of the vtable
address
- SBValue::GetSummary() returns NULL
- SBValue::GetType() returns a type appropriate for a uintptr_t type for
the current process
- SBValue::GetLoadAddress() returns the address of the vtable adderess
- SBValue::GetValueAsUnsigned(...) returns the vtable address
- SBValue::GetNumChildren() returns the number of virtual function
pointers in the vtable
- SBValue::GetChildAtIndex(...) returns a SBValue that represents a
virtual function pointer
The child SBValue objects that represent a virtual function pointer has
the following values:
- SBValue::GetName() returns "[%u]" where %u is the vtable function
pointer index
- SBValue::GetValue() returns a string representation of the virtual
function pointer
- SBValue::GetSummary() returns a symbolicated respresentation of the
virtual function pointer
- SBValue::GetType() returns the function prototype type if there is
debug info, or a generic funtion prototype if there is no debug info
- SBValue::GetLoadAddress() returns the address of the virtual function
pointer
- SBValue::GetValueAsUnsigned(...) returns the virtual function pointer
- SBValue::GetNumChildren() returns 0
- SBValue::GetChildAtIndex(...) returns invalid SBValue for any index
Examples of using this API via python:
```
(lldb) script vtable = lldb.frame.FindVariable("shape_ptr").GetVTable()
(lldb) script vtable
vtable for Shape = 0x0000000100004088 {
[0] = 0x0000000100003d20 a.out`Shape::~Shape() at main.cpp:3
[1] = 0x0000000100003e4c a.out`Shape::~Shape() at main.cpp:3
[2] = 0x0000000100003e7c a.out`Shape::area() at main.cpp:4
[3] = 0x0000000100003e3c a.out`Shape::optional() at main.cpp:7
}
(lldb) script c = vtable.GetChildAtIndex(0)
(lldb) script c
(void ()) [0] = 0x0000000100003d20 a.out`Shape::~Shape() at main.cpp:3
```