blob: 900fd32c810896b167c1806d6be090b2bfe1acf3 [file] [log] [blame]
Enrico Granatadf7e79e2015-09-02 01:21:31 +00001//===-- FormattersHelpers.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// C Includes
11
12// C++ Includes
13
14// Other libraries and framework includes
15
16// Project includes
17#include "lldb/DataFormatters/FormattersHelpers.h"
18
19#include "lldb/Core/ConstString.h"
20#include "lldb/Core/RegularExpression.h"
Enrico Granata419d7912015-09-04 00:33:51 +000021#include "lldb/Target/StackFrame.h"
Enrico Granatad717cc92015-10-20 04:50:09 +000022#include "lldb/Target/Target.h"
Enrico Granata419d7912015-09-04 00:33:51 +000023#include "lldb/Target/Thread.h"
Enrico Granatadf7e79e2015-09-02 01:21:31 +000024
25using namespace lldb;
26using namespace lldb_private;
27using namespace lldb_private::formatters;
28
29void
30lldb_private::formatters::AddFormat (TypeCategoryImpl::SharedPointer category_sp,
31 lldb::Format format,
32 ConstString type_name,
33 TypeFormatImpl::Flags flags,
34 bool regex)
35{
36 lldb::TypeFormatImplSP format_sp(new TypeFormatImpl_Format(format, flags));
37
38 if (regex)
39 category_sp->GetRegexTypeFormatsContainer()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())),format_sp);
40 else
41 category_sp->GetTypeFormatsContainer()->Add(type_name, format_sp);
42}
43
Enrico Granatafa6b2782015-09-17 00:14:50 +000044void
45lldb_private::formatters::AddSummary(TypeCategoryImpl::SharedPointer category_sp,
46 TypeSummaryImplSP summary_sp,
47 ConstString type_name,
48 bool regex)
49{
50 if (regex)
51 category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())),summary_sp);
52 else
53 category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
54}
Enrico Granatadf7e79e2015-09-02 01:21:31 +000055
56void
57lldb_private::formatters::AddStringSummary(TypeCategoryImpl::SharedPointer category_sp,
58 const char* string,
59 ConstString type_name,
60 TypeSummaryImpl::Flags flags,
61 bool regex)
62{
63 lldb::TypeSummaryImplSP summary_sp(new StringSummaryFormat(flags,
64 string));
65
66 if (regex)
67 category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())),summary_sp);
68 else
69 category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
70}
71
72void
73lldb_private::formatters::AddOneLineSummary (TypeCategoryImpl::SharedPointer category_sp,
74 ConstString type_name,
75 TypeSummaryImpl::Flags flags,
76 bool regex)
77{
78 flags.SetShowMembersOneLiner(true);
79 lldb::TypeSummaryImplSP summary_sp(new StringSummaryFormat(flags, ""));
80
81 if (regex)
82 category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())),summary_sp);
83 else
84 category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
85}
86
87#ifndef LLDB_DISABLE_PYTHON
88void
89lldb_private::formatters::AddCXXSummary (TypeCategoryImpl::SharedPointer category_sp,
90 CXXFunctionSummaryFormat::Callback funct,
91 const char* description,
92 ConstString type_name,
93 TypeSummaryImpl::Flags flags,
94 bool regex)
95{
96 lldb::TypeSummaryImplSP summary_sp(new CXXFunctionSummaryFormat(flags,funct,description));
97 if (regex)
98 category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())),summary_sp);
99 else
100 category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
101}
102
103void
104lldb_private::formatters::AddCXXSynthetic (TypeCategoryImpl::SharedPointer category_sp,
105 CXXSyntheticChildren::CreateFrontEndCallback generator,
106 const char* description,
107 ConstString type_name,
108 ScriptedSyntheticChildren::Flags flags,
109 bool regex)
110{
111 lldb::SyntheticChildrenSP synth_sp(new CXXSyntheticChildren(flags,description,generator));
112 if (regex)
113 category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())), synth_sp);
114 else
115 category_sp->GetTypeSyntheticsContainer()->Add(type_name,synth_sp);
116}
117
118void
119lldb_private::formatters::AddFilter (TypeCategoryImpl::SharedPointer category_sp,
120 std::vector<std::string> children,
121 const char* description,
122 ConstString type_name,
123 ScriptedSyntheticChildren::Flags flags,
124 bool regex)
125{
126 TypeFilterImplSP filter_sp(new TypeFilterImpl(flags));
127 for (auto child : children)
128 filter_sp->AddExpressionPath(child);
129 if (regex)
130 category_sp->GetRegexTypeFiltersContainer()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())), filter_sp);
131 else
132 category_sp->GetTypeFiltersContainer()->Add(type_name,filter_sp);
133}
134#endif
Enrico Granata419d7912015-09-04 00:33:51 +0000135
136StackFrame*
137lldb_private::formatters::GetViableFrame (ExecutionContext exe_ctx)
138{
139 StackFrame* frame = exe_ctx.GetFramePtr();
140 if (frame)
141 return frame;
142
143 Process* process = exe_ctx.GetProcessPtr();
144 if (!process)
145 return nullptr;
146
147 ThreadSP thread_sp(process->GetThreadList().GetSelectedThread());
148 if (thread_sp)
149 return thread_sp->GetSelectedFrame().get();
150 return nullptr;
151}
152
153bool
154lldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj,
155 const char* target_type,
156 const char* selector,
157 uint64_t &value)
158{
159 if (!target_type || !*target_type)
160 return false;
161 if (!selector || !*selector)
162 return false;
163 StreamString expr;
164 expr.Printf("(%s)[(id)0x%" PRIx64 " %s]",target_type,valobj.GetPointerValue(),selector);
165 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
166 lldb::ValueObjectSP result_sp;
167 Target* target = exe_ctx.GetTargetPtr();
168 StackFrame* stack_frame = GetViableFrame(exe_ctx);
169 if (!target || !stack_frame)
170 return false;
171
172 EvaluateExpressionOptions options;
173 options.SetCoerceToId(false);
174 options.SetUnwindOnError(true);
175 options.SetKeepInMemory(true);
176
177 target->EvaluateExpression(expr.GetData(),
178 stack_frame,
179 result_sp,
180 options);
181 if (!result_sp)
182 return false;
183 value = result_sp->GetValueAsUnsigned(0);
184 return true;
185}
186
187bool
188lldb_private::formatters::ExtractSummaryFromObjCExpression (ValueObject &valobj,
189 const char* target_type,
190 const char* selector,
Enrico Granata31fda932015-10-07 01:41:23 +0000191 Stream &stream,
192 lldb::LanguageType lang_type)
Enrico Granata419d7912015-09-04 00:33:51 +0000193{
194 if (!target_type || !*target_type)
195 return false;
196 if (!selector || !*selector)
197 return false;
198 StreamString expr;
199 expr.Printf("(%s)[(id)0x%" PRIx64 " %s]",target_type,valobj.GetPointerValue(),selector);
200 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
201 lldb::ValueObjectSP result_sp;
202 Target* target = exe_ctx.GetTargetPtr();
203 StackFrame* stack_frame = GetViableFrame(exe_ctx);
204 if (!target || !stack_frame)
205 return false;
206
207 EvaluateExpressionOptions options;
208 options.SetCoerceToId(false);
209 options.SetUnwindOnError(true);
210 options.SetKeepInMemory(true);
Enrico Granata31fda932015-10-07 01:41:23 +0000211 options.SetLanguage(lldb::eLanguageTypeObjC_plus_plus);
212 options.SetResultIsInternal(true);
Enrico Granata419d7912015-09-04 00:33:51 +0000213 options.SetUseDynamic(lldb::eDynamicCanRunTarget);
214
215 target->EvaluateExpression(expr.GetData(),
216 stack_frame,
217 result_sp,
218 options);
219 if (!result_sp)
220 return false;
Enrico Granata31fda932015-10-07 01:41:23 +0000221 stream.Printf("%s",result_sp->GetSummaryAsCString(lang_type));
Enrico Granata419d7912015-09-04 00:33:51 +0000222 return true;
223}
224
225lldb::ValueObjectSP
226lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
227 const char* return_type,
228 const char* selector,
229 uint64_t index)
230{
231 lldb::ValueObjectSP valobj_sp;
232 if (!return_type || !*return_type)
233 return valobj_sp;
234 if (!selector || !*selector)
235 return valobj_sp;
236 StreamString expr_path_stream;
237 valobj.GetExpressionPath(expr_path_stream, false);
238 StreamString expr;
239 expr.Printf("(%s)[%s %s:%" PRId64 "]",return_type,expr_path_stream.GetData(),selector,index);
240 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
241 lldb::ValueObjectSP result_sp;
242 Target* target = exe_ctx.GetTargetPtr();
243 StackFrame* stack_frame = GetViableFrame(exe_ctx);
244 if (!target || !stack_frame)
245 return valobj_sp;
246
247 EvaluateExpressionOptions options;
248 options.SetCoerceToId(false);
249 options.SetUnwindOnError(true);
250 options.SetKeepInMemory(true);
251 options.SetUseDynamic(lldb::eDynamicCanRunTarget);
252
253 target->EvaluateExpression(expr.GetData(),
254 stack_frame,
255 valobj_sp,
256 options);
257 return valobj_sp;
258}
259
260lldb::ValueObjectSP
261lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
262 const char* return_type,
263 const char* selector,
264 const char* key)
265{
266 lldb::ValueObjectSP valobj_sp;
267 if (!return_type || !*return_type)
268 return valobj_sp;
269 if (!selector || !*selector)
270 return valobj_sp;
271 if (!key || !*key)
272 return valobj_sp;
273 StreamString expr_path_stream;
274 valobj.GetExpressionPath(expr_path_stream, false);
275 StreamString expr;
276 expr.Printf("(%s)[%s %s:%s]",return_type,expr_path_stream.GetData(),selector,key);
277 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
278 lldb::ValueObjectSP result_sp;
279 Target* target = exe_ctx.GetTargetPtr();
280 StackFrame* stack_frame = GetViableFrame(exe_ctx);
281 if (!target || !stack_frame)
282 return valobj_sp;
283
284 EvaluateExpressionOptions options;
285 options.SetCoerceToId(false);
286 options.SetUnwindOnError(true);
287 options.SetKeepInMemory(true);
288 options.SetUseDynamic(lldb::eDynamicCanRunTarget);
289
290 target->EvaluateExpression(expr.GetData(),
291 stack_frame,
292 valobj_sp,
293 options);
294 return valobj_sp;
295}
296
297size_t
298lldb_private::formatters::ExtractIndexFromString (const char* item_name)
299{
300 if (!item_name || !*item_name)
301 return UINT32_MAX;
302 if (*item_name != '[')
303 return UINT32_MAX;
304 item_name++;
305 char* endptr = NULL;
306 unsigned long int idx = ::strtoul(item_name, &endptr, 0);
307 if (idx == 0 && endptr == item_name)
308 return UINT32_MAX;
309 if (idx == ULONG_MAX)
310 return UINT32_MAX;
311 return idx;
312}
Dawn Perchik045c8292015-09-25 02:16:52 +0000313
314lldb::addr_t
315lldb_private::formatters::GetArrayAddressOrPointerValue (ValueObject& valobj)
316{
317 lldb::addr_t data_addr = LLDB_INVALID_ADDRESS;
318
319 if (valobj.IsPointerType())
320 data_addr = valobj.GetValueAsUnsigned(0);
321 else if (valobj.IsArrayType())
322 data_addr = valobj.GetAddressOf();
323
324 return data_addr;
325}