blob: ba5f6c04f78d991f6e26ec94e08878de0b4645c0 [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
43
44void
45lldb_private::formatters::AddStringSummary(TypeCategoryImpl::SharedPointer category_sp,
46 const char* string,
47 ConstString type_name,
48 TypeSummaryImpl::Flags flags,
49 bool regex)
50{
51 lldb::TypeSummaryImplSP summary_sp(new StringSummaryFormat(flags,
52 string));
53
54 if (regex)
55 category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())),summary_sp);
56 else
57 category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
58}
59
60void
61lldb_private::formatters::AddOneLineSummary (TypeCategoryImpl::SharedPointer category_sp,
62 ConstString type_name,
63 TypeSummaryImpl::Flags flags,
64 bool regex)
65{
66 flags.SetShowMembersOneLiner(true);
67 lldb::TypeSummaryImplSP summary_sp(new StringSummaryFormat(flags, ""));
68
69 if (regex)
70 category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())),summary_sp);
71 else
72 category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
73}
74
75#ifndef LLDB_DISABLE_PYTHON
76void
77lldb_private::formatters::AddCXXSummary (TypeCategoryImpl::SharedPointer category_sp,
78 CXXFunctionSummaryFormat::Callback funct,
79 const char* description,
80 ConstString type_name,
81 TypeSummaryImpl::Flags flags,
82 bool regex)
83{
84 lldb::TypeSummaryImplSP summary_sp(new CXXFunctionSummaryFormat(flags,funct,description));
85 if (regex)
86 category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())),summary_sp);
87 else
88 category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
89}
90
91void
92lldb_private::formatters::AddCXXSynthetic (TypeCategoryImpl::SharedPointer category_sp,
93 CXXSyntheticChildren::CreateFrontEndCallback generator,
94 const char* description,
95 ConstString type_name,
96 ScriptedSyntheticChildren::Flags flags,
97 bool regex)
98{
99 lldb::SyntheticChildrenSP synth_sp(new CXXSyntheticChildren(flags,description,generator));
100 if (regex)
101 category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())), synth_sp);
102 else
103 category_sp->GetTypeSyntheticsContainer()->Add(type_name,synth_sp);
104}
105
106void
107lldb_private::formatters::AddFilter (TypeCategoryImpl::SharedPointer category_sp,
108 std::vector<std::string> children,
109 const char* description,
110 ConstString type_name,
111 ScriptedSyntheticChildren::Flags flags,
112 bool regex)
113{
114 TypeFilterImplSP filter_sp(new TypeFilterImpl(flags));
115 for (auto child : children)
116 filter_sp->AddExpressionPath(child);
117 if (regex)
118 category_sp->GetRegexTypeFiltersContainer()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())), filter_sp);
119 else
120 category_sp->GetTypeFiltersContainer()->Add(type_name,filter_sp);
121}
122#endif
Enrico Granata419d7912015-09-04 00:33:51 +0000123
124StackFrame*
125lldb_private::formatters::GetViableFrame (ExecutionContext exe_ctx)
126{
127 StackFrame* frame = exe_ctx.GetFramePtr();
128 if (frame)
129 return frame;
130
131 Process* process = exe_ctx.GetProcessPtr();
132 if (!process)
133 return nullptr;
134
135 ThreadSP thread_sp(process->GetThreadList().GetSelectedThread());
136 if (thread_sp)
137 return thread_sp->GetSelectedFrame().get();
138 return nullptr;
139}
140
141bool
142lldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj,
143 const char* target_type,
144 const char* selector,
145 uint64_t &value)
146{
147 if (!target_type || !*target_type)
148 return false;
149 if (!selector || !*selector)
150 return false;
151 StreamString expr;
152 expr.Printf("(%s)[(id)0x%" PRIx64 " %s]",target_type,valobj.GetPointerValue(),selector);
153 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
154 lldb::ValueObjectSP result_sp;
155 Target* target = exe_ctx.GetTargetPtr();
156 StackFrame* stack_frame = GetViableFrame(exe_ctx);
157 if (!target || !stack_frame)
158 return false;
159
160 EvaluateExpressionOptions options;
161 options.SetCoerceToId(false);
162 options.SetUnwindOnError(true);
163 options.SetKeepInMemory(true);
164
165 target->EvaluateExpression(expr.GetData(),
166 stack_frame,
167 result_sp,
168 options);
169 if (!result_sp)
170 return false;
171 value = result_sp->GetValueAsUnsigned(0);
172 return true;
173}
174
175bool
176lldb_private::formatters::ExtractSummaryFromObjCExpression (ValueObject &valobj,
177 const char* target_type,
178 const char* selector,
179 Stream &stream)
180{
181 if (!target_type || !*target_type)
182 return false;
183 if (!selector || !*selector)
184 return false;
185 StreamString expr;
186 expr.Printf("(%s)[(id)0x%" PRIx64 " %s]",target_type,valobj.GetPointerValue(),selector);
187 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
188 lldb::ValueObjectSP result_sp;
189 Target* target = exe_ctx.GetTargetPtr();
190 StackFrame* stack_frame = GetViableFrame(exe_ctx);
191 if (!target || !stack_frame)
192 return false;
193
194 EvaluateExpressionOptions options;
195 options.SetCoerceToId(false);
196 options.SetUnwindOnError(true);
197 options.SetKeepInMemory(true);
198 options.SetUseDynamic(lldb::eDynamicCanRunTarget);
199
200 target->EvaluateExpression(expr.GetData(),
201 stack_frame,
202 result_sp,
203 options);
204 if (!result_sp)
205 return false;
206 stream.Printf("%s",result_sp->GetSummaryAsCString());
207 return true;
208}
209
210lldb::ValueObjectSP
211lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
212 const char* return_type,
213 const char* selector,
214 uint64_t index)
215{
216 lldb::ValueObjectSP valobj_sp;
217 if (!return_type || !*return_type)
218 return valobj_sp;
219 if (!selector || !*selector)
220 return valobj_sp;
221 StreamString expr_path_stream;
222 valobj.GetExpressionPath(expr_path_stream, false);
223 StreamString expr;
224 expr.Printf("(%s)[%s %s:%" PRId64 "]",return_type,expr_path_stream.GetData(),selector,index);
225 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
226 lldb::ValueObjectSP result_sp;
227 Target* target = exe_ctx.GetTargetPtr();
228 StackFrame* stack_frame = GetViableFrame(exe_ctx);
229 if (!target || !stack_frame)
230 return valobj_sp;
231
232 EvaluateExpressionOptions options;
233 options.SetCoerceToId(false);
234 options.SetUnwindOnError(true);
235 options.SetKeepInMemory(true);
236 options.SetUseDynamic(lldb::eDynamicCanRunTarget);
237
238 target->EvaluateExpression(expr.GetData(),
239 stack_frame,
240 valobj_sp,
241 options);
242 return valobj_sp;
243}
244
245lldb::ValueObjectSP
246lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
247 const char* return_type,
248 const char* selector,
249 const char* key)
250{
251 lldb::ValueObjectSP valobj_sp;
252 if (!return_type || !*return_type)
253 return valobj_sp;
254 if (!selector || !*selector)
255 return valobj_sp;
256 if (!key || !*key)
257 return valobj_sp;
258 StreamString expr_path_stream;
259 valobj.GetExpressionPath(expr_path_stream, false);
260 StreamString expr;
261 expr.Printf("(%s)[%s %s:%s]",return_type,expr_path_stream.GetData(),selector,key);
262 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
263 lldb::ValueObjectSP result_sp;
264 Target* target = exe_ctx.GetTargetPtr();
265 StackFrame* stack_frame = GetViableFrame(exe_ctx);
266 if (!target || !stack_frame)
267 return valobj_sp;
268
269 EvaluateExpressionOptions options;
270 options.SetCoerceToId(false);
271 options.SetUnwindOnError(true);
272 options.SetKeepInMemory(true);
273 options.SetUseDynamic(lldb::eDynamicCanRunTarget);
274
275 target->EvaluateExpression(expr.GetData(),
276 stack_frame,
277 valobj_sp,
278 options);
279 return valobj_sp;
280}
281
282size_t
283lldb_private::formatters::ExtractIndexFromString (const char* item_name)
284{
285 if (!item_name || !*item_name)
286 return UINT32_MAX;
287 if (*item_name != '[')
288 return UINT32_MAX;
289 item_name++;
290 char* endptr = NULL;
291 unsigned long int idx = ::strtoul(item_name, &endptr, 0);
292 if (idx == 0 && endptr == item_name)
293 return UINT32_MAX;
294 if (idx == ULONG_MAX)
295 return UINT32_MAX;
296 return idx;
297}