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
26 using namespace lldb;
27 using namespace lldb_private;
28
TypeSummaryOptions()29 TypeSummaryOptions::TypeSummaryOptions()
30 : m_lang(eLanguageTypeUnknown), m_capping(eTypeSummaryCapped) {}
31
GetLanguage() const32 lldb::LanguageType TypeSummaryOptions::GetLanguage() const { return m_lang; }
33
GetCapping() const34 lldb::TypeSummaryCapping TypeSummaryOptions::GetCapping() const {
35 return m_capping;
36 }
37
SetLanguage(lldb::LanguageType lang)38 TypeSummaryOptions &TypeSummaryOptions::SetLanguage(lldb::LanguageType lang) {
39 m_lang = lang;
40 return *this;
41 }
42
43 TypeSummaryOptions &
SetCapping(lldb::TypeSummaryCapping cap)44 TypeSummaryOptions::SetCapping(lldb::TypeSummaryCapping cap) {
45 m_capping = cap;
46 return *this;
47 }
48
TypeSummaryImpl(Kind kind,const TypeSummaryImpl::Flags & flags)49 TypeSummaryImpl::TypeSummaryImpl(Kind kind, const TypeSummaryImpl::Flags &flags)
50 : m_flags(flags), m_kind(kind) {}
51
StringSummaryFormat(const TypeSummaryImpl::Flags & flags,const char * format_cstr)52 StringSummaryFormat::StringSummaryFormat(const TypeSummaryImpl::Flags &flags,
53 const char *format_cstr)
54 : TypeSummaryImpl(Kind::eSummaryString, flags), m_format_str() {
55 SetSummaryString(format_cstr);
56 }
57
SetSummaryString(const char * format_cstr)58 void StringSummaryFormat::SetSummaryString(const char *format_cstr) {
59 m_format.Clear();
60 if (format_cstr && format_cstr[0]) {
61 m_format_str = format_cstr;
62 m_error = FormatEntity::Parse(format_cstr, m_format);
63 } else {
64 m_format_str.clear();
65 m_error.Clear();
66 }
67 }
68
FormatObject(ValueObject * valobj,std::string & retval,const TypeSummaryOptions & options)69 bool StringSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval,
70 const TypeSummaryOptions &options) {
71 if (!valobj) {
72 retval.assign("NULL ValueObject");
73 return false;
74 }
75
76 StreamString s;
77 ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
78 SymbolContext sc;
79 StackFrame *frame = exe_ctx.GetFramePtr();
80 if (frame)
81 sc = frame->GetSymbolContext(lldb::eSymbolContextEverything);
82
83 if (IsOneLiner()) {
84 ValueObjectPrinter printer(valobj, &s, DumpValueObjectOptions());
85 printer.PrintChildrenOneLiner(HideNames(valobj));
86 retval = std::string(s.GetString());
87 return true;
88 } else {
89 if (FormatEntity::Format(m_format, s, &sc, &exe_ctx,
90 &sc.line_entry.range.GetBaseAddress(), valobj,
91 false, false)) {
92 retval.assign(std::string(s.GetString()));
93 return true;
94 } else {
95 retval.assign("error: summary string parsing error");
96 return false;
97 }
98 }
99 }
100
GetDescription()101 std::string StringSummaryFormat::GetDescription() {
102 StreamString sstr;
103
104 sstr.Printf("`%s`%s%s%s%s%s%s%s%s%s", m_format_str.c_str(),
105 m_error.Fail() ? " error: " : "",
106 m_error.Fail() ? m_error.AsCString() : "",
107 Cascades() ? "" : " (not cascading)",
108 !DoesPrintChildren(nullptr) ? "" : " (show children)",
109 !DoesPrintValue(nullptr) ? " (hide value)" : "",
110 IsOneLiner() ? " (one-line printout)" : "",
111 SkipsPointers() ? " (skip pointers)" : "",
112 SkipsReferences() ? " (skip references)" : "",
113 HideNames(nullptr) ? " (hide member names)" : "");
114 return std::string(sstr.GetString());
115 }
116
CXXFunctionSummaryFormat(const TypeSummaryImpl::Flags & flags,Callback impl,const char * description)117 CXXFunctionSummaryFormat::CXXFunctionSummaryFormat(
118 const TypeSummaryImpl::Flags &flags, Callback impl, const char *description)
119 : TypeSummaryImpl(Kind::eCallback, flags), m_impl(impl),
120 m_description(description ? description : "") {}
121
FormatObject(ValueObject * valobj,std::string & dest,const TypeSummaryOptions & options)122 bool CXXFunctionSummaryFormat::FormatObject(ValueObject *valobj,
123 std::string &dest,
124 const TypeSummaryOptions &options) {
125 dest.clear();
126 StreamString stream;
127 if (!m_impl || !m_impl(*valobj, stream, options))
128 return false;
129 dest = std::string(stream.GetString());
130 return true;
131 }
132
GetDescription()133 std::string CXXFunctionSummaryFormat::GetDescription() {
134 StreamString sstr;
135 sstr.Printf("%s%s%s%s%s%s%s %s", Cascades() ? "" : " (not cascading)",
136 !DoesPrintChildren(nullptr) ? "" : " (show children)",
137 !DoesPrintValue(nullptr) ? " (hide value)" : "",
138 IsOneLiner() ? " (one-line printout)" : "",
139 SkipsPointers() ? " (skip pointers)" : "",
140 SkipsReferences() ? " (skip references)" : "",
141 HideNames(nullptr) ? " (hide member names)" : "",
142 m_description.c_str());
143 return std::string(sstr.GetString());
144 }
145
ScriptSummaryFormat(const TypeSummaryImpl::Flags & flags,const char * function_name,const char * python_script)146 ScriptSummaryFormat::ScriptSummaryFormat(const TypeSummaryImpl::Flags &flags,
147 const char *function_name,
148 const char *python_script)
149 : TypeSummaryImpl(Kind::eScript, flags), m_function_name(),
150 m_python_script(), m_script_function_sp() {
151 if (function_name)
152 m_function_name.assign(function_name);
153 if (python_script)
154 m_python_script.assign(python_script);
155 }
156
FormatObject(ValueObject * valobj,std::string & retval,const TypeSummaryOptions & options)157 bool ScriptSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval,
158 const TypeSummaryOptions &options) {
159 if (!valobj)
160 return false;
161
162 TargetSP target_sp(valobj->GetTargetSP());
163
164 if (!target_sp) {
165 retval.assign("error: no target");
166 return false;
167 }
168
169 ScriptInterpreter *script_interpreter =
170 target_sp->GetDebugger().GetScriptInterpreter();
171
172 if (!script_interpreter) {
173 retval.assign("error: no ScriptInterpreter");
174 return false;
175 }
176
177 return script_interpreter->GetScriptedSummary(
178 m_function_name.c_str(), valobj->GetSP(), m_script_function_sp, options,
179 retval);
180 }
181
GetDescription()182 std::string ScriptSummaryFormat::GetDescription() {
183 StreamString sstr;
184 sstr.Printf("%s%s%s%s%s%s%s\n ", Cascades() ? "" : " (not cascading)",
185 !DoesPrintChildren(nullptr) ? "" : " (show children)",
186 !DoesPrintValue(nullptr) ? " (hide value)" : "",
187 IsOneLiner() ? " (one-line printout)" : "",
188 SkipsPointers() ? " (skip pointers)" : "",
189 SkipsReferences() ? " (skip references)" : "",
190 HideNames(nullptr) ? " (hide member names)" : "");
191 if (m_python_script.empty()) {
192 if (m_function_name.empty()) {
193 sstr.PutCString("no backing script");
194 } else {
195 sstr.PutCString(m_function_name);
196 }
197 } else {
198 sstr.PutCString(m_python_script);
199 }
200 return std::string(sstr.GetString());
201 }
202