================
@@ -132,6 +132,84 @@ std::vector<std::string> GetStrings(const 
llvm::json::Object *obj,
   return strs;
 }
 
+/// Create a short summary for a container that contains the summary of its
+/// first children, so that the user can get a glimpse of its contents at a
+/// glance.
+static std::optional<std::string>
+GetSyntheticSummaryForContainer(lldb::SBValue &v) {
+  if (v.TypeIsPointerType() || !v.MightHaveChildren())
+    return std::nullopt;
+  /// As this operation can be potentially slow, we limit the total time spent
+  /// fetching children to a few ms.
+  const auto max_evaluation_time = std::chrono::milliseconds(10);
+  /// We don't want to generate a extremely long summary string, so we limit 
its
+  /// length.
+  const size_t max_length = 32;
+
+  auto start = std::chrono::steady_clock::now();
+  std::string summary;
+  llvm::raw_string_ostream os(summary);
+  os << "{";
+
+  llvm::StringRef separator = "";
+
+  for (size_t i = 0, e = v.GetNumChildren(); i < e; ++i) {
----------------
clayborg wrote:

> I'm not sure I understand. `v.GetNumChildren()` wouldn't need to do any more 
> work for a case with "10 class pointer variables", right? 

correct. that is a problem. This API is asking any variable how many children 
it has. So if we have a CompilerType in LLDB that represents a class, it starts 
off as a forward declaration and it can complete itself through the external 
AST support in clang. As soon as we call GetNumChildren, we need to complete 
the type as some of the children of a type might come from base classes, but 
only if they have fields or other base classes that contain fields. Empty base 
classes do not show up in the variable view. And then we need to count the 
number of fields that the class actaully has as well so we can show them as 
children, so as soon as we call "v.GetNumChildren()" we must complete the type.

> You can determine how many children this type has (10) without completing the 
> types those pointers point to?

Correct yes, that is what I meant by "layout type". LLDB has the ability to say 
"get me a version of this type that is needed to layout this current class". So 
if a class has 10 ivars that are all pointers, we don't need to complete those 
classes. If we have 10 ivars that are class instances, then we do need to 
complete the type since we assist in the clang AST context in laying out the 
type with the help of the DWARF info. This is needed because of 
"-flimit-debug-info". If we have class A that inherits from class B, and there 
is no class B definition in the DWARF, then we have to have the DWARF help us 
laying out the type. What we do is start and end a definition for class B and 
we attach. metadata saying "this class should have been complete but wasn't", 
and the layout support that clang has allows us to specify the offsets of all 
fields and base classes so we can always show the variable correctly to people. 
The layout stuff is needed because DWARF doesn't encode many things, one being 
the current pragma pack settings and other things that can affect the layout of 
the type.

> Or is it later code (like line 168, etc) that try to get the summary of those 
> pointer member variables that are an issue? (though getting the summary of a 
> pointer shouldn't automatically dereference the pointer/complete its 
> pointed-to type, should it?)

Any summary code that needs to access children to make up the summary string 
can be expensive and cause the type to need to be completed due to above 
explanation. If we have a "Foo *", the value of the variable will show as the 
pointer value, but if the type that is being pointed to has a summary, we do 
end up showing that for pointers and for references. This is because users 
expect it from the GDB days and due to the way we expand variables. If we have 
a "Point *" and we expand it in a GUI, we don't expect it to expand to a 
"Point" and then for it to need to be expanded yet again to see the "x" and "y" 
values, we expect to directly see the "x" and "y" right away. If the pointee is 
a simple type, like an "int *", we exand and show the "int", but if we have a 
class pointer, then we immediately show the children of the class. Many users 
complained when we initially did it where a "Point *" would expand to a "Point" 
object, so we changed lldb.




https://github.com/llvm/llvm-project/pull/65514
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to