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