1//===-- TypeSummary.cpp ---------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/DataFormatters/TypeSummary.h"
10
11
12
13
14#include "lldb/lldb-enumerations.h"
15#include "lldb/lldb-public.h"
16
17#include "lldb/Core/Debugger.h"
18#include "lldb/Core/ValueObject.h"
19#include "lldb/DataFormatters/ValueObjectPrinter.h"
20#include "lldb/Interpreter/CommandInterpreter.h"
21#include "lldb/Symbol/CompilerType.h"
22#include "lldb/Target/StackFrame.h"
23#include "lldb/Target/Target.h"
24#include "lldb/Utility/StreamString.h"
25
26using namespace lldb;
27using namespace lldb_private;
28
29TypeSummaryOptions::TypeSummaryOptions() = default;
30
31lldb::LanguageType TypeSummaryOptions::GetLanguage() const { return m_lang; }
32
33lldb::TypeSummaryCapping TypeSummaryOptions::GetCapping() const {
34 return m_capping;
35}
36
37TypeSummaryOptions &TypeSummaryOptions::SetLanguage(lldb::LanguageType lang) {
38 m_lang = lang;
39 return *this;
40}
41
42TypeSummaryOptions &
43TypeSummaryOptions::SetCapping(lldb::TypeSummaryCapping cap) {
44 m_capping = cap;
45 return *this;
46}
47
48TypeSummaryImpl::TypeSummaryImpl(Kind kind, const TypeSummaryImpl::Flags &flags)
49 : m_flags(flags), m_kind(kind) {}
50
51StringSummaryFormat::StringSummaryFormat(const TypeSummaryImpl::Flags &flags,
52 const char *format_cstr)
53 : TypeSummaryImpl(Kind::eSummaryString, flags), m_format_str() {
54 SetSummaryString(format_cstr);
55}
56
57void StringSummaryFormat::SetSummaryString(const char *format_cstr) {
58 m_format.Clear();
59 if (format_cstr && format_cstr[0]) {
60 m_format_str = format_cstr;
61 m_error = FormatEntity::Parse(format: format_cstr, entry&: m_format);
62 } else {
63 m_format_str.clear();
64 m_error.Clear();
65 }
66}
67
68bool StringSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval,
69 const TypeSummaryOptions &options) {
70 if (!valobj) {
71 retval.assign(s: "NULL ValueObject");
72 return false;
73 }
74
75 StreamString s;
76 ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
77 SymbolContext sc;
78 StackFrame *frame = exe_ctx.GetFramePtr();
79 if (frame)
80 sc = frame->GetSymbolContext(resolve_scope: lldb::eSymbolContextEverything);
81
82 if (IsOneLiner()) {
83 // We've already checked the case of a NULL valobj above. Let's put in an
84 // assert here to make sure someone doesn't take that out:
85 assert(valobj && "Must have a valid ValueObject to summarize");
86 ValueObjectPrinter printer(*valobj, &s, DumpValueObjectOptions());
87 printer.PrintChildrenOneLiner(hide_names: HideNames(valobj));
88 retval = std::string(s.GetString());
89 return true;
90 } else {
91 if (FormatEntity::Format(entry: m_format, s, sc: &sc, exe_ctx: &exe_ctx,
92 addr: &sc.line_entry.range.GetBaseAddress(), valobj,
93 function_changed: false, initial_function: false)) {
94 retval.assign(str: std::string(s.GetString()));
95 return true;
96 } else {
97 retval.assign(s: "error: summary string parsing error");
98 return false;
99 }
100 }
101}
102
103std::string StringSummaryFormat::GetDescription() {
104 StreamString sstr;
105
106 sstr.Printf(format: "`%s`%s%s%s%s%s%s%s%s%s", m_format_str.c_str(),
107 m_error.Fail() ? " error: " : "",
108 m_error.Fail() ? m_error.AsCString() : "",
109 Cascades() ? "" : " (not cascading)",
110 !DoesPrintChildren(valobj: nullptr) ? "" : " (show children)",
111 !DoesPrintValue(valobj: nullptr) ? " (hide value)" : "",
112 IsOneLiner() ? " (one-line printout)" : "",
113 SkipsPointers() ? " (skip pointers)" : "",
114 SkipsReferences() ? " (skip references)" : "",
115 HideNames(valobj: nullptr) ? " (hide member names)" : "");
116 return std::string(sstr.GetString());
117}
118
119CXXFunctionSummaryFormat::CXXFunctionSummaryFormat(
120 const TypeSummaryImpl::Flags &flags, Callback impl, const char *description)
121 : TypeSummaryImpl(Kind::eCallback, flags), m_impl(impl),
122 m_description(description ? description : "") {}
123
124bool CXXFunctionSummaryFormat::FormatObject(ValueObject *valobj,
125 std::string &dest,
126 const TypeSummaryOptions &options) {
127 dest.clear();
128 StreamString stream;
129 if (!m_impl || !m_impl(*valobj, stream, options))
130 return false;
131 dest = std::string(stream.GetString());
132 return true;
133}
134
135std::string CXXFunctionSummaryFormat::GetDescription() {
136 StreamString sstr;
137 sstr.Printf(format: "%s%s%s%s%s%s%s %s", Cascades() ? "" : " (not cascading)",
138 !DoesPrintChildren(valobj: nullptr) ? "" : " (show children)",
139 !DoesPrintValue(valobj: nullptr) ? " (hide value)" : "",
140 IsOneLiner() ? " (one-line printout)" : "",
141 SkipsPointers() ? " (skip pointers)" : "",
142 SkipsReferences() ? " (skip references)" : "",
143 HideNames(valobj: nullptr) ? " (hide member names)" : "",
144 m_description.c_str());
145 return std::string(sstr.GetString());
146}
147
148ScriptSummaryFormat::ScriptSummaryFormat(const TypeSummaryImpl::Flags &flags,
149 const char *function_name,
150 const char *python_script)
151 : TypeSummaryImpl(Kind::eScript, flags), m_function_name(),
152 m_python_script(), m_script_function_sp() {
153 if (function_name)
154 m_function_name.assign(s: function_name);
155 if (python_script)
156 m_python_script.assign(s: python_script);
157}
158
159bool ScriptSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval,
160 const TypeSummaryOptions &options) {
161 if (!valobj)
162 return false;
163
164 TargetSP target_sp(valobj->GetTargetSP());
165
166 if (!target_sp) {
167 retval.assign(s: "error: no target");
168 return false;
169 }
170
171 ScriptInterpreter *script_interpreter =
172 target_sp->GetDebugger().GetScriptInterpreter();
173
174 if (!script_interpreter) {
175 retval.assign(s: "error: no ScriptInterpreter");
176 return false;
177 }
178
179 return script_interpreter->GetScriptedSummary(
180 function_name: m_function_name.c_str(), valobj: valobj->GetSP(), callee_wrapper_sp&: m_script_function_sp, options,
181 retval);
182}
183
184std::string ScriptSummaryFormat::GetDescription() {
185 StreamString sstr;
186 sstr.Printf(format: "%s%s%s%s%s%s%s\n ", Cascades() ? "" : " (not cascading)",
187 !DoesPrintChildren(valobj: nullptr) ? "" : " (show children)",
188 !DoesPrintValue(valobj: nullptr) ? " (hide value)" : "",
189 IsOneLiner() ? " (one-line printout)" : "",
190 SkipsPointers() ? " (skip pointers)" : "",
191 SkipsReferences() ? " (skip references)" : "",
192 HideNames(valobj: nullptr) ? " (hide member names)" : "");
193 if (m_python_script.empty()) {
194 if (m_function_name.empty()) {
195 sstr.PutCString(cstr: "no backing script");
196 } else {
197 sstr.PutCString(cstr: m_function_name);
198 }
199 } else {
200 sstr.PutCString(cstr: m_python_script);
201 }
202 return std::string(sstr.GetString());
203}
204

source code of lldb/source/DataFormatters/TypeSummary.cpp