Skip to content

Commit 96b1784

Browse files
[lldb-vscode] Use auto summaries whenever variables don't have a summary (#66551)
Auto summaries were only being used when non-pointer/reference variables didn't have values nor summaries. Greg pointed out that it should be better to simply use auto summaries when the variable doesn't have a summary of its own, regardless of other conditions. This led to code simplification and correct visualization of auto summaries for pointer/reference types, as seen in this screenshot. <img width="310" alt="Screenshot 2023-09-19 at 7 04 55 PM" src="https://github.com/llvm/llvm-project/assets/1613874/d356d579-13f2-487b-ae3a-f3443dce778f">
1 parent feb5c57 commit 96b1784

File tree

3 files changed

+31
-55
lines changed

3 files changed

+31
-55
lines changed

lldb/test/API/tools/lldb-vscode/evaluate/TestVSCode_evaluate.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,9 @@ def run_test_evaluate_expressions(
6363
"struct1", "{foo:15}" if enableAutoVariableSummaries else "my_struct @ 0x"
6464
)
6565
self.assertEvaluate(
66-
"struct2", "{foo:16}" if enableAutoVariableSummaries else "0x.*"
66+
"struct2", "0x.* {foo:16}" if enableAutoVariableSummaries else "0x.*"
6767
)
68+
self.assertEvaluate("struct3", "0x.*0")
6869
self.assertEvaluate("struct1.foo", "15")
6970
self.assertEvaluate("struct2->foo", "16")
7071

lldb/test/API/tools/lldb-vscode/evaluate/main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct my_struct {
1818
int main(int argc, char const *argv[]) {
1919
my_struct struct1 = {15};
2020
my_struct *struct2 = new my_struct{16};
21+
my_struct *struct3 = nullptr;
2122
int var1 = 20;
2223
int var2 = 21;
2324
int var3 = static_int; // breakpoint 1
@@ -43,6 +44,6 @@ int main(int argc, char const *argv[]) {
4344
my_bool_vec.push_back(true);
4445
my_bool_vec.push_back(false); // breakpoint 6
4546
my_bool_vec.push_back(true); // breakpoint 7
46-
47+
4748
return 0;
4849
}

lldb/tools/lldb-vscode/JSONUtils.cpp

Lines changed: 27 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,14 @@ std::vector<std::string> GetStrings(const llvm::json::Object *obj,
136136
/// first children, so that the user can get a glimpse of its contents at a
137137
/// glance.
138138
static std::optional<std::string>
139-
GetSyntheticSummaryForContainer(lldb::SBValue &v) {
139+
TryCreateAutoSummaryForContainer(lldb::SBValue &v) {
140140
// We gate this feature because it performs GetNumChildren(), which can
141141
// cause performance issues because LLDB needs to complete possibly huge
142142
// types.
143143
if (!g_vsc.enable_auto_variable_summaries)
144144
return std::nullopt;
145145

146-
if (v.TypeIsPointerType() || !v.MightHaveChildren())
146+
if (!v.MightHaveChildren())
147147
return std::nullopt;
148148
/// As this operation can be potentially slow, we limit the total time spent
149149
/// fetching children to a few ms.
@@ -194,28 +194,18 @@ GetSyntheticSummaryForContainer(lldb::SBValue &v) {
194194
return summary;
195195
}
196196

197-
/// Return whether we should dereference an SBValue in order to generate a more
198-
/// meaningful summary string.
199-
static bool ShouldBeDereferencedForSummary(lldb::SBValue &v) {
197+
/// Try to create a summary string for the given value that doesn't have a
198+
/// summary of its own.
199+
static std::optional<std::string> TryCreateAutoSummary(lldb::SBValue value) {
200200
if (!g_vsc.enable_auto_variable_summaries)
201-
return false;
202-
203-
if (!v.GetType().IsPointerType() && !v.GetType().IsReferenceType())
204-
return false;
205-
206-
// If we are referencing a pointer, we don't dereference to avoid confusing
207-
// the user with the addresses that could shown in the summary.
208-
if (v.Dereference().GetType().IsPointerType())
209-
return false;
210-
211-
// If it's synthetic or a pointer to a basic type that provides a summary, we
212-
// don't dereference.
213-
if ((v.IsSynthetic() || v.GetType().GetPointeeType().GetBasicType() !=
214-
lldb::eBasicTypeInvalid) &&
215-
!llvm::StringRef(v.GetSummary()).empty()) {
216-
return false;
217-
}
218-
return true;
201+
return std::nullopt;
202+
203+
// We use the dereferenced value for generating the summary.
204+
if (value.GetType().IsPointerType() || value.GetType().IsReferenceType())
205+
value = value.Dereference();
206+
207+
// We only support auto summaries for containers.
208+
return TryCreateAutoSummaryForContainer(value);
219209
}
220210

221211
void SetValueForKey(lldb::SBValue &v, llvm::json::Object &object,
@@ -227,36 +217,20 @@ void SetValueForKey(lldb::SBValue &v, llvm::json::Object &object,
227217
if (!error.Success()) {
228218
strm << "<error: " << error.GetCString() << ">";
229219
} else {
230-
auto tryDumpSummaryAndValue = [&strm](lldb::SBValue value) {
231-
llvm::StringRef val = value.GetValue();
232-
llvm::StringRef summary = value.GetSummary();
233-
if (!val.empty()) {
234-
strm << val;
235-
if (!summary.empty())
236-
strm << ' ' << summary;
237-
return true;
238-
}
239-
if (!summary.empty()) {
240-
strm << ' ' << summary;
241-
return true;
242-
}
243-
if (auto container_summary = GetSyntheticSummaryForContainer(value)) {
244-
strm << *container_summary;
245-
return true;
246-
}
247-
return false;
248-
};
249-
250-
// We first try to get the summary from its dereferenced value.
251-
bool done = ShouldBeDereferencedForSummary(v) &&
252-
tryDumpSummaryAndValue(v.Dereference());
253-
254-
// We then try to get it from the current value itself.
255-
if (!done)
256-
done = tryDumpSummaryAndValue(v);
257-
258-
// As last resort, we print its type and address if available.
259-
if (!done) {
220+
llvm::StringRef value = v.GetValue();
221+
llvm::StringRef nonAutoSummary = v.GetSummary();
222+
std::optional<std::string> summary = !nonAutoSummary.empty()
223+
? nonAutoSummary.str()
224+
: TryCreateAutoSummary(v);
225+
if (!value.empty()) {
226+
strm << value;
227+
if (summary)
228+
strm << ' ' << *summary;
229+
} else if (summary) {
230+
strm << *summary;
231+
232+
// As last resort, we print its type and address if available.
233+
} else {
260234
if (llvm::StringRef type_name = v.GetType().GetDisplayTypeName();
261235
!type_name.empty()) {
262236
strm << type_name;

0 commit comments

Comments
 (0)