summaryrefslogtreecommitdiff
path: root/lldb/source/Core/ValueObject.cpp
AgeCommit message (Collapse)Author
2024-10-24[lldb] Move ValueObject into its own library (NFC) (#113393)Jonas Devlieghere
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%" '{}' \; ```
2024-10-24Fix pointer to reference type (#113596)jeffreytan81
We have got customer reporting "v &obj" and "p &obj" reporting different results. Turns out it only happens for obj that is itself a reference type which "v &obj" reports the address of the reference itself instead of the target object the reference points to. This diverged from C++ semantics. This PR fixes this issue by returning the address of the dereferenced object if it is reference type. A new test is added which fails before. Co-authored-by: jeffreytan81 <jeffreytan@fb.com>
2024-09-10[LLDB][Data Formatters] Calculate average and total time for summary ↵Jacob Lalonde
providers within lldb (#102708) This PR adds a statistics provider cache, which allows an individual target to keep a rolling tally of it's total time and number of invocations for a given summary provider. This information is then available in statistics dump to help slow summary providers, and gleam more into insight into LLDB's time use.
2024-09-05[lldb] Make deep copies of Status explicit (NFC) (#107170)Adrian Prantl
2024-08-27[lldb] Turn lldb_private::Status into a value type. (#106163)Adrian Prantl
This patch removes all of the Set.* methods from Status. This cleanup is part of a series of patches that make it harder use the anti-pattern of keeping a long-lives Status object around and updating it while dropping any errors it contains on the floor. This patch is largely NFC, the more interesting next steps this enables is to: 1. remove Status.Clear() 2. assert that Status::operator=() never overwrites an error 3. remove Status::operator=() Note that step (2) will bring 90% of the benefits for users, and step (3) will dramatically clean up the error handling code in various places. In the end my goal is to convert all APIs that are of the form ` ResultTy DoFoo(Status& error) ` to ` llvm::Expected<ResultTy> DoFoo() ` How to read this patch? The interesting changes are in Status.h and Status.cpp, all other changes are mostly ` perl -pi -e 's/\.SetErrorString/ = Status::FromErrorString/g' $(git grep -l SetErrorString lldb/source) ` plus the occasional manual cleanup.
2024-06-20Refactor GetObjectDescription() to return llvm::Expected (NFC)Adrian Prantl
This is de facto an NFC change for Objective-C but will benefit the Swift language plugin.
2024-06-20Convert ValueObject::Dump() to return llvm::Error() (NFCish)Adrian Prantl
This change by itself has no measurable effect on the LLDB testsuite. I'm making it in preparation for threading through more errors in the Swift language plugin.
2024-06-13[LLDB] Add more helper functions to ValueObject class. (#87197)cmtice
Create additional helper functions for the ValueObject class, for: - returning the value as an APSInt or APFloat - additional type casting options - additional ways to create ValueObjects from various types of data - dereferencing a ValueObject These helper functions are needed for implementing the Data Inspection Language, described in https://discourse.llvm.org/t/rfc-data-inspection-language/69893
2024-06-07[lldb] Split ValueObject::CreateChildAtIndex into two functions (#94455)Pavel Labath
The the function is doing two fairly different things, depending on how it is called. While this allows for some code reuse, it also makes it hard to override it correctly. Possibly for this reason ValueObjectSynthetic overerides GetChildAtIndex instead, which forces it to reimplement some of its functionality, most notably caching of generated children. Splitting this up makes it easier to move the caching to a common place (and hopefully makes the code easier to follow in general).
2024-06-05[lldb] UpdateFormatsIfNeeded should respect the dynamic value type (#93262)Augusto Noronha
UpdateFormatsIfNeeded has hardcoded the call to GetFormat with no dynamic values. GetFormat will try to find the synthetic children of the ValueObject, and passing the wrong one can fail, which can be bad for performance but should not be user visible. Fix the performace bug by passing the dynamic value type of the ValueObject. rdar://122506593
2024-05-22Change GetChildCompilerTypeAtIndex to return Expected (NFC) (#92979)Adrian Prantl
This change is a general improvement of the internal API. My motivation is to use this in the Swift typesystem plugin.
2024-03-11Make ValueObject::Cast work for casts from smaller to larger structs in the ↵jimingham
cases where this currently can work. (#84588) The ValueObjectConstResult classes that back expression result variables play a complicated game with where the data for their values is stored. They try to make it appear as though they are still tied to the memory in the target into which their value was written when the expression is run, but they also keep a copy in the Host which they use after the value is made (expression results are "history values" so that's how we make sure they have "the value at the time of the expression".) However, that means that if you ask them to cast themselves to a value bigger than their original size, they don't have a way to get more memory for that purpose. The same thing is true of ValueObjects backed by DataExtractors, the data extractors don't know how to get more data than they were made with in general. The only place where we actually ask ValueObjects to sample outside their captured bounds is when you do ValueObject::Cast from one structure type to a bigger structure type. In https://reviews.llvm.org/D153657 I handled this by just disallowing casts from one structure value to a larger one. My reasoning at the time was that the use case for this was to support discriminator based C inheritance schemes, and you can't directly cast values in C, only pointers, so this was not a natural way to handle those types. It seemed logical that since you would have had to start with pointers in the implementation, that's how you would write your lldb introspection code as well. Famous last words... Turns out there are some heavy users of the SB API's who were relying on this working, and this is a behavior change, so this patch makes this work in the cases where it used to work before, while still disallowing the cases we don't know how to support. Note that if you had done this Cast operation before with either expression results or value objects from data extractors, lldb would not have returned the correct results, so the cases this patch outlaws are ones that actually produce invalid results. So nobody should be using Cast in these cases, or if they were, this patch will point out the bug they hadn't yet noticed.
2024-03-08Change GetNumChildren()/CalculateNumChildren() methods return llvm::Expected ↵Adrian Prantl
(#84219) 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.
2024-03-08Revert "Change GetNumChildren()/CalculateNumChildren() methods return ↵Florian Mayer
llvm::Expected (#84219)" This reverts commit 99118c809367d518ffe4de60c16da953744b68b9.
2024-03-08Change GetNumChildren()/CalculateNumChildren() methods return llvm::Expected ↵Adrian Prantl
(#84219) 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.
2024-03-07Change Get|SetNumChildren to use unint32_tAdrian Prantl
2024-03-07Change GetChildAtIndex to take a uint32_tAdrian Prantl
2024-02-14[lldb] Add comment on cross printing of summary/value (#81681)Dave Lee
Adds a comment to indicate intention of a piece of value printing code. I was initially surprised to see this code (distilled for emphasis): ```cpp if (str.empty()) { if (style == eValueObjectRepresentationStyleValue) str = GetSummaryAsCString(); else if (style == eValueObjectRepresentationStyleSummary) str = GetValueAsCString(); } ``` My first thought was "is this a bug?", but I realized it was likely intentional. This change adds a comment to indicate yes, this is intentional.
2024-02-12Make ValueObjectPrinter's handling of its ValueObject pointers more ↵jimingham
principled (NFC) (#81314) I get a small but fairly steady stream of crash reports which I can only explain by ValueObjectPrinter trying to access its m_valobj field, and finding it NULL. I have never been able to reproduce any of these, and the reports show a state too long after the fact to know what went wrong. I've read through this section of lldb a bunch of times trying to figure out how this could happen, but haven't ever found anything actually wrong that could cause this. OTOH, ValueObjectPrinter is somewhat sloppy about how it handles the ValueObject it is printing. a) lldb allows you to make a ValueObjectPrinter with a Null incoming ValueObject. However, there's no affordance to set the ValueObject in the Printer after the fact, and it doesn't really make sense to do that. So I change the ValueObjectPrinter API's to take a ValueObject reference, rather than a pointer. All the places that make ValueObjectPrinters already check the non-null status of their ValueObject's before making the ValueObjectPrinter, so sadly, I didn't find the bug, but this will enforce the intent. b) The next step in printing the ValueObject is deciding which of the associated DynamicValue/SyntheticValue we are actually printing (based on the use_dynamic and use_synthetic settings in the original ValueObject. This was put in a pointer by GetMostSpecializedValue, but most of the printer code just accessed the pointer, and it was hard to reason out whether we were guaranteed to always call this before using m_valobj. So far as I could see we always do (sigh, didn't find the bug there either) but this was way too hard to reason about. In fact, we figure out once which ValueObject we're going to print and don't change that through the life of the printer. So I changed this to both set the "most specialized value" in the constructor, and then to always access it through GetMostSpecializedValue(). That makes it easier to reason about the use of this ValueObject as well. This is an NFC change, all it does is make the code easier to reason about.
2024-01-24Revert "[lldb] Improve maintainability and readability for ValueObject ↵Pavel Labath
methods (#75865)" This reverts commit d657519838e4b2310e13ec5ff52599e041860825 as it breaks two dozen tests. The breakages are related to variable path expression parsing and summary string parsing (possibly the same code).
2024-01-23[lldb] Improve maintainability and readability for ValueObject methods (#75865)Pete Lawrence
As I worked through changes to another PR (https://github.com/llvm/llvm-project/pull/74912), I couldn't help but rewrite a few methods for readability, maintainability, and possibly some behavior correctness too. 1. Exiting early instead of nested `if`-statements, which: - Reduces indentation levels for all subsequent lines - Treats missing pre-conditions similar to an error - Clearly indicates that the full length of the method is the "happy path". 2. Explicitly return empty Value Object shared pointers for those error (like) situations, which - Reduces the time it takes a maintainer to figure out what the method actually returns based on those conditions. 3. Converting a mix of `if` and `if`-`else`-statements around an enum into one `switch` statement, which: - Consolidates the former branching logic - Lets the compiler warn you of a (future) missing enum case - This one may actually change behavior slightly, because what was an early test for one enum case, now happens later on in the `switch`. 4. Consolidating near-identical, "copy-pasta" logic into one place, which: - Separates the common code to the diverging paths. - Highlights the differences between the code paths. rdar://119833526
2024-01-15[lldb][ValueObject][NFC] Further remove redundant parameters to ↵Michael Buch
ReadPointedString (#78029) We only ever call this function once, without relying on the defaulted `honor_array` parameter, so make it non-defaulted. Also `max_length` is always set to `0`, so remove it entirely. This simplifies some upcoming refactoring.
2024-01-12[lldb][ValueObject][NFC] Remove unused parameter to ReadPointedString (#77919)Michael Buch
All its usages were removed in `2206b48d6ddabad61979fa69ba09e6b6fb19b0b2`.
2023-12-19[lldb] Remove unused GetChildAtIndexPath(...) methods from ValueObject.cpp ↵Pete Lawrence
(#75870) This a follow-up PR from this other one: https://github.com/llvm/llvm-project/pull/74413 Nothing calls into these two methods, so we (@DavidSpickett, @adrian-prantl, and I) agreed to remove them once we merged the previous PR.
2023-12-16[lldb] Use StringRef::{starts,ends}_with (NFC)Kazu Hirata
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.
2023-12-13[lldb] Return index of element in ValueObject path instead of the element's ↵Pete Lawrence
value (#74413) It's more meaningful and actionable to indicate which element in the array has an issue by returning that element's index instead of its value. The value can be ambiguous if at least one other element has the same value. The first parameter for these methods is `idxs`, an array of indices that represent a path from a (root) parent to on of its descendants, typically though intermediate descendants. When the path leads to a descendant that doesn't exist, the method is supposed to indicate where things went wrong by setting an index to `&index_of_error`, the second parameter. The problem is the method sets `*index_of_error` to the index of the most recent parent's child in the hierarchy, which isn't very useful if there's more one index with the same value in the path. In this example, each element in the path has a value that's the same as another element. ```cpp GetChildAtIndexPath({1, 2, 3, 3, 1, 1, 2}, &index_of_error); ``` Say the the second `1` in the path (the 5th element at `[4]`) doesn't exist and the code returns a `nullptr`. In that situation, the code sets `*index_of_error` to `1`, but that's an ambiguous hint can implicate the 1st, 5th, or 6th element (at `[0]`, `[4]`, or `[5]`). It’s more helpful to set `*index_of_error` to `4` to clearly indicate which element in `idxs` has the issue.
2023-11-08Simplify ValueObject::GetQualifiedRepresentationIfAvailable(). (#71559)Adrian Prantl
I received a couple of nullptr-deref crash reports with no line numbers in this function. The way the function was written it was a bit diffucult to keep track of when result_sp could be null, so this patch simplifies the function to make it more obvious when a nullptr can be contained in the variable.
2023-10-30Add the ability to get a C++ vtable ValueObject from another ValueObj… ↵Greg Clayton
(#67599) 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 ```
2023-09-13[lldb] Accept optional module in Value::ResolveValue (#66286)Augusto Noronha
Value::ResolveValue calls Value::GetValueAsData as part of its implementation. The latter can receive an optional Module pointer, which is always null when called from the former. Allow threading in the Module in Value::ResolveValue. rdar://115021869
2023-08-30[lldb] Allow synthetic providers in C++ and fix linking problemswalter erquinigo
- Allow the definition of synthetic formatters in C++ even when LLDB is built without python scripting support. - Fix linking problems with the CXXSyntheticChildren Differential Revision: https://reviews.llvm.org/D158010
2023-08-17[lldb][NFCI] Remove unneeded ConstString from ↵Alex Langford
ValueObject::GetValueForExpressionPath_Impl Differential Revision: https://reviews.llvm.org/D158026
2023-08-16[lldb][NFCI] Remove unused method overload of ValueObject::GetChildAtNamePathAlex Langford
Differential Revision: https://reviews.llvm.org/D158024
2023-06-26Don't allow SBValue::Cast to cast from a smaller type to a larger,Jim Ingham
as we don't in general know where the extra data should come from. Differential Revision: https://reviews.llvm.org/D153657
2023-06-13[lldb] Default can_create to true in GetChildAtIndex (NFC)Dave Lee
Existing callers of `GetChildAtIndex` pass true for can_create. This change makes true the default value, callers don't have to pass an opaque true. See also D151966 for the same change to `GetChildMemberWithName`. Differential Revision: https://reviews.llvm.org/D152031
2023-06-13[lldb] Default can_create to true in GetChildMemberWithName (NFC)Dave Lee
It turns out all existing callers of `GetChildMemberWithName` pass true for `can_create`. This change makes `true` the default value, callers don't have to pass an opaque true. Differential Revision: https://reviews.llvm.org/D151966
2023-06-01[lldb] Take StringRef names in GetChildAtNamePath (NFC)Dave Lee
Following D151810, this changes `GetChildAtNamePath` to take a path of `StringRef` values instead of `ConstString`. Differential Revision: https://reviews.llvm.org/D151813
2023-06-01[lldb] Take StringRef name in GetIndexOfChildWithName (NFC)Dave Lee
As with D151615, which changed `GetIndexOfChildMemberWithName` to take a `StringRef` instead of a `ConstString`, this change does the same for `GetIndexOfChildWithName`. Differential Revision: https://reviews.llvm.org/D151811
2023-05-31[lldb] Take StringRef name in GetIndexOfChildMemberWithName (NFC)Dave Lee
Change the type of the `name` parameter from `char *` to `StringRef`. Follow up to D151615. Differential Revision: https://reviews.llvm.org/D151810
2023-05-31[lldb] Take StringRef name in GetChildMemberWithName (NFC)Dave Lee
`GetChildMemberWithName` does not need a `ConstString`. This change makes the function take a `StringRef` instead, which alleviates the need for callers to construct a `ConstString`. I don't expect this change to improve performance, only ergonomics. This is in support of Alex's effort to replace `ConstString` where appropriate. There are related `ValueObject` functions that can also be changed, if this is accepted. Differential Revision: https://reviews.llvm.org/D151615
2023-04-21Make sure SelectMostRelevantFrame happens only when returning to the user.Jim Ingham
This is a user facing action, it is meant to focus the user's attention on something other than the 0th frame when you stop somewhere where that's helpful. For instance, stopping in pthread_kill after an assert will select the assert frame. This is not something you want to have happen internally in lldb, both because internally you really don't want the selected frame changing out from under you, and because the recognizers can do arbitrary work, and that can cause deadlocks or other unexpected behavior. However, it's not something that the current code does explicitly after a stop has been delivered, it's expected to happen implicitly as part of stopping. I changing this to call SMRF explicitly after a user stop, but that got pretty ugly quickly. So I added a bool to control whether to run this and audited all the current uses to determine whether we're returning to the user or not. Differential Revision: https://reviews.llvm.org/D148863
2023-03-10Don't produce a dynamic value if there was an error creating it.Jim Ingham
We used to make a dynamic value that "pretended to be its parent" but that's hard for some of the more complex ValueObject types, and it's better in this case just to return no dynamic value. Differential Revision: https://reviews.llvm.org/D145629
2023-03-07Revert "[lldb] Ignore libcxx std::ranges global variables in frame var"Michael Buch
Reverting because Xcode requires this to be handled elsewhere. The global variable list gets constructed using the SBAPI This reverts commit de10c1a824405833a0f49b22e7fa3f32a1393cc3.
2023-03-03[lldb] Ignore libcxx std::ranges global variables in frame varMichael Buch
The motivation is to avoid cluttering LLDB's global variable view for std::ranges users. Before: ``` (lldb) frame var -g ... (const std::ranges::__end::__fn) std::__1::ranges::__cpo::end = {} (const std::ranges::views::__all::__fn) std::__1::ranges::views::__cpo::all = {} (const std::ranges::__begin::__fn) std::__1::ranges::__cpo::begin = {} (const std::ranges::views::__take::__fn) std::__1::ranges::views::__cpo::take = {} (const std::ranges::__max_element::__fn) std::__1::ranges::__cpo::max_element = {} (const std::ranges::__size::__fn) std::__1::ranges::__cpo::size = {} (const std::ranges::__data::__fn) std::__1::ranges::__cpo::data = {} ``` After this patch none of these __cpo variables would show up. Differential Revision: https://reviews.llvm.org/D145245
2023-03-02Revert "Add SBValue::GetValueAsAddress API for removing non-addressing metadata"Jason Molenda
Revert while I investigate two CI bot failures; the more important is the lldb-arm-ubuntu where the FixAddress is removing the 0th bit so we're adding the `actual=` decorator on a string pointer, ``` Got output: (char *) strptr = 0x00400817 (actual=0x400816) ptr = [{ },{H}] ``` in TestDataFormatterSmartArray.py line 229. This reverts commit 4d635be2dbadc77522eddc9668697385a3b9f8b4.
2023-03-02Add SBValue::GetValueAsAddress API for removing non-addressing metadataJason Molenda
On target where metadata is stored in bits that aren't used for virtual addressing -- AArch64 Top Byte Ignore and pointer authentication are two examples -- an SBValue object representing a pointer will return the address with metadata for SBValue::GetValueAsUnsigned. Users may want to get the virtual address without the metadata; this new method gives them a way to do this. Differential Revision: https://reviews.llvm.org/D142792
2023-02-28An SBValue whose underlying ValueObject has no valid value, but doesJim Ingham
hold an error should: (a) return false for IsValid, since that's the current behavior and is a convenient way to check "should I get the value for this". (b) preserve the error when an SBValue is made from it, and print the error in the ValueObjectPrinter. Make that happen. Differential Revision: https://reviews.llvm.org/D144664
2023-01-07[lldb] Use std::optional instead of llvm::Optional (NFC)Kazu Hirata
This patch replaces (llvm::|)Optional< with std::optional<. I'll post a separate patch to clean up the "using" declarations, #include "llvm/ADT/Optional.h", etc. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-07[lldb] Add #include <optional> (NFC)Kazu Hirata
This patch adds #include <optional> to those files containing llvm::Optional<...> or Optional<...>. I'll post a separate patch to actually replace llvm::Optional with std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-11-23Add the ability to see when a type in incomplete.Greg Clayton
-flimit-debug-info and other compiler options might end up removing debug info that is needed for debugging. LLDB marks these types as being forcefully completed in the metadata in the TypeSystem. These types should have been complete in the debug info but were not because the compiler omitted them to save space. When we can't find a suitable replacement for the type, we should let the user know that these types are incomplete to indicate there was an issue instead of just showing nothing for a type. The solution is to display presented in this patch is to display "<incomplete type>" as the summary for any incomplete types. If there is a summary string or function that is provided for a type, but the type is currently forcefully completed, the installed summary will be ignored and we will display "<incomplete type>". This patch also exposes the ability to ask a SBType if it was forcefully completed with: bool SBType::IsTypeForcefullyCompleted(); This will allow the user interface for a debugger to also detect this issue and possibly mark the variable display up on some way to indicate to the user the type is incomplete. To show how this is diplayed, we can look at the existing output first for the example source file from the file: lldb/test/API/functionalities/limit-debug-info/main.cpp (lldb) frame variable inherits_from_one inherits_from_two one_as_member two_as_member array_of_one array_of_two shadowed_one (InheritsFromOne) ::inherits_from_one = (member = 47) (InheritsFromTwo) ::inherits_from_two = (member = 47) (OneAsMember) ::one_as_member = (one = member::One @ 0x0000000100008028, member = 47) (TwoAsMember) ::two_as_member = (two = member::Two @ 0x0000000100008040, member = 47) (array::One [3]) ::array_of_one = ([0] = array::One @ 0x0000000100008068, [1] = array::One @ 0x0000000100008069, [2] = array::One @ 0x000000010000806a) (array::Two [3]) ::array_of_two = ([0] = array::Two @ 0x0000000100008098, [1] = array::Two @ 0x0000000100008099, [2] = array::Two @ 0x000000010000809a) (ShadowedOne) ::shadowed_one = (member = 47) (lldb) frame variable --show-types inherits_from_one inherits_from_two one_as_member two_as_member array_of_one array_of_two shadowed_one (InheritsFromOne) ::inherits_from_one = { (int) member = 47 } (InheritsFromTwo) ::inherits_from_two = { (int) member = 47 } (OneAsMember) ::one_as_member = { (member::One) one = {} (int) member = 47 } (TwoAsMember) ::two_as_member = { (member::Two) two = {} (int) member = 47 } (array::One [3]) ::array_of_one = { (array::One) [0] = {} (array::One) [1] = {} (array::One) [2] = {} } (array::Two [3]) ::array_of_two = { (array::Two) [0] = {} (array::Two) [1] = {} (array::Two) [2] = {} } (ShadowedOne) ::shadowed_one = { (int) member = 47 } With this patch in place we can now see any classes that were forcefully completed to let us know that we are missing information: (lldb) frame variable inherits_from_one inherits_from_two one_as_member two_as_member array_of_one array_of_two shadowed_one (InheritsFromOne) ::inherits_from_one = (One = <incomplete type>, member = 47) (InheritsFromTwo) ::inherits_from_two = (Two = <incomplete type>, member = 47) (OneAsMember) ::one_as_member = (one = <incomplete type>, member = 47) (TwoAsMember) ::two_as_member = (two = <incomplete type>, member = 47) (array::One[3]) ::array_of_one = ([0] = <incomplete type>, [1] = <incomplete type>, [2] = <incomplete type>) (array::Two[3]) ::array_of_two = ([0] = <incomplete type>, [1] = <incomplete type>, [2] = <incomplete type>) (ShadowedOne) ::shadowed_one = (func_shadow::One = <incomplete type>, member = 47) (lldb) frame variable --show-types inherits_from_one inherits_from_two one_as_member two_as_member array_of_one array_of_two shadowed_one (InheritsFromOne) ::inherits_from_one = { (One) One = <incomplete type> {} (int) member = 47 } (InheritsFromTwo) ::inherits_from_two = { (Two) Two = <incomplete type> {} (int) member = 47 } (OneAsMember) ::one_as_member = { (member::One) one = <incomplete type> {} (int) member = 47 } (TwoAsMember) ::two_as_member = { (member::Two) two = <incomplete type> {} (int) member = 47 } (array::One[3]) ::array_of_one = { (array::One) [0] = <incomplete type> {} (array::One) [1] = <incomplete type> {} (array::One) [2] = <incomplete type> {} } (array::Two[3]) ::array_of_two = { (array::Two) [0] = <incomplete type> {} (array::Two) [1] = <incomplete type> {} (array::Two) [2] = <incomplete type> {} } (ShadowedOne) ::shadowed_one = { (func_shadow::One) func_shadow::One = <incomplete type> {} (int) member = 47 } Differential Revision: https://reviews.llvm.org/D138259
2022-11-21[lldb] Disable looking at pointee types to find synthetic value for non-ObjCArthur Eubanks
After D134378, we started seeing crashes with incomplete types (in the context of shared libraries). When trying to print a `std::vector<int> &` with only debug info for a declaration, we now try to use the formatter after D134378. With an incomplete type, this somehow goes into infinite recursion with the frames ``` lldb_private::ValueObject::Dereference lldb_private::ValueObjectSynthetic::CreateSynthFilter lldb_private::ValueObjectSynthetic::ValueObjectSynthetic lldb_private::ValueObject::CalculateSyntheticValue lldb_private::ValueObject::HasSyntheticValue ``` This has to do with `FrontEndWantsDereference` that some STL formatters set, causing recursion between the formatter (which tries to dereference), and dereferencing (which wants to know if there's a formatter to avoid dereferencing). The reason this only started appearing after D134378 was because previously with incomplete types, for names with `<`, lldb would attempt to parse template parameter DIEs, which were empty, then create an empty `ClassTemplateSpecializationDecl` which overrode the name used to lookup a formatter in `FormattersMatchData()` to not include template parameters (e.g. `std::vector<> &`). After D134378 we don't create a `ClassTemplateSpecializationDecl` when there are no template parameters and the name to lookup a formatter is the original name (e.g. `std::vector<int> &`). The code to try harder with incomplete child compiler types was added in D79554 for ObjC purposes. Reviewed By: labath Differential Revision: https://reviews.llvm.org/D137983