1 //===-- TypeSummary.cpp ----------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/lldb-python.h"
11
12 // C Includes
13
14 // C++ Includes
15
16 // Other libraries and framework includes
17
18 // Project includes
19 #include "lldb/lldb-public.h"
20 #include "lldb/lldb-enumerations.h"
21
22 #include "lldb/Core/Debugger.h"
23 #include "lldb/Core/StreamString.h"
24 #include "lldb/Core/Timer.h"
25 #include "lldb/DataFormatters/TypeSummary.h"
26 #include "lldb/Interpreter/CommandInterpreter.h"
27 #include "lldb/Symbol/ClangASTType.h"
28 #include "lldb/Target/StackFrame.h"
29 #include "lldb/Target/Target.h"
30
31 #include "lldb/Host/Host.h"
32
33 using namespace lldb;
34 using namespace lldb_private;
35
TypeSummaryImpl(const TypeSummaryImpl::Flags & flags)36 TypeSummaryImpl::TypeSummaryImpl (const TypeSummaryImpl::Flags& flags) :
37 m_flags(flags)
38 {
39 }
40
41
StringSummaryFormat(const TypeSummaryImpl::Flags & flags,const char * format_cstr)42 StringSummaryFormat::StringSummaryFormat (const TypeSummaryImpl::Flags& flags,
43 const char *format_cstr) :
44 TypeSummaryImpl(flags),
45 m_format()
46 {
47 if (format_cstr)
48 m_format.assign(format_cstr);
49 }
50
51 bool
FormatObject(ValueObject * valobj,std::string & retval)52 StringSummaryFormat::FormatObject (ValueObject *valobj,
53 std::string& retval)
54 {
55 if (!valobj)
56 {
57 retval.assign("NULL ValueObject");
58 return false;
59 }
60
61 StreamString s;
62 ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
63 SymbolContext sc;
64 StackFrame *frame = exe_ctx.GetFramePtr();
65 if (frame)
66 sc = frame->GetSymbolContext(lldb::eSymbolContextEverything);
67
68 if (IsOneliner())
69 {
70 ValueObject* object;
71
72 ValueObjectSP synth_valobj = valobj->GetSyntheticValue();
73 if (synth_valobj)
74 object = synth_valobj.get();
75 else
76 object = valobj;
77
78 const uint32_t num_children = object->GetNumChildren();
79 if (num_children)
80 {
81 s.PutChar('(');
82
83 for (uint32_t idx=0; idx<num_children; ++idx)
84 {
85 lldb::ValueObjectSP child_sp(object->GetChildAtIndex(idx, true));
86 if (child_sp.get())
87 {
88 if (idx)
89 s.PutCString(", ");
90 if (!HideNames())
91 {
92 s.PutCString(child_sp.get()->GetName().AsCString());
93 s.PutCString(" = ");
94 }
95 child_sp.get()->DumpPrintableRepresentation(s,
96 ValueObject::eValueObjectRepresentationStyleSummary,
97 lldb::eFormatInvalid,
98 ValueObject::ePrintableRepresentationSpecialCasesDisable);
99 }
100 }
101
102 s.PutChar(')');
103
104 retval.assign(s.GetString());
105 return true;
106 }
107 else
108 {
109 retval.assign("error: oneliner for no children");
110 return false;
111 }
112
113 }
114 else
115 {
116 if (Debugger::FormatPrompt(m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, valobj))
117 {
118 retval.assign(s.GetString());
119 return true;
120 }
121 else
122 {
123 retval.assign("error: summary string parsing error");
124 return false;
125 }
126 }
127 }
128
129 std::string
GetDescription()130 StringSummaryFormat::GetDescription ()
131 {
132 StreamString sstr;
133
134 sstr.Printf ("`%s`%s%s%s%s%s%s%s", m_format.c_str(),
135 Cascades() ? "" : " (not cascading)",
136 !DoesPrintChildren() ? "" : " (show children)",
137 !DoesPrintValue() ? " (hide value)" : "",
138 IsOneliner() ? " (one-line printout)" : "",
139 SkipsPointers() ? " (skip pointers)" : "",
140 SkipsReferences() ? " (skip references)" : "",
141 HideNames() ? " (hide member names)" : "");
142 return sstr.GetString();
143 }
144
CXXFunctionSummaryFormat(const TypeSummaryImpl::Flags & flags,Callback impl,const char * description)145 CXXFunctionSummaryFormat::CXXFunctionSummaryFormat (const TypeSummaryImpl::Flags& flags,
146 Callback impl,
147 const char* description) :
148 TypeSummaryImpl(flags),
149 m_impl(impl),
150 m_description(description ? description : "")
151 {
152 }
153
154 bool
FormatObject(ValueObject * valobj,std::string & dest)155 CXXFunctionSummaryFormat::FormatObject (ValueObject *valobj,
156 std::string& dest)
157 {
158 dest.clear();
159 StreamString stream;
160 if (!m_impl || m_impl(*valobj,stream) == false)
161 return false;
162 dest.assign(stream.GetData());
163 return true;
164 }
165
166 std::string
GetDescription()167 CXXFunctionSummaryFormat::GetDescription ()
168 {
169 StreamString sstr;
170 sstr.Printf ("`%s (%p) `%s%s%s%s%s%s%s", m_description.c_str(),m_impl,
171 Cascades() ? "" : " (not cascading)",
172 !DoesPrintChildren() ? "" : " (show children)",
173 !DoesPrintValue() ? " (hide value)" : "",
174 IsOneliner() ? " (one-line printout)" : "",
175 SkipsPointers() ? " (skip pointers)" : "",
176 SkipsReferences() ? " (skip references)" : "",
177 HideNames() ? " (hide member names)" : "");
178 return sstr.GetString();
179 }
180
181 #ifndef LLDB_DISABLE_PYTHON
182
183
ScriptSummaryFormat(const TypeSummaryImpl::Flags & flags,const char * function_name,const char * python_script)184 ScriptSummaryFormat::ScriptSummaryFormat (const TypeSummaryImpl::Flags& flags,
185 const char * function_name,
186 const char * python_script) :
187 TypeSummaryImpl(flags),
188 m_function_name(),
189 m_python_script(),
190 m_script_function_sp()
191 {
192 if (function_name)
193 m_function_name.assign(function_name);
194 if (python_script)
195 m_python_script.assign(python_script);
196 }
197
198 bool
FormatObject(ValueObject * valobj,std::string & retval)199 ScriptSummaryFormat::FormatObject (ValueObject *valobj,
200 std::string& retval)
201 {
202 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
203
204 if (!valobj)
205 return false;
206
207 Host::SetCrashDescriptionWithFormat("[Python summary] Name: %s - Function: %s",
208 valobj->GetName().AsCString("unknown"),
209 m_function_name.c_str());
210
211 TargetSP target_sp(valobj->GetTargetSP());
212
213 if (!target_sp)
214 {
215 retval.assign("error: no target");
216 return false;
217 }
218
219 ScriptInterpreter *script_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
220
221 if (!script_interpreter)
222 {
223 retval.assign("error: no ScriptInterpreter");
224 return false;
225 }
226
227 return script_interpreter->GetScriptedSummary(m_function_name.c_str(),
228 valobj->GetSP(),
229 m_script_function_sp,
230 retval);
231
232 }
233
234 std::string
GetDescription()235 ScriptSummaryFormat::GetDescription ()
236 {
237 StreamString sstr;
238 sstr.Printf ("%s%s%s%s%s%s%s\n%s", Cascades() ? "" : " (not cascading)",
239 !DoesPrintChildren() ? "" : " (show children)",
240 !DoesPrintValue() ? " (hide value)" : "",
241 IsOneliner() ? " (one-line printout)" : "",
242 SkipsPointers() ? " (skip pointers)" : "",
243 SkipsReferences() ? " (skip references)" : "",
244 HideNames() ? " (hide member names)" : "",
245 m_python_script.c_str());
246 return sstr.GetString();
247
248 }
249
250 #endif // #ifndef LLDB_DISABLE_PYTHON
251